diff options
-rw-r--r-- | CHANGES.current | 8 | ||||
-rw-r--r-- | Examples/test-suite/cpp11_template_parameters_decltype.i | 7 | ||||
-rw-r--r-- | Source/CParse/parser.y | 44 |
3 files changed, 42 insertions, 17 deletions
diff --git a/CHANGES.current b/CHANGES.current index a528b663c..e50ddac51 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,14 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.2.0 (in progress) =========================== +2023-05-18: olly + #1589 #2335 Support parsing arbitrary expression in decltype. + + Use parser error recovery to skip to the closing matching `)` and + issue a warning that we can't deduce the decltype for the + expression (like we already do for any expression which isn't a + simple variable or similar). + 2023-05-12: mmomtchev, erezgeva [Javascript] #2561 Support check typemaps for Javascript. diff --git a/Examples/test-suite/cpp11_template_parameters_decltype.i b/Examples/test-suite/cpp11_template_parameters_decltype.i index 1d00124f1..257d1ec8d 100644 --- a/Examples/test-suite/cpp11_template_parameters_decltype.i +++ b/Examples/test-suite/cpp11_template_parameters_decltype.i @@ -6,14 +6,12 @@ #pragma SWIG nowarn=SWIGWARN_CPP11_DECLTYPE -#if 0 -// to fix (non-template expression equivalent to template expression further down): +// Non-template expression equivalent to template expression further down: %inline %{ #include <utility> #include <vector> void f(bool c = std::is_constructible<std::string, decltype(std::declval<std::vector<std::pair<int, int>>>().begin()->first)>::value) {} %} -#endif %inline %{ // Github issue #1590 @@ -26,14 +24,11 @@ struct Json { Json(const T & t) : Json(t.to_json()) {} // Github issue #1589 -// To fix -#if !defined(SWIG) // Implicit constructor: map-like objects (std::map, std::unordered_map, etc) template <class M, typename std::enable_if< std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value, int>::type = 0> Json(const M & m) : Json(object(m.begin(), m.end())) {} -#endif }; %} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 5e09e54e7..8c8724944 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1734,7 +1734,7 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) %type <id> access_specifier; %type <node> base_specifier; %type <str> variadic_opt; -%type <type> type rawtype type_right anon_bitfield_type decltype ; +%type <type> type rawtype type_right anon_bitfield_type decltype decltypeexpr; %type <bases> base_list inherit raw_inherit; %type <dtype> definetype def_args etype default_delete deleted_definition explicit_default; %type <dtype> expr exprnum exprsimple exprcompound valexpr exprmem callparms callptail; @@ -6224,17 +6224,39 @@ type_right : primitive_type { $$ = $1; } ; -decltype : DECLTYPE LPAREN expr RPAREN { - Node *n = Swig_symbol_clookup($3.val, 0); - if (!n) { - Swig_warning(WARN_CPP11_DECLTYPE, cparse_file, cparse_line, "Unable to deduce decltype for '%s'.\n", $3.val); +decltype : DECLTYPE LPAREN { + $<str>$ = get_raw_text_balanced('(', ')'); + } decltypeexpr { + if ($4) { + $$ = $4; + Delete($<str>3); + } else { + String *expr = $<str>3; + Delitem(expr,0); + Delitem(expr,DOH_END); + Swig_warning(WARN_CPP11_DECLTYPE, cparse_file, cparse_line, "Unable to deduce decltype for '%s'.\n", expr); + $$ = expr; + } + } + ; - $$ = NewStringf("decltype(%s)", $3.val); - } else { - $$ = Getattr(n, "type"); - } - } - ; +decltypeexpr : expr RPAREN { + Node *n = Swig_symbol_clookup($1.val, 0); + if (!n) { + Swig_warning(WARN_CPP11_DECLTYPE, cparse_file, cparse_line, "Unable to deduce decltype for '%s'.\n", $1.val); + + $$ = NewStringf("decltype(%s)", $1.val); + } else { + $$ = Getattr(n, "type"); + } + } + | error RPAREN { + // Avoid a parse error if we can't parse the expression decltype() is applied to. + $$ = 0; + skip_balanced('(',')'); + Clear(scanner_ccode); + } + ; primitive_type : primitive_type_list { if (!$1.type) $1.type = NewString("int"); |