diff options
Diffstat (limited to 'clang/lib/Parse')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 4 |
2 files changed, 37 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 3017da48213..7d1a9bb4b65 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -245,6 +245,11 @@ Parser::DeclTy *Parser::ParseSimpleDeclaration(unsigned Context) { /// declarator '=' initializer /// [GNU] declarator simple-asm-expr[opt] attributes[opt] /// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer +/// [C++] declarator initializer[opt] +/// +/// [C++] initializer: +/// [C++] '=' initializer-clause +/// [C++] '(' expression-list ')' /// Parser::DeclTy *Parser:: ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) { @@ -284,6 +289,27 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) { return 0; } Actions.AddInitializerToDecl(LastDeclInGroup, Init.Val); + } else if (Tok.is(tok::l_paren)) { + // Parse C++ direct initializer: '(' expression-list ')' + SourceLocation LParenLoc = ConsumeParen(); + ExprListTy Exprs; + CommaLocsTy CommaLocs; + + bool InvalidExpr = false; + if (ParseExpressionList(Exprs, CommaLocs)) { + SkipUntil(tok::r_paren); + InvalidExpr = true; + } + // Match the ')'. + SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); + + if (!InvalidExpr) { + assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() && + "Unexpected number of commas!"); + Actions.AddCXXDirectInitializerToDecl(LastDeclInGroup, LParenLoc, + &Exprs[0], Exprs.size(), + &CommaLocs[0], RParenLoc); + } } // If we don't have a comma, it is either the end of the list (a ';') or an @@ -1200,6 +1226,12 @@ void Parser::ParseDirectDeclarator(Declarator &D) { while (1) { if (Tok.is(tok::l_paren)) { + // 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. + if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit() && + !isCXXFunctionDeclarator()) + break; ParseFunctionDeclarator(ConsumeParen(), D); } else if (Tok.is(tok::l_square)) { ParseBracketDeclarator(D); @@ -1247,6 +1279,8 @@ void Parser::ParseParenDeclarator(Declarator &D) { // direct-declarator: '(' declarator ')' // direct-declarator: '(' attributes declarator ')' if (isGrouping) { + D.setGroupingParens(true); + if (Tok.is(tok::kw___attribute)) D.AddAttributes(ParseAttributes()); diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 800be8dd013..fa4bdfafb74 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -449,7 +449,9 @@ Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() { Tok.is(tok::comma) || // int X(), -> not a function def Tok.is(tok::semi) || // int X(); -> not a function def Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def - Tok.is(tok::kw___attribute)) { // int X() __attr__ -> not a function def + Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def + (getLang().CPlusPlus && + Tok.is(tok::l_paren)) ) { // int X(0) -> not a function def [C++] // FALL THROUGH. } else if (DeclaratorInfo.isFunctionDeclarator() && (Tok.is(tok::l_brace) || // int X() {} |

