cpp: decltype, trailing return type support

git-svn-id: svn://ultimatepp.org/upp/trunk@8747 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2015-07-25 10:39:38 +00:00
parent a86acead53
commit acab0cf50b
3 changed files with 52 additions and 1 deletions

View file

@ -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++;

View file

@ -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<int> 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

View file

@ -95,3 +95,5 @@ CPPID(alignas)
CPPID(thread_local)
CPPID(char16_t)
CPPID(char32_t)
CPPID(static_assert)
CPPID(decltype)