[cfe-commits] r132662 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp test/SemaCXX/generalized-initializers.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Sun Jun 5 05:23:16 PDT 2011
Author: cornedbee
Date: Sun Jun 5 07:23:16 2011
New Revision: 132662
URL: http://llvm.org/viewvc/llvm-project?rev=132662&view=rev
Log:
Parse C++0x generalized initializers.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/test/SemaCXX/generalized-initializers.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=132662&r1=132661&r2=132662&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Jun 5 07:23:16 2011
@@ -108,6 +108,7 @@
def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
def err_expected_lbrace : Error<"expected '{'">;
def err_expected_lparen : Error<"expected '('">;
+def err_expected_lparen_or_lbrace : Error<"expected '('or '{'">;
def err_expected_rparen : Error<"expected ')'">;
def err_expected_lsquare : Error<"expected '['">;
def err_expected_rsquare : Error<"expected ']'">;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=132662&r1=132661&r2=132662&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Jun 5 07:23:16 2011
@@ -814,8 +814,10 @@
// analyzed.
if (FRI && Tok.is(tok::colon)) {
FRI->ColonLoc = ConsumeToken();
- // FIXME: handle braced-init-list here.
- FRI->RangeExpr = ParseExpression();
+ if (Tok.is(tok::l_brace))
+ FRI->RangeExpr = ParseBraceInitializer();
+ else
+ FRI->RangeExpr = ParseExpression();
Decl *ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
Actions.ActOnCXXForRangeDecl(ThisDecl);
Actions.FinalizeDeclaration(ThisDecl);
@@ -914,6 +916,7 @@
/// [C++] '(' expression-list ')'
/// [C++0x] '=' 'default' [TODO]
/// [C++0x] '=' 'delete'
+/// [C++0x] braced-init-list
///
/// According to the standard grammar, =default and =delete are function
/// definitions, but that definitely doesn't fit with the parser here.
@@ -1041,6 +1044,26 @@
RParenLoc,
TypeContainsAuto);
}
+ } else if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ // Parse C++0x braced-init-list.
+ if (D.getCXXScopeSpec().isSet()) {
+ EnterScope(0);
+ Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
+ }
+
+ ExprResult Init(ParseBraceInitializer());
+
+ if (D.getCXXScopeSpec().isSet()) {
+ Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
+ ExitScope();
+ }
+
+ if (Init.isInvalid()) {
+ Actions.ActOnInitializerError(ThisDecl);
+ } else
+ Actions.AddInitializerToDecl(ThisDecl, Init.take(),
+ /*DirectInit=*/true, TypeContainsAuto);
+
} else {
Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
}
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=132662&r1=132661&r2=132662&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sun Jun 5 07:23:16 2011
@@ -2157,6 +2157,7 @@
///
/// [C++] mem-initializer:
/// mem-initializer-id '(' expression-list[opt] ')'
+/// [C++0x] mem-initializer-id braced-init-list
///
/// [C++] mem-initializer-id:
/// '::'[opt] nested-name-specifier[opt] class-name
@@ -2187,31 +2188,37 @@
SourceLocation IdLoc = ConsumeToken();
// Parse the '('.
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok, diag::err_expected_lparen);
+ if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ // FIXME: Do something with the braced-init-list.
+ ParseBraceInitializer();
return true;
- }
- SourceLocation LParenLoc = ConsumeParen();
+ } else if(Tok.is(tok::l_paren)) {
+ SourceLocation LParenLoc = ConsumeParen();
- // Parse the optional expression-list.
- ExprVector ArgExprs(Actions);
- CommaLocsTy CommaLocs;
- if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
- SkipUntil(tok::r_paren);
- return true;
- }
+ // Parse the optional expression-list.
+ ExprVector ArgExprs(Actions);
+ CommaLocsTy CommaLocs;
+ if (Tok.isNot(tok::r_paren) && ParseExpressionList(ArgExprs, CommaLocs)) {
+ SkipUntil(tok::r_paren);
+ return true;
+ }
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
- SourceLocation EllipsisLoc;
- if (Tok.is(tok::ellipsis))
- EllipsisLoc = ConsumeToken();
-
- return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
- TemplateTypeTy, IdLoc,
- LParenLoc, ArgExprs.take(),
- ArgExprs.size(), RParenLoc,
- EllipsisLoc);
+ SourceLocation EllipsisLoc;
+ if (Tok.is(tok::ellipsis))
+ EllipsisLoc = ConsumeToken();
+
+ return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
+ TemplateTypeTy, IdLoc,
+ LParenLoc, ArgExprs.take(),
+ ArgExprs.size(), RParenLoc,
+ EllipsisLoc);
+ }
+
+ Diag(Tok, getLang().CPlusPlus0x ? diag::err_expected_lparen_or_lbrace
+ : diag::err_expected_lparen);
+ return true;
}
/// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=132662&r1=132661&r2=132662&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sun Jun 5 07:23:16 2011
@@ -480,7 +480,9 @@
/// [OBJC] '@encode' '(' type-name ')'
/// [OBJC] objc-string-literal
/// [C++] simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
+/// [C++0x] simple-type-specifier braced-init-list [C++ 5.2.3]
/// [C++] typename-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
+/// [C++0x] typename-specifier braced-init-list [C++ 5.2.3]
/// [C++] 'const_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
/// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
/// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
@@ -923,15 +925,18 @@
if (SavedKind == tok::kw_typename) {
// postfix-expression: typename-specifier '(' expression-list[opt] ')'
+ // typename-specifier braced-init-list
if (TryAnnotateTypeOrScopeToken())
return ExprError();
}
// postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
+ // simple-type-specifier braced-init-list
//
DeclSpec DS(AttrFactory);
ParseCXXSimpleTypeSpecifier(DS);
- if (Tok.isNot(tok::l_paren))
+ if (Tok.isNot(tok::l_paren) &&
+ (!getLang().CPlusPlus0x || Tok.isNot(tok::l_brace)))
return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
<< DS.getSourceRange());
@@ -1122,6 +1127,7 @@
/// postfix-expression: [C99 6.5.2]
/// primary-expression
/// postfix-expression '[' expression ']'
+/// postfix-expression '[' braced-init-list ']'
/// postfix-expression '(' argument-expression-list[opt] ')'
/// postfix-expression '.' identifier
/// postfix-expression '->' identifier
@@ -1177,7 +1183,11 @@
return move(LHS);
Loc = ConsumeBracket();
- ExprResult Idx(ParseExpression());
+ ExprResult Idx;
+ if (getLang().CPlusPlus0x && Tok.is(tok::l_brace))
+ Idx = ParseBraceInitializer();
+ else
+ Idx = ParseExpression();
SourceLocation RLoc = Tok.getLocation();
@@ -2021,8 +2031,19 @@
/// argument-expression-list , assignment-expression
///
/// [C++] expression-list:
-/// [C++] assignment-expression ...[opt]
-/// [C++] expression-list , assignment-expression ...[opt]
+/// [C++] assignment-expression
+/// [C++] expression-list , assignment-expression
+///
+/// [C++0x] expression-list:
+/// [C++0x] initializer-list
+///
+/// [C++0x] initializer-list
+/// [C++0x] initializer-clause ...[opt]
+/// [C++0x] initializer-list , initializer-clause ...[opt]
+///
+/// [C++0x] initializer-clause:
+/// [C++0x] assignment-expression
+/// [C++0x] braced-init-list
///
bool Parser::ParseExpressionList(llvm::SmallVectorImpl<Expr*> &Exprs,
llvm::SmallVectorImpl<SourceLocation> &CommaLocs,
@@ -2039,8 +2060,13 @@
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression);
ConsumeCodeCompletionToken();
}
-
- ExprResult Expr(ParseAssignmentExpression());
+
+ ExprResult Expr;
+ if (getLang().CPlusPlus0x && Tok.is(tok::l_brace))
+ Expr = ParseBraceInitializer();
+ else
+ Expr = ParseAssignmentExpression();
+
if (Tok.is(tok::ellipsis))
Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());
if (Expr.isInvalid())
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=132662&r1=132661&r2=132662&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Jun 5 07:23:16 2011
@@ -809,42 +809,55 @@
/// Can be interpreted either as function-style casting ("int(x)")
/// or class type construction ("ClassType(x,y,z)")
/// or creation of a value-initialized type ("int()").
+/// See [C++ 5.2.3].
///
/// postfix-expression: [C++ 5.2p1]
-/// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3]
-/// typename-specifier '(' expression-list[opt] ')' [TODO]
+/// simple-type-specifier '(' expression-list[opt] ')'
+/// [C++0x] simple-type-specifier braced-init-list
+/// typename-specifier '(' expression-list[opt] ')'
+/// [C++0x] typename-specifier braced-init-list
///
ExprResult
Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
- assert(Tok.is(tok::l_paren) && "Expected '('!");
- GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
+ assert((Tok.is(tok::l_paren) ||
+ (getLang().CPlusPlus0x && Tok.is(tok::l_brace)))
+ && "Expected '(' or '{'!");
- SourceLocation LParenLoc = ConsumeParen();
+ if (Tok.is(tok::l_brace)) {
- ExprVector Exprs(Actions);
- CommaLocsTy CommaLocs;
+ // FIXME: Convert to a proper type construct expression.
+ return ParseBraceInitializer();
- if (Tok.isNot(tok::r_paren)) {
- if (ParseExpressionList(Exprs, CommaLocs)) {
- SkipUntil(tok::r_paren);
- return ExprError();
+ } else {
+ GreaterThanIsOperatorScope G(GreaterThanIsOperator, true);
+
+ SourceLocation LParenLoc = ConsumeParen();
+
+ ExprVector Exprs(Actions);
+ CommaLocsTy CommaLocs;
+
+ if (Tok.isNot(tok::r_paren)) {
+ if (ParseExpressionList(Exprs, CommaLocs)) {
+ SkipUntil(tok::r_paren);
+ return ExprError();
+ }
}
- }
- // Match the ')'.
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ // Match the ')'.
+ SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
- // TypeRep could be null, if it references an invalid typedef.
- if (!TypeRep)
- return ExprError();
+ // TypeRep could be null, if it references an invalid typedef.
+ if (!TypeRep)
+ return ExprError();
- assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
- "Unexpected number of commas!");
- return Actions.ActOnCXXTypeConstructExpr(TypeRep, LParenLoc, move_arg(Exprs),
- RParenLoc);
+ assert((Exprs.size() == 0 || Exprs.size()-1 == CommaLocs.size())&&
+ "Unexpected number of commas!");
+ return Actions.ActOnCXXTypeConstructExpr(TypeRep, LParenLoc, move_arg(Exprs),
+ RParenLoc);
+ }
}
/// ParseCXXCondition - if/switch/while condition expression.
@@ -1727,7 +1740,7 @@
///
/// new-initializer:
/// '(' expression-list[opt] ')'
-/// [C++0x] braced-init-list [TODO]
+/// [C++0x] braced-init-list
///
ExprResult
Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
@@ -1816,6 +1829,9 @@
SkipUntil(tok::semi, /*StopAtSemi=*/true, /*DontConsume=*/true);
return ExprError();
}
+ } else if (Tok.is(tok::l_brace)) {
+ // FIXME: Have to communicate the init-list to ActOnCXXNew.
+ ParseBraceInitializer();
}
return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
Modified: cfe/trunk/test/SemaCXX/generalized-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/generalized-initializers.cpp?rev=132662&r1=132661&r2=132662&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/generalized-initializers.cpp (original)
+++ cfe/trunk/test/SemaCXX/generalized-initializers.cpp Sun Jun 5 07:23:16 2011
@@ -45,8 +45,9 @@
{ const int a = {}; static_assert(a == 0, ""); }
{ const int a{1}; static_assert(a == 1, ""); }
{ const int a = {1}; static_assert(a == 1, ""); }
- { const int a{1, 2}; } // expected-error {{ too many initializers}}
- { const int a = {1, 2}; } // expected-error {{ too many initializers}}
+ { const int a{1, 2}; } // expected-error {{excess elements}}
+ { const int a = {1, 2}; } // expected-error {{excess elements}}
+ { const short a{100000}; } // expected-error {{narrowing conversion}}
{ const short a = {100000}; } // expected-error {{narrowing conversion}}
}
@@ -158,7 +159,7 @@
struct B {
template<typename ...T>
- B(initializer_list<int>, T ...);
+ B(std::initializer_list<int>, T ...);
};
// invalid (the first phase only considers init-list ctors)
More information about the cfe-commits
mailing list