[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