aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-10-06 17:10:33 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-10-06 17:10:33 +0000
commit73a0d889eda0f000a441319e39540509175b8e81 (patch)
tree683f7b24cbec0ea01151430f7122a067da5639ff /lib/Parse/ParseDecl.cpp
parentebe0af9359fa42933439a307a2cb1e2954199c56 (diff)
Implement support for C++ direct initializers in declarations, e.g. "int x(1);".
This is how this kind of initializers appear in the AST: -The Init expression of the VarDecl is a functional type construction (of the VarDecl's type). -The new VarDecl::hasCXXDirectInitializer() returns true. e.g, for "int x(1);": -VarDecl 'x' has Init with expression "int(1)" (CXXFunctionalCastExpr). -hasCXXDirectInitializer() of VarDecl 'x' returns true. A major benefit is that clients that don't particularly care about which exactly form was the initializer can handle both cases without special case code. Note that codegening works now for "int x(1);" without any changes to CodeGen. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57178 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r--lib/Parse/ParseDecl.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 3017da4821..7d1a9bb4b6 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/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());