diff options
author | David Blaikie <dblaikie@gmail.com> | 2011-12-04 05:04:18 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2011-12-04 05:04:18 +0000 |
commit | 42d6d0c91ab089cb252ab2f91c16d4557f458a2c (patch) | |
tree | 798a87db00244b0536a6b3880eb6c040218aa70d /lib/Parse/ParseDecl.cpp | |
parent | 649657e7d6c150136cae5ab22e39b9794cff80cc (diff) |
Support decltype in nested-name-specifiers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145785 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 3bddd3de13..0c5a4879ae 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1889,6 +1889,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; // typedef-name + case tok::kw_decltype: case tok::identifier: { // In C++, check to see if this is a scope specifier like foo::bar::, if // so handle it as such. This is important for ctor parsing. @@ -2248,7 +2249,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, ParseTypeofSpecifier(DS); continue; - case tok::kw_decltype: + case tok::annot_decltype: ParseDecltypeSpecifier(DS); continue; @@ -2370,6 +2371,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid)) break; // Fall through. + case tok::kw_decltype: case tok::kw_typename: // typename foo::bar // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -2532,7 +2534,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, return true; // C++0x decltype support. - case tok::kw_decltype: + case tok::annot_decltype: ParseDecltypeSpecifier(DS); return true; @@ -3346,6 +3348,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { if (TryAltiVecVectorToken()) return true; // Fall through. + case tok::kw_decltype: // decltype(T())::type case tok::kw_typename: // typename T::type // Annotate typenames and C++ scope specifiers. If we get one, just // recurse to handle whatever we get. @@ -3441,7 +3444,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { return true; // C++0x decltype. - case tok::kw_decltype: + case tok::annot_decltype: return true; // C1x _Atomic() @@ -3968,6 +3971,10 @@ void Parser::ParseDirectDeclarator(Declarator &D) { while (1) { if (Tok.is(tok::l_paren)) { + // Enter function-declaration scope, limiting any declarators to the + // function prototype scope, including parameter declarators. + ParseScope PrototypeScope(this, + Scope::FunctionPrototypeScope|Scope::DeclScope); // The paren may be part of a C++ direct initializer, eg. "int x(1);". // In such a case, check if we actually have a function declarator; if it // is not, the declarator has been fully parsed. @@ -3982,13 +3989,14 @@ void Parser::ParseDirectDeclarator(Declarator &D) { BalancedDelimiterTracker T(*this, tok::l_paren); T.consumeOpen(); ParseFunctionDeclarator(D, attrs, T); + PrototypeScope.Exit(); } else if (Tok.is(tok::l_square)) { ParseBracketDeclarator(D); } else { break; } } -} +} /// ParseParenDeclarator - We parsed the declarator D up to a paren. This is /// only called before the identifier, so these are most likely just grouping @@ -4084,7 +4092,12 @@ void Parser::ParseParenDeclarator(Declarator &D) { // ParseFunctionDeclarator to handle of argument list. D.SetIdentifier(0, Tok.getLocation()); + // Enter function-declaration scope, limiting any declarators to the + // function prototype scope, including parameter declarators. + ParseScope PrototypeScope(this, + Scope::FunctionPrototypeScope|Scope::DeclScope); ParseFunctionDeclarator(D, attrs, T, RequiresArg); + PrototypeScope.Exit(); } /// ParseFunctionDeclarator - We are after the identifier and have parsed the @@ -4109,6 +4122,8 @@ void Parser::ParseFunctionDeclarator(Declarator &D, ParsedAttributes &attrs, BalancedDelimiterTracker &Tracker, bool RequiresArg) { + assert(getCurScope()->isFunctionPrototypeScope() && + "Should call from a Function scope"); // lparen is already consumed! assert(D.isPastIdentifier() && "Should not call before identifier!"); @@ -4142,11 +4157,6 @@ void Parser::ParseFunctionDeclarator(Declarator &D, Tracker.consumeClose(); EndLoc = Tracker.getCloseLocation(); } else { - // Enter function-declaration scope, limiting any declarators to the - // function prototype scope, including parameter declarators. - ParseScope PrototypeScope(this, - Scope::FunctionPrototypeScope|Scope::DeclScope); - if (Tok.isNot(tok::r_paren)) ParseParameterDeclarationClause(D, attrs, ParamInfo, EllipsisLoc); else if (RequiresArg) @@ -4197,9 +4207,6 @@ void Parser::ParseFunctionDeclarator(Declarator &D, EndLoc = Range.getEnd(); } } - - // Leave prototype scope. - PrototypeScope.Exit(); } // Remember that we parsed a function type, and remember the attributes. |