diff options
-rw-r--r-- | Examples/test-suite/cpp11_template_parameters_decltype.i | 5 | ||||
-rw-r--r-- | Source/CParse/parser.y | 44 |
2 files changed, 33 insertions, 16 deletions
diff --git a/Examples/test-suite/cpp11_template_parameters_decltype.i b/Examples/test-suite/cpp11_template_parameters_decltype.i index 1d00124f1..8528636d7 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): %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 7a9cefe7b..cea0fd0e1 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"); |