summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.current8
-rw-r--r--Examples/test-suite/cpp11_template_parameters_decltype.i7
-rw-r--r--Source/CParse/parser.y44
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");