diff --git a/uppsrc/CppBase/Body.cpp b/uppsrc/CppBase/Body.cpp index 896538268..579198e6a 100644 --- a/uppsrc/CppBase/Body.cpp +++ b/uppsrc/CppBase/Body.cpp @@ -47,6 +47,24 @@ bool Parser::TryDecl() return true; } String type; + if(t == tk_decltype && lex[q + 1] == '(') { + q += 2; + int q0 = q; + int lvl = 1; + for(;;) { + if(lex[q] == t_eof) + break; + if(lex[q] == '(') + lvl++; + else + if(lex[q] == ')' && --lvl == 0) { + Locals("@" + String(lex.Pos(q0), lex.Pos(q))); + return true; + } + ++q; + } + return false; + } if(lex[q] == t_dblcolon) { type << "::"; q++; diff --git a/uppsrc/CppBase/Parser.cpp b/uppsrc/CppBase/Parser.cpp index f9d398d8f..c1a3b8033 100644 --- a/uppsrc/CppBase/Parser.cpp +++ b/uppsrc/CppBase/Parser.cpp @@ -144,6 +144,9 @@ String FnItem(const char *s, const char *pname, const char *qname, const String& if(*s++ == ']') break; } + else + if(c == '-' && s[1] == '>') + break; // trailing return type else { res.Cat(c); if(c == ',') @@ -697,6 +700,24 @@ String Parser::ReadType(Decla& d, const String& tname, const String& tparam) const char *p = lex.Pos(); bool cs = false; Index cix; + if(Key(tk_decltype) && Key('(')) { + const char *p = lex.Pos(); + int lvl = 1; + for(;;) { + if(lex == t_eof) + break; + if(lex == '(') + lvl++; + else + if(lex == ')' && --lvl == 0) { + d.type = "@" + String(p, lex.Pos()); + ++lex; + break; + } + ++lex; + } + } + else if(Key(tk_auto)) d.type = "*"; else { @@ -881,6 +902,12 @@ void Parser::Declarator(Decl& d, const char *p) ParamList(d); p = lex.Pos(); Qualifier(true); + + if(d.function && Key(t_arrow)) { // C++11 trailing return type + d.type.Clear(); + ReadType(d, Null, Null); + } + if(filetype == FILE_C && lex != '{' && lex != ';') // K&R style function header while(lex != '{' && lex != t_eof) ++lex; @@ -1279,7 +1306,7 @@ CppItem& Parser::Fn(const Decl& d, const String& templ, bool body, String ptype; for(int i = 0; i < d.param.GetCount(); i++) { const Decla& p = d.param[i]; - if(dobody) { + if(dobody) { // put arguments to the list of local variables Local& l = local.Add(p.name); l.type = p.type; l.isptr = p.isptr; @@ -1469,6 +1496,10 @@ void Parser::Do() if(UsingNamespace()) ; else + if(Key(tk_static_assert)) + while(lex != t_eof && lex != ';') + ++lex; + else if(Key(';')) // 'empty' declaration, result of some ignores ; else diff --git a/uppsrc/CppBase/keyword.i b/uppsrc/CppBase/keyword.i index 24c20ed86..5a29836b8 100644 --- a/uppsrc/CppBase/keyword.i +++ b/uppsrc/CppBase/keyword.i @@ -95,3 +95,5 @@ CPPID(alignas) CPPID(thread_local) CPPID(char16_t) CPPID(char32_t) +CPPID(static_assert) +CPPID(decltype) \ No newline at end of file