18
18
#include " sema.h"
19
19
#include < iostream>
20
20
#include < cstdio>
21
-
21
+ # include < optional >
22
22
23
23
namespace cpp2 {
24
24
@@ -1734,7 +1734,13 @@ class cppfront
1734
1734
auto last_was_prefixed = false ;
1735
1735
auto saw_dollar = false ;
1736
1736
1737
- auto args = std::optional<std::vector<text_with_pos>>{};
1737
+ struct text_chunks_with_parens_position {
1738
+ std::vector<text_with_pos> text_chunks;
1739
+ cpp2::source_position open_pos;
1740
+ cpp2::source_position close_pos;
1741
+ };
1742
+
1743
+ auto args = std::optional<text_chunks_with_parens_position>{};
1738
1744
1739
1745
auto print_to_string = [&](auto & i, auto ... args) {
1740
1746
auto print = std::string{};
@@ -1780,12 +1786,15 @@ class cppfront
1780
1786
// expr_list is emited to args variable for future use
1781
1787
if (i->op ->type () == lexeme::LeftParen) {
1782
1788
1783
- args.emplace ();
1789
+ assert (i->op );
1790
+ assert (i->op_close );
1791
+ auto local_args = text_chunks_with_parens_position{{}, i->op ->position (), i->op_close ->position ()};
1784
1792
1785
1793
if (!i->expr_list ->expressions .empty ()) {
1786
- args. emplace ( print_to_text_chunks (*i->expr_list ) );
1794
+ local_args. text_chunks = print_to_text_chunks (*i->expr_list );
1787
1795
}
1788
1796
1797
+ args.emplace (std::move (local_args));
1789
1798
}
1790
1799
// Going backwards if we found Dot and there is args variable
1791
1800
// it means that it should be handled by UFCS
@@ -1809,17 +1818,18 @@ class cppfront
1809
1818
// from obj.fun<int, long, double>(1,2) this CPP2_UFCS_TEMPLATE(fun, (<int,long, double>), obj, 1, 2)
1810
1819
auto split = funcname.find (' <' ); assert (split != std::string::npos);
1811
1820
funcname.insert (split, " , (" );
1821
+ assert (funcname.back () == ' >' );
1812
1822
funcname += ' )' ;
1813
1823
}
1814
1824
// If there are no additional arguments, use the _0 version
1815
- if (args.value ().empty ()) {
1825
+ if (args.value ().text_chunks . empty ()) {
1816
1826
ufcs_string += " _0" ;
1817
1827
}
1818
1828
1819
1829
prefix.emplace_back (ufcs_string + " (" + funcname + " , " , i->op ->position () );
1820
- suffix.emplace_back (" )" , i-> op -> position () );
1821
- if (!args.value ().empty ()) {
1822
- for (auto && e: args.value ()) {
1830
+ suffix.emplace_back (" )" , args. value (). close_pos );
1831
+ if (!args.value ().text_chunks . empty ()) {
1832
+ for (auto && e: args.value (). text_chunks ) {
1823
1833
suffix.push_back (e);
1824
1834
}
1825
1835
suffix.emplace_back (" , " , i->op ->position ());
@@ -1876,12 +1886,12 @@ class cppfront
1876
1886
1877
1887
if (args) {
1878
1888
// if args are stored it means that this is function or method
1879
- // that is not handled by UFCS e.g. that has more than one template argument
1880
- suffix.emplace_back (" )" , n. position () );
1881
- for (auto && e: args.value ()) {
1889
+ // that is not handled by UFCS and args need to be printed
1890
+ suffix.emplace_back (" )" , args. value (). close_pos );
1891
+ for (auto && e: args.value (). text_chunks ) {
1882
1892
suffix.push_back (e);
1883
1893
}
1884
- suffix.emplace_back (" (" , n. position () );
1894
+ suffix.emplace_back (" (" , args. value (). open_pos );
1885
1895
args.reset ();
1886
1896
}
1887
1897
@@ -1937,11 +1947,11 @@ class cppfront
1937
1947
// if after printing core expression args is defined
1938
1948
// it means that the chaining started by function call
1939
1949
// we need to print its arguments
1940
- suffix.emplace_back (" )" , n. position () );
1941
- for (auto && e: args.value ()) {
1950
+ suffix.emplace_back (" )" , args. value (). close_pos );
1951
+ for (auto && e: args.value (). text_chunks ) {
1942
1952
suffix.push_back (e);
1943
1953
}
1944
- suffix.emplace_back (" (" , n. position () );
1954
+ suffix.emplace_back (" (" , args. value (). open_pos );
1945
1955
args.reset ();
1946
1956
}
1947
1957
0 commit comments