diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 1001b8ac8..d8fb30936 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -411,7 +411,8 @@ CPP0X_TEST_CASES = \ cpp0x_rvalue_reference \ cpp0x_variadic_templates \ cpp0x_alternate_function_syntax \ - cpp0x_userdefined_literals + cpp0x_userdefined_literals \ + cpp0x_decltype # cpp0x_hash_types # not fully implemented yet # cpp0x_lambda_functions # not supported by GCC or MSVC yet # cpp0x_null_pointer_constant # not supported by any compilers yet diff --git a/Examples/test-suite/cpp0x_decltype.i b/Examples/test-suite/cpp0x_decltype.i new file mode 100644 index 000000000..316c38962 --- /dev/null +++ b/Examples/test-suite/cpp0x_decltype.i @@ -0,0 +1,19 @@ +/* This testcase checks whether Swig correctly uses the new 'decltype()' + introduced in C++0x. +*/ +%module cpp0x_decltype + +%inline %{ +class A { +public: + int i; + decltype(i) j; + + auto foo( decltype(i) a ) -> decltype(i) { + if (a==5) + return 10; + else + return 0; + } +}; +%} diff --git a/Examples/test-suite/python/cpp0x_decltype_runme.py b/Examples/test-suite/python/cpp0x_decltype_runme.py new file mode 100644 index 000000000..ce742e6b2 --- /dev/null +++ b/Examples/test-suite/python/cpp0x_decltype_runme.py @@ -0,0 +1,19 @@ +import cpp0x_decltype + +a = cpp0x_decltype.A() +a.i = 5 +if a.i != 5: + raise RuntimeError, "Assignment to a.i failed." + +a.j = 10 +if a.j != 10: + raise RuntimeError, "Assignment to a.j failed." + +b = a.foo(5) +if b != 10: + raise RuntimeError, "foo(5) should return 10." + +b = a.foo(6) +if b != 0: + raise RuntimeError, "foo(6) should return 0." + diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c index 369c962e9..626958169 100644 --- a/Source/CParse/cscanner.c +++ b/Source/CParse/cscanner.c @@ -636,6 +636,8 @@ int yylex(void) { return (CONSTEXPR); if (strcmp(yytext, "thread_local") == 0) return (THREAD_LOCAL); + if (strcmp(yytext, "decltype") == 0) + return (DECLTYPE); if (strcmp(yytext, "virtual") == 0) return (VIRTUAL); if (strcmp(yytext, "static_assert") == 0) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index b164690e1..2392e7705 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1493,7 +1493,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { %token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS %token ENUM %token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT AUTO -%token STATIC_ASSERT CONSTEXPR THREAD_LOCAL /* C++0x keywords */ +%token STATIC_ASSERT CONSTEXPR THREAD_LOCAL DECLTYPE /* C++0x keywords */ %token USING %token NAMESPACE %token NATIVE INLINE @@ -1557,7 +1557,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { %type

templateparameter ; %type templcpptype cpptype access_specifier; %type base_specifier -%type type rawtype type_right anon_bitfield_type ; +%type type rawtype type_right anon_bitfield_type decltype ; %type base_list inherit raw_inherit; %type definetype def_args etype; %type expr exprnum exprcompound valexpr; @@ -3128,6 +3128,7 @@ cpp_alternate_rettype : primitive_type { $$ = $1; } | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); } | TYPE_RAW { $$ = $1; } | idcolon { $$ = $1; } + | decltype { $$ = $1; } ; /* Lambda function syntax introduced in C++0x. @@ -5471,6 +5472,19 @@ type_right : primitive_type { $$ = $1; | cpptype idcolon { $$ = NewStringf("%s %s", $1, $2); } + | decltype { + $$ = $1; + } + ; + +decltype : DECLTYPE LPAREN idcolon RPAREN { + Node *n = Swig_symbol_clookup($3,0); + if (!n) { + Swig_error(cparse_file, cparse_line, "Identifier %s not defined.\n", $3); + } else { + $$ = Getattr(n, "type"); + } + } ; primitive_type : primitive_type_list {