[cfe-commits] r150318 - in /cfe/trunk: include/clang/AST/ include/clang/Sema/ lib/AST/ lib/CodeGen/ lib/Parse/ lib/Sema/ lib/Serialization/ test/CXX/temp/temp.decls/temp.variadic/ test/Sema/ test/SemaTemplate/

Sebastian Redl sebastian.redl at getdesigned.at
Sat Feb 11 15:51:48 PST 2012


Author: cornedbee
Date: Sat Feb 11 17:51:47 2012
New Revision: 150318

URL: http://llvm.org/viewvc/llvm-project?rev=150318&view=rev
Log:
Represent C++ direct initializers as ParenListExprs before semantic analysis
instead of having a special-purpose function.

- ActOnCXXDirectInitializer, which was mostly duplication of
  AddInitializerToDecl (leading e.g. to PR10620, which Eli fixed a few days
  ago), is dropped completely.
- MultiInitializer, which was an ugly hack I added, is dropped again.
- We now have the infrastructure in place to distinguish between
  int x = {1};
  int x({1});
  int x{1};
-- VarDecl now has getInitStyle(), which indicates which of the above was used.
-- CXXConstructExpr now has a flag to indicate that it represents list-
   initialization, although this is not yet used.
- InstantiateInitializer was renamed to SubstInitializer and simplified.
- ActOnParenOrParenListExpr has been replaced by ActOnParenListExpr, which
  always produces a ParenListExpr. Placed that so far failed to convert that
  back to a ParenExpr containing comma operators have been fixed. I'm pretty
  sure I could have made a crashing test case before this.

The end result is a (I hope) considerably cleaner design of initializers.
More importantly, the fact that I can now distinguish between the various
initialization kinds means that I can get the tricky generalized initializer
test cases Johannes Schaub supplied to work. (This is not yet done.)

This commit passed self-host, with the resulting compiler passing the tests. I
hope it doesn't break more complicated code. It's a pretty big change, but one
that I feel is necessary.

Added:
    cfe/trunk/test/SemaTemplate/nested-incomplete-class.cpp
Removed:
    cfe/trunk/include/clang/Sema/MultiInitializer.h
    cfe/trunk/lib/Sema/MultiInitializer.cpp
    cfe/trunk/test/Sema/paren-list-expr-type.cpp
Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/Sema/Initialization.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/AST/DumpXML.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Sema/CMakeLists.txt
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Feb 11 17:51:47 2012
@@ -681,6 +681,13 @@
   /// It is illegal to call this function with SC == None.
   static const char *getStorageClassSpecifierString(StorageClass SC);
 
+  /// \brief Initialization styles.
+  enum InitializationStyle {
+    CInit,    ///< C-style initialization with assignment
+    CallInit, ///< Call-style initialization (C++98)
+    ListInit  ///< Direct list-initialization (C++11)
+  };
+
 protected:
   /// \brief Placeholder type used in Init to denote an unparsed C++ default
   /// argument.
@@ -706,7 +713,7 @@
     unsigned SClass : 3;
     unsigned SClassAsWritten : 3;
     unsigned ThreadSpecified : 1;
-    unsigned HasCXXDirectInit : 1;
+    unsigned InitStyle : 2;
 
     /// \brief Whether this variable is the exception variable in a C++ catch
     /// or an Objective-C @catch statement.
@@ -728,7 +735,7 @@
     /// \brief Whether this variable is (C++0x) constexpr.
     unsigned IsConstexpr : 1;
   };
-  enum { NumVarDeclBits = 13 };
+  enum { NumVarDeclBits = 14 };
 
   friend class ASTDeclReader;
   friend class StmtIteratorBase;
@@ -756,7 +763,7 @@
     /// Otherwise, the number of function parameter scopes enclosing
     /// the function parameter scope in which this parameter was
     /// declared.
-    unsigned ScopeDepthOrObjCQuals : 8;
+    unsigned ScopeDepthOrObjCQuals : 7;
 
     /// The number of parameters preceding this parameter in the
     /// function parameter scope in which it was declared.
@@ -1073,16 +1080,27 @@
   /// declaration is an integral constant expression.
   bool checkInitIsICE() const;
 
-  void setCXXDirectInitializer(bool T) { VarDeclBits.HasCXXDirectInit = T; }
+  void setInitStyle(InitializationStyle Style) {
+    VarDeclBits.InitStyle = Style;
+  }
 
-  /// hasCXXDirectInitializer - If true, the initializer was a direct
-  /// initializer, e.g: "int x(1);". The Init expression will be the expression
-  /// inside the parens or a "ClassType(a,b,c)" class constructor expression for
-  /// class types. Clients can distinguish between "int x(1);" and "int x=1;"
-  /// by checking hasCXXDirectInitializer.
+  /// \brief The style of initialization for this declaration.
   ///
-  bool hasCXXDirectInitializer() const {
-    return VarDeclBits.HasCXXDirectInit;
+  /// C-style initialization is "int x = 1;". Call-style initialization is
+  /// a C++98 direct-initializer, e.g. "int x(1);". The Init expression will be
+  /// the expression inside the parens or a "ClassType(a,b,c)" class constructor
+  /// expression for class types. List-style initialization is C++11 syntax,
+  /// e.g. "int x{1};". Clients can distinguish between different forms of
+  /// initialization by checking this value. In particular, "int x = {1};" is
+  /// C-style, "int x({1})" is call-style, and "int x{1};" is list-style; the
+  /// Init expression in all three cases is an InitListExpr.
+  InitializationStyle getInitStyle() const {
+    return static_cast<InitializationStyle>(VarDeclBits.InitStyle);
+  }
+
+  /// \brief Whether the initializer is a direct-initializer (list or call).
+  bool isDirectInit() const {
+    return getInitStyle() != CInit;
   }
 
   /// \brief Determine whether this variable is the exception variable in a

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Feb 11 17:51:47 2012
@@ -3977,7 +3977,7 @@
 
 public:
   ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs,
-                unsigned numexprs, SourceLocation rparenloc, QualType T);
+                unsigned numexprs, SourceLocation rparenloc);
 
   /// \brief Build an empty paren list.
   explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { }

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sat Feb 11 17:51:47 2012
@@ -812,6 +812,7 @@
   unsigned NumArgs : 16;
   bool Elidable : 1;
   bool HadMultipleCandidates : 1;
+  bool ListInitialization : 1;
   bool ZeroInitialization : 1;
   unsigned ConstructKind : 2;
   Stmt **Args;
@@ -822,32 +823,36 @@
                    CXXConstructorDecl *d, bool elidable,
                    Expr **args, unsigned numargs,
                    bool HadMultipleCandidates,
-                   bool ZeroInitialization = false,
-                   ConstructionKind ConstructKind = CK_Complete,
-                   SourceRange ParenRange = SourceRange());
+                   bool ListInitialization,
+                   bool ZeroInitialization,
+                   ConstructionKind ConstructKind,
+                   SourceRange ParenRange);
 
   /// \brief Construct an empty C++ construction expression.
   CXXConstructExpr(StmtClass SC, EmptyShell Empty)
-    : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(0),
-      HadMultipleCandidates(false), ZeroInitialization(0),
-      ConstructKind(0), Args(0) { }
+    : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(false),
+      HadMultipleCandidates(false), ListInitialization(false),
+      ZeroInitialization(false), ConstructKind(0), Args(0)
+  { }
 
 public:
   /// \brief Construct an empty C++ construction expression.
   explicit CXXConstructExpr(EmptyShell Empty)
     : Expr(CXXConstructExprClass, Empty), Constructor(0),
-      NumArgs(0), Elidable(0), HadMultipleCandidates(false),
-      ZeroInitialization(0), ConstructKind(0), Args(0) { }
+      NumArgs(0), Elidable(false), HadMultipleCandidates(false),
+      ListInitialization(false), ZeroInitialization(false),
+      ConstructKind(0), Args(0)
+  { }
 
   static CXXConstructExpr *Create(ASTContext &C, QualType T,
                                   SourceLocation Loc,
                                   CXXConstructorDecl *D, bool Elidable,
                                   Expr **Args, unsigned NumArgs,
                                   bool HadMultipleCandidates,
-                                  bool ZeroInitialization = false,
-                                  ConstructionKind ConstructKind = CK_Complete,
-                                  SourceRange ParenRange = SourceRange());
-
+                                  bool ListInitialization,
+                                  bool ZeroInitialization,
+                                  ConstructionKind ConstructKind,
+                                  SourceRange ParenRange);
 
   CXXConstructorDecl* getConstructor() const { return Constructor; }
   void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
@@ -864,6 +869,10 @@
   bool hadMultipleCandidates() const { return HadMultipleCandidates; }
   void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
 
+  /// \brief Whether this constructor call was written as list-initialization.
+  bool isListInitialization() const { return ListInitialization; }
+  void setListInitialization(bool V) { ListInitialization = V; }
+
   /// \brief Whether this construction first requires
   /// zero-initialization before the initializer is called.
   bool requiresZeroInitialization() const { return ZeroInitialization; }

Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Sat Feb 11 17:51:47 2012
@@ -326,20 +326,22 @@
 public:
   /// \brief The kind of initialization being performed.
   enum InitKind {
-    IK_Direct,  ///< Direct initialization
-    IK_Copy,    ///< Copy initialization
-    IK_Default, ///< Default initialization
-    IK_Value    ///< Value initialization
+    IK_Direct,     ///< Direct initialization
+    IK_DirectList, ///< Direct list-initialization
+    IK_Copy,       ///< Copy initialization
+    IK_Default,    ///< Default initialization
+    IK_Value       ///< Value initialization
   };
   
 private:
   /// \brief The kind of initialization that we're storing.
   enum StoredInitKind {
-    SIK_Direct = IK_Direct,   ///< Direct initialization
-    SIK_Copy = IK_Copy,       ///< Copy initialization
-    SIK_Default = IK_Default, ///< Default initialization
-    SIK_Value = IK_Value,     ///< Value initialization
-    SIK_ImplicitValue,        ///< Implicit value initialization
+    SIK_Direct = IK_Direct,         ///< Direct initialization
+    SIK_DirectList = IK_DirectList, ///< Direct list-initialization
+    SIK_Copy = IK_Copy,             ///< Copy initialization
+    SIK_Default = IK_Default,       ///< Default initialization
+    SIK_Value = IK_Value,           ///< Value initialization
+    SIK_ImplicitValue,              ///< Implicit value initialization
     SIK_DirectCast,  ///< Direct initialization due to a cast
     /// \brief Direct initialization due to a C-style cast.
     SIK_DirectCStyleCast,
@@ -370,6 +372,10 @@
     return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
   }
 
+  static InitializationKind CreateDirectList(SourceLocation InitLoc) {
+    return InitializationKind(SIK_DirectList, InitLoc, InitLoc, InitLoc);
+  }
+
   /// \brief Create a direct initialization due to a cast that isn't a C-style 
   /// or functional cast.
   static InitializationKind CreateCast(SourceRange TypeRange) {

Removed: cfe/trunk/include/clang/Sema/MultiInitializer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiInitializer.h?rev=150317&view=auto
==============================================================================
--- cfe/trunk/include/clang/Sema/MultiInitializer.h (original)
+++ cfe/trunk/include/clang/Sema/MultiInitializer.h (removed)
@@ -1,72 +0,0 @@
-//===--- MultiInitializer.h - Initializer expression group ------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the MultiInitializer class, which can represent a list
-// initializer or a parentheses-wrapped group of expressions in a C++ member
-// initializer.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_MULTIINITIALIZER_H
-#define LLVM_CLANG_SEMA_MULTIINITIALIZER_H
-
-#include "clang/Sema/Ownership.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/PointerUnion.h"
-
-namespace clang {
-  class ASTContext;
-  class Expr;
-  class InitializationKind;
-  class InitializedEntity;
-  class InitListExpr;
-  class Sema;
-
-class MultiInitializer {
-  llvm::PointerUnion<Expr*, Expr**> InitListOrExpressions;
-  unsigned NumInitializers;
-  SourceLocation LParenLoc;
-  SourceLocation RParenLoc;
-
-  InitListExpr *getInitList() const;
-  Expr **getExpressions() const { return InitListOrExpressions.get<Expr**>(); }
-
-public:
-  MultiInitializer(Expr* InitList)
-    : InitListOrExpressions(InitList)
-  {}
-
-  MultiInitializer(SourceLocation LParenLoc, Expr **Exprs, unsigned NumInits,
-                   SourceLocation RParenLoc)
-    : InitListOrExpressions(Exprs), NumInitializers(NumInits),
-    LParenLoc(LParenLoc), RParenLoc(RParenLoc)
-  {}
-
-  bool isInitializerList() const { return InitListOrExpressions.is<Expr*>(); }
-
-  SourceLocation getStartLoc() const;
-  SourceLocation getEndLoc() const;
-
-  typedef Expr **iterator;
-  iterator begin() const;
-  iterator end() const;
-
-  bool isTypeDependent() const;
-
-  bool DiagnoseUnexpandedParameterPack(Sema &SemaRef) const;
-
-  // Return the InitListExpr or create a ParenListExpr.
-  Expr *CreateInitExpr(ASTContext &Ctx, QualType T) const;
-
-  ExprResult PerformInit(Sema &SemaRef, InitializedEntity Entity,
-                         InitializationKind Kind) const;
-};
-}
-
-#endif

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Feb 11 17:51:47 2012
@@ -22,7 +22,6 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/Sema/LocInfoType.h"
-#include "clang/Sema/MultiInitializer.h"
 #include "clang/Sema/TypoCorrection.h"
 #include "clang/Sema/Weak.h"
 #include "clang/AST/Expr.h"
@@ -2387,9 +2386,9 @@
   ExprResult ActOnNumericConstant(const Token &Tok);
   ExprResult ActOnCharacterConstant(const Token &Tok);
   ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
-  ExprResult ActOnParenOrParenListExpr(SourceLocation L,
-                                       SourceLocation R,
-                                       MultiExprArg Val);
+  ExprResult ActOnParenListExpr(SourceLocation L,
+                                SourceLocation R,
+                                MultiExprArg Val);
 
   /// ActOnStringLiteral - The specified tokens were lexed as pasted string
   /// fragments (e.g. "foo" "bar" L"baz").
@@ -2769,15 +2768,6 @@
                               UnqualifiedId &Name,
                               TypeResult Type);
 
-  /// AddCXXDirectInitializerToDecl - This action is called immediately after
-  /// ActOnDeclarator, when a C++ direct initializer is present.
-  /// e.g: "int x(1);"
-  void AddCXXDirectInitializerToDecl(Decl *Dcl,
-                                     SourceLocation LParenLoc,
-                                     MultiExprArg Exprs,
-                                     SourceLocation RParenLoc,
-                                     bool TypeMayContainAuto);
-
   /// InitializeVarWithConstructor - Creates an CXXConstructExpr
   /// and sets it as the initializer for the the passed in VarDecl.
   bool InitializeVarWithConstructor(VarDecl *VD,
@@ -3574,21 +3564,21 @@
                                     ParsedType TemplateTypeTy,
                                     const DeclSpec &DS,
                                     SourceLocation IdLoc,
-                                    const MultiInitializer &Init,
+                                    Expr *Init,
                                     SourceLocation EllipsisLoc);
 
   MemInitResult BuildMemberInitializer(ValueDecl *Member,
-                                       const MultiInitializer &Args,
+                                       Expr *Init,
                                        SourceLocation IdLoc);
 
   MemInitResult BuildBaseInitializer(QualType BaseType,
                                      TypeSourceInfo *BaseTInfo,
-                                     const MultiInitializer &Args,
+                                     Expr *Init,
                                      CXXRecordDecl *ClassDecl,
                                      SourceLocation EllipsisLoc);
 
   MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo,
-                                           const MultiInitializer &Args,
+                                           Expr *Init,
                                            CXXRecordDecl *ClassDecl);
 
   bool SetDelegatingInitializer(CXXConstructorDecl *Constructor,
@@ -5186,6 +5176,10 @@
   Decl *SubstDecl(Decl *D, DeclContext *Owner,
                   const MultiLevelTemplateArgumentList &TemplateArgs);
 
+  ExprResult SubstInitializer(Expr *E,
+                       const MultiLevelTemplateArgumentList &TemplateArgs,
+                       bool CXXDirectInit);
+
   bool
   SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
                       CXXRecordDecl *Pattern,
@@ -5259,11 +5253,6 @@
   void InstantiateMemInitializers(CXXConstructorDecl *New,
                                   const CXXConstructorDecl *Tmpl,
                             const MultiLevelTemplateArgumentList &TemplateArgs);
-  bool InstantiateInitializer(Expr *Init,
-                            const MultiLevelTemplateArgumentList &TemplateArgs,
-                              SourceLocation &LParenLoc,
-                              ASTOwningVector<Expr*> &NewArgs,
-                              SourceLocation &RParenLoc);
 
   NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
                           const MultiLevelTemplateArgumentList &TemplateArgs);

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Sat Feb 11 17:51:47 2012
@@ -621,16 +621,20 @@
   Out << Name;
   Expr *Init = D->getInit();
   if (!Policy.SuppressInitializers && Init) {
-    if (D->hasCXXDirectInitializer())
-      Out << "(";
-    else {
-        CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init);
-        if (!CCE || CCE->getConstructor()->isCopyOrMoveConstructor())
-          Out << " = ";
-    }
-    Init->printPretty(Out, Context, 0, Policy, Indentation);
-    if (D->hasCXXDirectInitializer())
-      Out << ")";
+    bool ImplicitInit = false;
+    if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init))
+      ImplicitInit = D->getInitStyle() == VarDecl::CallInit &&
+          Construct->getNumArgs() == 0 && !Construct->isListInitialization();
+    if (!ImplicitInit) {
+      if (D->getInitStyle() == VarDecl::CallInit)
+        Out << "(";
+      else if (D->getInitStyle() == VarDecl::CInit) {
+        Out << " = ";
+      }
+      Init->printPretty(Out, Context, 0, Policy, Indentation);
+      if (D->getInitStyle() == VarDecl::CallInit)
+        Out << ")";
+    }
   }
   prettyPrintAttributes(D);
 }

Modified: cfe/trunk/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DumpXML.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DumpXML.cpp (original)
+++ cfe/trunk/lib/AST/DumpXML.cpp Sat Feb 11 17:51:47 2012
@@ -461,7 +461,13 @@
     if (D->getStorageClass() != SC_None)
       set("storage",
           VarDecl::getStorageClassSpecifierString(D->getStorageClass()));
-    setFlag("directinit", D->hasCXXDirectInitializer());
+    StringRef initStyle = "";
+    switch (D->getInitStyle()) {
+    case VarDecl::CInit: initStyle = "c"; break;
+    case VarDecl::CallInit: initStyle = "call"; break;
+    case VarDecl::ListInit: initStyle = "list"; break;
+    }
+    set("initstyle", initStyle);
     setFlag("nrvo", D->isNRVOVariable());
     // TODO: instantiation, etc.
   }

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sat Feb 11 17:51:47 2012
@@ -3414,11 +3414,10 @@
 
 ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc,
                              Expr **exprs, unsigned nexprs,
-                             SourceLocation rparenloc, QualType T)
-  : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary,
+                             SourceLocation rparenloc)
+  : Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary,
          false, false, false, false),
     NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) {
-  assert(!T.isNull() && "ParenListExpr must have a valid type");
   Exprs = new (C) Stmt*[nexprs];
   for (unsigned i = 0; i != nexprs; ++i) {
     if (exprs[i]->isTypeDependent())

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Sat Feb 11 17:51:47 2012
@@ -653,7 +653,7 @@
                      Type->getType().getNonReferenceType(), 
                      Type->getTypeLoc().getBeginLoc(),
                      Cons, false, Args, NumArgs,
-                     HadMultipleCandidates, ZeroInitialization,
+                     HadMultipleCandidates, /*FIXME*/false, ZeroInitialization,
                      CXXConstructExpr::CK_Complete, parenRange),
     Type(Type) {
 }
@@ -668,13 +668,15 @@
                                            CXXConstructorDecl *D, bool Elidable,
                                            Expr **Args, unsigned NumArgs,
                                            bool HadMultipleCandidates,
+                                           bool ListInitialization,
                                            bool ZeroInitialization,
                                            ConstructionKind ConstructKind,
                                            SourceRange ParenRange) {
   return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, 
                                   Elidable, Args, NumArgs,
-                                  HadMultipleCandidates, ZeroInitialization,
-                                  ConstructKind, ParenRange);
+                                  HadMultipleCandidates, ListInitialization,
+                                  ZeroInitialization, ConstructKind,
+                                  ParenRange);
 }
 
 CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
@@ -682,6 +684,7 @@
                                    CXXConstructorDecl *D, bool elidable,
                                    Expr **args, unsigned numargs,
                                    bool HadMultipleCandidates,
+                                   bool ListInitialization,
                                    bool ZeroInitialization,
                                    ConstructionKind ConstructKind,
                                    SourceRange ParenRange)
@@ -691,6 +694,7 @@
          T->containsUnexpandedParameterPack()),
     Constructor(D), Loc(Loc), ParenRange(ParenRange),  NumArgs(numargs),
     Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates),
+    ListInitialization(ListInitialization),
     ZeroInitialization(ZeroInitialization),
     ConstructKind(ConstructKind), Args(0)
 {

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Sat Feb 11 17:51:47 2012
@@ -2740,7 +2740,8 @@
                              CXXConstExpr->getConstructor(),
                              CXXConstExpr->isElidable(),
                              &ConstructorArgs[0], ConstructorArgs.size(),
-                             CXXConstExpr->hadMultipleCandidates(), 
+                             CXXConstExpr->hadMultipleCandidates(),
+                             CXXConstExpr->isListInitialization(),
                              CXXConstExpr->requiresZeroInitialization(),
                              CXXConstExpr->getConstructionKind(), SourceRange());
   

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sat Feb 11 17:51:47 2012
@@ -1344,10 +1344,11 @@
         ExitScope();
       }
 
-      Actions.AddCXXDirectInitializerToDecl(ThisDecl, T.getOpenLocation(),
-                                            move_arg(Exprs),
-                                            T.getCloseLocation(),
-                                            TypeContainsAuto);
+      ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
+                                                          T.getCloseLocation(),
+                                                          move_arg(Exprs));
+      Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
+                                   /*DirectInit=*/true, TypeContainsAuto);
     }
   } else if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
     // Parse C++0x braced-init-list.

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sat Feb 11 17:51:47 2012
@@ -2006,8 +2006,8 @@
 
     if (!ParseExpressionList(ArgExprs, CommaLocs)) {
       ExprType = SimpleExpr;
-      Result = Actions.ActOnParenOrParenListExpr(OpenLoc, Tok.getLocation(),
-                                                 move_arg(ArgExprs));
+      Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(),
+                                          move_arg(ArgExprs));
     }
   } else {
     InMessageExpressionRAIIObject InMessage(*this, false);

Modified: cfe/trunk/lib/Sema/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CMakeLists.txt?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CMakeLists.txt (original)
+++ cfe/trunk/lib/Sema/CMakeLists.txt Sat Feb 11 17:51:47 2012
@@ -8,7 +8,6 @@
   DelayedDiagnostic.cpp
   IdentifierResolver.cpp
   JumpDiagnostics.cpp
-  MultiInitializer.cpp
   Scope.cpp
   Sema.cpp
   SemaAccess.cpp

Removed: cfe/trunk/lib/Sema/MultiInitializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiInitializer.cpp?rev=150317&view=auto
==============================================================================
--- cfe/trunk/lib/Sema/MultiInitializer.cpp (original)
+++ cfe/trunk/lib/Sema/MultiInitializer.cpp (removed)
@@ -1,93 +0,0 @@
-//===--- MultiInitializer.cpp - Initializer expression group ----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the MultiInitializer class, which can represent a list
-// initializer or a parentheses-wrapped group of expressions in a C++ member
-// initializer.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Sema/MultiInitializer.h"
-#include "clang/Sema/Initialization.h"
-#include "clang/Sema/Sema.h"
-#include "clang/AST/Expr.h"
-
-using namespace clang;
-
-InitListExpr *MultiInitializer::getInitList() const {
-  return cast<InitListExpr>(InitListOrExpressions.get<Expr*>());
-}
-
-SourceLocation MultiInitializer::getStartLoc() const {
-  return isInitializerList() ? getInitList()->getLBraceLoc() : LParenLoc;
-}
-
-SourceLocation MultiInitializer::getEndLoc() const {
-  return isInitializerList() ? getInitList()->getRBraceLoc() : RParenLoc;
-}
-
-MultiInitializer::iterator MultiInitializer::begin() const {
-  return isInitializerList() ? getInitList()->getInits() : getExpressions();
-}
-
-MultiInitializer::iterator MultiInitializer::end() const {
-  if (isInitializerList()) {
-    InitListExpr *ILE = getInitList();
-    return ILE->getInits() + ILE->getNumInits();
-  }
-  return getExpressions() + NumInitializers;
-}
-
-bool MultiInitializer::isTypeDependent() const {
-  if (isInitializerList())
-    return getInitList()->isTypeDependent();
-  for (iterator I = begin(), E = end(); I != E; ++I) {
-    if ((*I)->isTypeDependent())
-      return true;
-  }
-  return false;
-}
-
-bool MultiInitializer::DiagnoseUnexpandedParameterPack(Sema &SemaRef) const {
-  if (isInitializerList())
-    return SemaRef.DiagnoseUnexpandedParameterPack(getInitList(),
-                                                   Sema::UPPC_Initializer);
-  for (iterator I = begin(), E = end(); I != E; ++I) {
-    if (SemaRef.DiagnoseUnexpandedParameterPack(*I, Sema::UPPC_Initializer))
-      return true;
-  }
-  return false;
-}
-
-Expr *MultiInitializer::CreateInitExpr(ASTContext &Ctx, QualType T) const {
-  if (isInitializerList())
-    return InitListOrExpressions.get<Expr*>();
-
-  return new (Ctx) ParenListExpr(Ctx, LParenLoc, getExpressions(),
-                                 NumInitializers, RParenLoc, T);
-}
-
-ExprResult MultiInitializer::PerformInit(Sema &SemaRef,
-                                         InitializedEntity Entity,
-                                         InitializationKind Kind) const {
-  Expr *Single;
-  Expr **Args;
-  unsigned NumArgs;
-  if (isInitializerList()) {
-    Single = InitListOrExpressions.get<Expr*>();
-    Args = &Single;
-    NumArgs = 1;
-  } else {
-    Args = getExpressions();
-    NumArgs = NumInitializers;
-  }
-  InitializationSequence InitSeq(SemaRef, Entity, Kind, Args, NumArgs);
-  return InitSeq.Perform(SemaRef, Entity, Kind,
-                         MultiExprArg(SemaRef, Args, NumArgs), 0);
-}

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Feb 11 17:51:47 2012
@@ -2139,9 +2139,8 @@
 /// emitting diagnostics as appropriate.
 ///
 /// Declarations using the auto type specifier (C++ [decl.spec.auto]) call back
-/// to here in AddInitializerToDecl and AddCXXDirectInitializerToDecl. We can't
-/// check them before the initializer is attached.
-///
+/// to here in AddInitializerToDecl. We can't check them before the initializer
+/// is attached.
 void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old) {
   if (New->isInvalidDecl() || Old->isInvalidDecl())
     return;
@@ -5983,17 +5982,6 @@
   if (RealDecl == 0 || RealDecl->isInvalidDecl())
     return;
 
-  // Check for self-references within variable initializers.
-  if (VarDecl *vd = dyn_cast<VarDecl>(RealDecl)) {
-    // Variables declared within a function/method body are handled
-    // by a dataflow analysis.
-    if (!vd->hasLocalStorage() && !vd->isStaticLocal())
-      CheckSelfReference(RealDecl, Init);    
-  }
-  else {
-    CheckSelfReference(RealDecl, Init);
-  }
-
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
     // With declarators parsed the way they are, the parser cannot
     // distinguish between a normal initializer and a pure-specifier.
@@ -6018,12 +6006,44 @@
     return;
   }
 
+  // Check for self-references within variable initializers.
+  // Variables declared within a function/method body are handled
+  // by a dataflow analysis.
+  if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal())
+    CheckSelfReference(RealDecl, Init);
+
+  ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
+
   // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
+    Expr *DeduceInit = Init;
+    // Initializer could be a C++ direct-initializer. Deduction only works if it
+    // contains exactly one expression.
+    if (CXXDirectInit) {
+      if (CXXDirectInit->getNumExprs() == 0) {
+        // It isn't possible to write this directly, but it is possible to
+        // end up in this situation with "auto x(some_pack...);"
+        Diag(CXXDirectInit->getSourceRange().getBegin(),
+             diag::err_auto_var_init_no_expression)
+          << VDecl->getDeclName() << VDecl->getType()
+          << VDecl->getSourceRange();
+        RealDecl->setInvalidDecl();
+        return;
+      } else if (CXXDirectInit->getNumExprs() > 1) {
+        Diag(CXXDirectInit->getExpr(1)->getSourceRange().getBegin(),
+             diag::err_auto_var_init_multiple_expressions)
+          << VDecl->getDeclName() << VDecl->getType()
+          << VDecl->getSourceRange();
+        RealDecl->setInvalidDecl();
+        return;
+      } else {
+        DeduceInit = CXXDirectInit->getExpr(0);
+      }
+    }
     TypeSourceInfo *DeducedType = 0;
-    if (DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType) ==
+    if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) ==
             DAR_Failed)
-      DiagnoseAutoDeductionFailure(VDecl, Init);
+      DiagnoseAutoDeductionFailure(VDecl, DeduceInit);
     if (!DeducedType) {
       RealDecl->setInvalidDecl();
       return;
@@ -6048,25 +6068,26 @@
     return;
   }
 
+  if (!VDecl->getType()->isDependentType()) {
+    // A definition must end up with a complete type, which means it must be
+    // complete with the restriction that an array type might be completed by
+    // the initializer; note that later code assumes this restriction.
+    QualType BaseDeclType = VDecl->getType();
+    if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType))
+      BaseDeclType = Array->getElementType();
+    if (RequireCompleteType(VDecl->getLocation(), BaseDeclType,
+                            diag::err_typecheck_decl_incomplete_type)) {
+      RealDecl->setInvalidDecl();
+      return;
+    }
 
-  // A definition must end up with a complete type, which means it must be
-  // complete with the restriction that an array type might be completed by the
-  // initializer; note that later code assumes this restriction.
-  QualType BaseDeclType = VDecl->getType();
-  if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType))
-    BaseDeclType = Array->getElementType();
-  if (RequireCompleteType(VDecl->getLocation(), BaseDeclType,
-                          diag::err_typecheck_decl_incomplete_type)) {
-    RealDecl->setInvalidDecl();
-    return;
+    // The variable can not have an abstract class type.
+    if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
+                               diag::err_abstract_type_in_decl,
+                               AbstractVariableType))
+      VDecl->setInvalidDecl();
   }
 
-  // The variable can not have an abstract class type.
-  if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
-                             diag::err_abstract_type_in_decl,
-                             AbstractVariableType))
-    VDecl->setInvalidDecl();
-
   const VarDecl *Def;
   if ((Def = VDecl->getDefinition()) && Def != VDecl) {
     Diag(VDecl->getLocation(), diag::err_redefinition)
@@ -6128,9 +6149,15 @@
                    : InitializationKind::CreateCopy(VDecl->getLocation(),
                                                     Init->getLocStart());
 
-    InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+    Expr **Args = &Init;
+    unsigned NumArgs = 1;
+    if (CXXDirectInit) {
+      Args = CXXDirectInit->getExprs();
+      NumArgs = CXXDirectInit->getNumExprs();
+    }
+    InitializationSequence InitSeq(*this, Entity, Kind, Args, NumArgs);
     ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                              MultiExprArg(*this, &Init, 1),
+                                              MultiExprArg(*this, Args,NumArgs),
                                               &DclT);
     if (Result.isInvalid()) {
       VDecl->setInvalidDecl();
@@ -6266,6 +6293,28 @@
       CheckForConstantInitializer(Init, DclT);
   }
 
+  // We will represent direct-initialization similarly to copy-initialization:
+  //    int x(1);  -as-> int x = 1;
+  //    ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
+  //
+  // Clients that want to distinguish between the two forms, can check for
+  // direct initializer using VarDecl::getInitStyle().
+  // A major benefit is that clients that don't particularly care about which
+  // exactly form was it (like the CodeGen) can handle both cases without
+  // special case code.
+
+  // C++ 8.5p11:
+  // The form of initialization (using parentheses or '=') is generally
+  // insignificant, but does matter when the entity being initialized has a
+  // class type.
+  if (CXXDirectInit) {
+    assert(DirectInit && "Call-style initializer must be direct init.");
+    VDecl->setInitStyle(VarDecl::CallInit);
+  } else if (DirectInit) {
+    // This must be list-initialization. No other way is direct-initialization.
+    VDecl->setInitStyle(VarDecl::ListInit);
+  }
+
   CheckCompleteVariableDeclaration(VDecl);
 }
 
@@ -6496,8 +6545,11 @@
                                       MultiExprArg(*this, 0, 0));
     if (Init.isInvalid())
       Var->setInvalidDecl();
-    else if (Init.get())
+    else if (Init.get()) {
       Var->setInit(MaybeCreateExprWithCleanups(Init.get()));
+      // This is important for template substitution.
+      Var->setInitStyle(VarDecl::CallInit);
+    }
 
     CheckCompleteVariableDeclaration(Var);
   }

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Feb 11 17:51:47 2012
@@ -1768,7 +1768,7 @@
                           Expr *InitList,
                           SourceLocation EllipsisLoc) {
   return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy,
-                             DS, IdLoc, MultiInitializer(InitList), 
+                             DS, IdLoc, InitList,
                              EllipsisLoc);
 }
 
@@ -1785,10 +1785,10 @@
                           Expr **Args, unsigned NumArgs,
                           SourceLocation RParenLoc,
                           SourceLocation EllipsisLoc) {
+  Expr *List = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                           RParenLoc);
   return BuildMemInitializer(ConstructorD, S, SS, MemberOrBase, TemplateTypeTy,
-                             DS, IdLoc, MultiInitializer(LParenLoc, Args, 
-                                                         NumArgs, RParenLoc),
-                             EllipsisLoc);
+                             DS, IdLoc, List, EllipsisLoc);
 }
 
 namespace {
@@ -1825,7 +1825,7 @@
                           ParsedType TemplateTypeTy,
                           const DeclSpec &DS,
                           SourceLocation IdLoc,
-                          const MultiInitializer &Args,
+                          Expr *Init,
                           SourceLocation EllipsisLoc) {
   if (!ConstructorD)
     return true;
@@ -1864,9 +1864,10 @@
           (Member = dyn_cast<IndirectFieldDecl>(*Result.first))) {
         if (EllipsisLoc.isValid())
           Diag(EllipsisLoc, diag::err_pack_expansion_member_init)
-            << MemberOrBase << SourceRange(IdLoc, Args.getEndLoc());
+            << MemberOrBase
+            << SourceRange(IdLoc, Init->getSourceRange().getEnd());
 
-        return BuildMemberInitializer(Member, Args, IdLoc);
+        return BuildMemberInitializer(Member, Init, IdLoc);
       }
     }
   }
@@ -1927,7 +1928,7 @@
           Diag(Member->getLocation(), diag::note_previous_decl)
             << CorrectedQuotedStr;
 
-          return BuildMemberInitializer(Member, Args, IdLoc);
+          return BuildMemberInitializer(Member, Init, IdLoc);
         } else if (TypeDecl *Type = Corr.getCorrectionDeclAs<TypeDecl>()) {
           const CXXBaseSpecifier *DirectBaseSpec;
           const CXXBaseSpecifier *VirtualBaseSpec;
@@ -1955,7 +1956,7 @@
 
       if (!TyD && BaseType.isNull()) {
         Diag(IdLoc, diag::err_mem_init_not_member_or_class)
-          << MemberOrBase << SourceRange(IdLoc, Args.getEndLoc());
+          << MemberOrBase << SourceRange(IdLoc,Init->getSourceRange().getEnd());
         return true;
       }
     }
@@ -1975,7 +1976,7 @@
   if (!TInfo)
     TInfo = Context.getTrivialTypeSourceInfo(BaseType, IdLoc);
 
-  return BuildBaseInitializer(BaseType, TInfo, Args, ClassDecl, EllipsisLoc);
+  return BuildBaseInitializer(BaseType, TInfo, Init, ClassDecl, EllipsisLoc);
 }
 
 /// Checks a member initializer expression for cases where reference (or
@@ -2102,15 +2103,14 @@
 }
 
 MemInitResult
-Sema::BuildMemberInitializer(ValueDecl *Member,
-                             const MultiInitializer &Args,
+Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
                              SourceLocation IdLoc) {
   FieldDecl *DirectMember = dyn_cast<FieldDecl>(Member);
   IndirectFieldDecl *IndirectMember = dyn_cast<IndirectFieldDecl>(Member);
   assert((DirectMember || IndirectMember) &&
          "Member must be a FieldDecl or IndirectFieldDecl");
 
-  if (Args.DiagnoseUnexpandedParameterPack(*this))
+  if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer))
     return true;
 
   if (Member->isInvalidDecl())
@@ -2120,13 +2120,19 @@
   //   foo(foo)
   // where foo is not also a parameter to the constructor.
   // TODO: implement -Wuninitialized and fold this into that framework.
-  for (MultiInitializer::iterator I = Args.begin(), E = Args.end();
-       I != E; ++I) {
+  Expr **Args;
+  unsigned NumArgs;
+  if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+    Args = ParenList->getExprs();
+    NumArgs = ParenList->getNumExprs();
+  } else {
+    InitListExpr *InitList = cast<InitListExpr>(Init);
+    Args = InitList->getInits();
+    NumArgs = InitList->getNumInits();
+  }
+  for (unsigned i = 0; i < NumArgs; ++i) {
     SourceLocation L;
-    Expr *Arg = *I;
-    if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(Arg))
-      Arg = DIE->getInit();
-    if (InitExprContainsUninitializedFields(Arg, Member, &L)) {
+    if (InitExprContainsUninitializedFields(Args[i], Member, &L)) {
       // FIXME: Return true in the case when other fields are used before being
       // uninitialized. For example, let this field be the i'th field. When
       // initializing the i'th field, throw a warning if any of the >= i'th
@@ -2137,14 +2143,11 @@
     }
   }
 
-  bool HasDependentArg = Args.isTypeDependent();
+  SourceRange InitRange = Init->getSourceRange();
 
-  Expr *Init;
-  if (Member->getType()->isDependentType() || HasDependentArg) {
+  if (Member->getType()->isDependentType() || Init->isTypeDependent()) {
     // Can't check initialization for a member of dependent type or when
     // any of the arguments are type-dependent expressions.
-    Init = Args.CreateInitExpr(Context,Member->getType().getNonReferenceType());
-
     DiscardCleanupsInEvaluationContext();
   } else {
     // Initialize the member.
@@ -2152,14 +2155,22 @@
       DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0)
                    : InitializedEntity::InitializeMember(IndirectMember, 0);
     InitializationKind Kind =
-      InitializationKind::CreateDirect(IdLoc, Args.getStartLoc(),
-                                       Args.getEndLoc());
+      InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
+                                       InitRange.getEnd());
 
-    ExprResult MemberInit = Args.PerformInit(*this, MemberEntity, Kind);
+    if (isa<InitListExpr>(Init)) {
+      Args = &Init;
+      NumArgs = 1;
+    }
+    InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
+    ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind,
+                                            MultiExprArg(*this, Args, NumArgs),
+                                            0);
     if (MemberInit.isInvalid())
       return true;
 
-    CheckImplicitConversions(MemberInit.get(), Args.getStartLoc());
+    CheckImplicitConversions(MemberInit.get(),
+                             InitRange.getBegin());
 
     // C++0x [class.base.init]p7:
     //   The initialization of each base and member constitutes a
@@ -2170,14 +2181,13 @@
 
     // If we are in a dependent context, template instantiation will
     // perform this type-checking again. Just save the arguments that we
-    // received in a ParenListExpr.
+    // received.
     // FIXME: This isn't quite ideal, since our ASTs don't capture all
     // of the information that we have about the member
     // initializer. However, deconstructing the ASTs is a dicey process,
     // and this approach is far more likely to get the corner cases right.
     if (CurContext->isDependentContext()) {
-      Init = Args.CreateInitExpr(Context,
-                                 Member->getType().getNonReferenceType());
+      // The existing Init will do fine.
     } else {
       Init = MemberInit.get();
       CheckForDanglingReferenceOrPointer(*this, Member, Init, IdLoc);
@@ -2185,19 +2195,18 @@
   }
 
   if (DirectMember) {
-    return new (Context) CXXCtorInitializer(Context, DirectMember,
-                                                    IdLoc, Args.getStartLoc(),
-                                                    Init, Args.getEndLoc());
+    return new (Context) CXXCtorInitializer(Context, DirectMember, IdLoc,
+                                            InitRange.getBegin(), Init,
+                                            InitRange.getEnd());
   } else {
-    return new (Context) CXXCtorInitializer(Context, IndirectMember,
-                                                    IdLoc, Args.getStartLoc(),
-                                                    Init, Args.getEndLoc());
+    return new (Context) CXXCtorInitializer(Context, IndirectMember, IdLoc,
+                                            InitRange.getBegin(), Init,
+                                            InitRange.getEnd());
   }
 }
 
 MemInitResult
-Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo,
-                                 const MultiInitializer &Args,
+Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
                                  CXXRecordDecl *ClassDecl) {
   SourceLocation NameLoc = TInfo->getTypeLoc().getLocalSourceRange().getBegin();
   if (!LangOpts.CPlusPlus0x)
@@ -2205,21 +2214,31 @@
       << TInfo->getTypeLoc().getLocalSourceRange();
   Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
 
+  SourceRange InitRange = Init->getSourceRange();
   // Initialize the object.
   InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
                                      QualType(ClassDecl->getTypeForDecl(), 0));
   InitializationKind Kind =
-    InitializationKind::CreateDirect(NameLoc, Args.getStartLoc(),
-                                     Args.getEndLoc());
+    InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(),
+                                     InitRange.getEnd());
 
-  ExprResult DelegationInit = Args.PerformInit(*this, DelegationEntity, Kind);
+  Expr **Args = &Init;
+  unsigned NumArgs = 1;
+  if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+    Args = ParenList->getExprs();
+    NumArgs = ParenList->getNumExprs();
+  }
+  InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args, NumArgs);
+  ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind,
+                                              MultiExprArg(*this, Args,NumArgs),
+                                              0);
   if (DelegationInit.isInvalid())
     return true;
 
   assert(cast<CXXConstructExpr>(DelegationInit.get())->getConstructor() &&
          "Delegating constructor with no target?");
 
-  CheckImplicitConversions(DelegationInit.get(), Args.getStartLoc());
+  CheckImplicitConversions(DelegationInit.get(), InitRange.getBegin());
 
   // C++0x [class.base.init]p7:
   //   The initialization of each base and member constitutes a
@@ -2228,18 +2247,15 @@
   if (DelegationInit.isInvalid())
     return true;
 
-  return new (Context) CXXCtorInitializer(Context, TInfo, Args.getStartLoc(), 
+  return new (Context) CXXCtorInitializer(Context, TInfo, InitRange.getBegin(), 
                                           DelegationInit.takeAs<Expr>(),
-                                          Args.getEndLoc());
+                                          InitRange.getEnd());
 }
 
 MemInitResult
 Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
-                           const MultiInitializer &Args,
-                           CXXRecordDecl *ClassDecl,
+                           Expr *Init, CXXRecordDecl *ClassDecl,
                            SourceLocation EllipsisLoc) {
-  bool HasDependentArg = Args.isTypeDependent();
-
   SourceLocation BaseLoc
     = BaseTInfo->getTypeLoc().getLocalSourceRange().getBegin();
 
@@ -2253,13 +2269,14 @@
   //   of that class, the mem-initializer is ill-formed. A
   //   mem-initializer-list can initialize a base class using any
   //   name that denotes that base class type.
-  bool Dependent = BaseType->isDependentType() || HasDependentArg;
+  bool Dependent = BaseType->isDependentType() || Init->isTypeDependent();
 
+  SourceRange InitRange = Init->getSourceRange();
   if (EllipsisLoc.isValid()) {
     // This is a pack expansion.
     if (!BaseType->containsUnexpandedParameterPack())  {
       Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
-        << SourceRange(BaseLoc, Args.getEndLoc());
+        << SourceRange(BaseLoc, InitRange.getEnd());
 
       EllipsisLoc = SourceLocation();
     }
@@ -2268,7 +2285,7 @@
     if (DiagnoseUnexpandedParameterPack(BaseLoc, BaseTInfo, UPPC_Initializer))
       return true;
 
-    if (Args.DiagnoseUnexpandedParameterPack(*this))
+    if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer))
       return true;
   }
 
@@ -2278,7 +2295,7 @@
   if (!Dependent) { 
     if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0),
                                        BaseType))
-      return BuildDelegatingInitializer(BaseTInfo, Args, ClassDecl);
+      return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl);
 
     FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec, 
                         VirtualBaseSpec);
@@ -2303,16 +2320,12 @@
   }
 
   if (Dependent) {
-    // Can't check initialization for a base of dependent type or when
-    // any of the arguments are type-dependent expressions.
-    Expr *BaseInit = Args.CreateInitExpr(Context, BaseType);
-
     DiscardCleanupsInEvaluationContext();
 
     return new (Context) CXXCtorInitializer(Context, BaseTInfo,
                                             /*IsVirtual=*/false,
-                                            Args.getStartLoc(), BaseInit,
-                                            Args.getEndLoc(), EllipsisLoc);
+                                            InitRange.getBegin(), Init,
+                                            InitRange.getEnd(), EllipsisLoc);
   }
 
   // C++ [base.class.init]p2:
@@ -2323,8 +2336,7 @@
     return Diag(BaseLoc, diag::err_base_init_direct_and_virtual)
       << BaseType << BaseTInfo->getTypeLoc().getLocalSourceRange();
 
-  CXXBaseSpecifier *BaseSpec
-    = const_cast<CXXBaseSpecifier *>(DirectBaseSpec);
+  CXXBaseSpecifier *BaseSpec = const_cast<CXXBaseSpecifier *>(DirectBaseSpec);
   if (!BaseSpec)
     BaseSpec = const_cast<CXXBaseSpecifier *>(VirtualBaseSpec);
 
@@ -2332,14 +2344,23 @@
   InitializedEntity BaseEntity =
     InitializedEntity::InitializeBase(Context, BaseSpec, VirtualBaseSpec);
   InitializationKind Kind = 
-    InitializationKind::CreateDirect(BaseLoc, Args.getStartLoc(),
-                                     Args.getEndLoc());
+    InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
+                                     InitRange.getEnd());
 
-  ExprResult BaseInit = Args.PerformInit(*this, BaseEntity, Kind);
+  Expr **Args = &Init;
+  unsigned NumArgs = 1;
+  if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+    Args = ParenList->getExprs();
+    NumArgs = ParenList->getNumExprs();
+  }
+  InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
+  ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind,
+                                          MultiExprArg(*this, Args, NumArgs),
+                                          0);
   if (BaseInit.isInvalid())
     return true;
 
-  CheckImplicitConversions(BaseInit.get(), Args.getStartLoc());
+  CheckImplicitConversions(BaseInit.get(), InitRange.getBegin());
 
   // C++0x [class.base.init]p7:
   //   The initialization of each base and member constitutes a 
@@ -2356,13 +2377,13 @@
   // initializer. However, deconstructing the ASTs is a dicey process,
   // and this approach is far more likely to get the corner cases right.
   if (CurContext->isDependentContext())
-    BaseInit = Owned(Args.CreateInitExpr(Context, BaseType));
+    BaseInit = Owned(Init);
 
   return new (Context) CXXCtorInitializer(Context, BaseTInfo,
                                           BaseSpec->isVirtual(),
-                                          Args.getStartLoc(),
+                                          InitRange.getBegin(),
                                           BaseInit.takeAs<Expr>(),
-                                          Args.getEndLoc(), EllipsisLoc);
+                                          InitRange.getEnd(), EllipsisLoc);
 }
 
 // Create a static_cast\<T&&>(expr).
@@ -9064,7 +9085,8 @@
   MarkFunctionReferenced(ConstructLoc, Constructor);
   return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
                                         Constructor, Elidable, Exprs, NumExprs,
-                                        HadMultipleCandidates, RequiresZeroInit,
+                                        HadMultipleCandidates, /*FIXME*/false,
+                                        RequiresZeroInit,
               static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
                                         ParenRange));
 }
@@ -9116,187 +9138,6 @@
     Diag(VD->getLocation(), diag::warn_global_destructor);
 }
 
-/// AddCXXDirectInitializerToDecl - This action is called immediately after
-/// ActOnDeclarator, when a C++ direct initializer is present.
-/// e.g: "int x(1);"
-void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
-                                         SourceLocation LParenLoc,
-                                         MultiExprArg Exprs,
-                                         SourceLocation RParenLoc,
-                                         bool TypeMayContainAuto) {
-  // If there is no declaration, there was an error parsing it.  Just ignore
-  // the initializer.
-  if (RealDecl == 0)
-    return;
-
-  VarDecl *VDecl = dyn_cast<VarDecl>(RealDecl);
-  if (!VDecl) {
-    Diag(RealDecl->getLocation(), diag::err_illegal_initializer);
-    RealDecl->setInvalidDecl();
-    return;
-  }
-
-  // C++0x [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
-  if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
-    if (Exprs.size() == 0) {
-      // It isn't possible to write this directly, but it is possible to
-      // end up in this situation with "auto x(some_pack...);"
-      Diag(LParenLoc, diag::err_auto_var_init_no_expression)
-        << VDecl->getDeclName() << VDecl->getType()
-        << VDecl->getSourceRange();
-      RealDecl->setInvalidDecl();
-      return;
-    }
-
-    if (Exprs.size() > 1) {
-      Diag(Exprs.get()[1]->getSourceRange().getBegin(),
-           diag::err_auto_var_init_multiple_expressions)
-        << VDecl->getDeclName() << VDecl->getType()
-        << VDecl->getSourceRange();
-      RealDecl->setInvalidDecl();
-      return;
-    }
-
-    Expr *Init = Exprs.get()[0];
-    TypeSourceInfo *DeducedType = 0;
-    if (DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType) ==
-            DAR_Failed)
-      DiagnoseAutoDeductionFailure(VDecl, Init);
-    if (!DeducedType) {
-      RealDecl->setInvalidDecl();
-      return;
-    }
-    VDecl->setTypeSourceInfo(DeducedType);
-    VDecl->setType(DeducedType->getType());
-
-    // In ARC, infer lifetime.
-    if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
-      VDecl->setInvalidDecl();
-
-    // If this is a redeclaration, check that the type we just deduced matches
-    // the previously declared type.
-    if (VarDecl *Old = VDecl->getPreviousDecl())
-      MergeVarDeclTypes(VDecl, Old);
-  }
-
-  // We will represent direct-initialization similarly to copy-initialization:
-  //    int x(1);  -as-> int x = 1;
-  //    ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
-  //
-  // Clients that want to distinguish between the two forms, can check for
-  // direct initializer using VarDecl::hasCXXDirectInitializer().
-  // A major benefit is that clients that don't particularly care about which
-  // exactly form was it (like the CodeGen) can handle both cases without
-  // special case code.
-
-  // C++ 8.5p11:
-  // The form of initialization (using parentheses or '=') is generally
-  // insignificant, but does matter when the entity being initialized has a
-  // class type.
-
-  if (!VDecl->getType()->isDependentType() &&
-      !VDecl->getType()->isIncompleteArrayType() && 
-      RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
-                          diag::err_typecheck_decl_incomplete_type)) {
-    VDecl->setInvalidDecl();
-    return;
-  }
-
-  // The variable can not have an abstract class type.
-  if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(),
-                             diag::err_abstract_type_in_decl,
-                             AbstractVariableType))
-    VDecl->setInvalidDecl();
-
-  const VarDecl *Def;
-  if ((Def = VDecl->getDefinition()) && Def != VDecl) {
-    Diag(VDecl->getLocation(), diag::err_redefinition)
-    << VDecl->getDeclName();
-    Diag(Def->getLocation(), diag::note_previous_definition);
-    VDecl->setInvalidDecl();
-    return;
-  }
-
-  // C++ [class.static.data]p4
-  //   If a static data member is of const integral or const
-  //   enumeration type, its declaration in the class definition can
-  //   specify a constant-initializer which shall be an integral
-  //   constant expression (5.19). In that case, the member can appear
-  //   in integral constant expressions. The member shall still be
-  //   defined in a namespace scope if it is used in the program and the
-  //   namespace scope definition shall not contain an initializer.
-  //
-  // We already performed a redefinition check above, but for static
-  // data members we also need to check whether there was an in-class
-  // declaration with an initializer.
-  const VarDecl* PrevInit = 0;
-  if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
-    Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
-    Diag(PrevInit->getLocation(), diag::note_previous_definition);
-    return;
-  } 
-
-  if (VDecl->hasLocalStorage())
-    getCurFunction()->setHasBranchProtectedScope();
-
-  bool IsDependent = false;
-  for (unsigned I = 0, N = Exprs.size(); I != N; ++I) {
-    if (DiagnoseUnexpandedParameterPack(Exprs.get()[I], UPPC_Expression)) {
-      VDecl->setInvalidDecl();
-      return;
-    }
-
-    if (Exprs.get()[I]->isTypeDependent())
-      IsDependent = true;
-  }
-
-  // If either the declaration has a dependent type or if any of the
-  // expressions is type-dependent, we represent the initialization
-  // via a ParenListExpr for later use during template instantiation.
-  if (VDecl->getType()->isDependentType() || IsDependent) {
-    // Let clients know that initialization was done with a direct initializer.
-    VDecl->setCXXDirectInitializer(true);
-
-    // Store the initialization expressions as a ParenListExpr.
-    unsigned NumExprs = Exprs.size();
-    VDecl->setInit(new (Context) ParenListExpr(
-        Context, LParenLoc, (Expr **)Exprs.release(), NumExprs, RParenLoc,
-        VDecl->getType().getNonReferenceType()));
-    return;
-  }
-  
-  // Capture the variable that is being initialized and the style of
-  // initialization.
-  InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
-  
-  // FIXME: Poor source location information.
-  InitializationKind Kind
-    = InitializationKind::CreateDirect(VDecl->getLocation(),
-                                       LParenLoc, RParenLoc);
-  
-  QualType T = VDecl->getType();
-  InitializationSequence InitSeq(*this, Entity, Kind, 
-                                 Exprs.get(), Exprs.size());
-  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs), &T);
-  if (Result.isInvalid()) {
-    VDecl->setInvalidDecl();
-    return;
-  } else if (T != VDecl->getType()) {
-    VDecl->setType(T);
-    Result.get()->setType(T);
-  }
-
-  
-  Expr *Init = Result.get();
-  CheckImplicitConversions(Init, LParenLoc);
-
-  Init = MaybeCreateExprWithCleanups(Init);
-  VDecl->setInit(Init);
-  VDecl->setCXXDirectInitializer(true);
-
-  CheckCompleteVariableDeclaration(VDecl);
-}
-
 /// \brief Given a constructor and the set of arguments provided for the
 /// constructor, convert the arguments and add any required default arguments
 /// to form a proper call to this constructor.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Feb 11 17:51:47 2012
@@ -2920,6 +2920,11 @@
   case tok::minusminus: Opc = UO_PostDec; break;
   }
 
+  // Since this might is a postfix expression, get rid of ParenListExprs.
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Input);
+  if (Result.isInvalid()) return ExprError();
+  Input = Result.take();
+
   return BuildUnaryOp(S, OpLoc, Opc, Input);
 }
 
@@ -4251,8 +4256,8 @@
   return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE);
 }
 
-/// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence
-/// of comma binary operators.
+/// This is not an AltiVec-style cast or or C++ direct-initialization, so turn
+/// the ParenListExpr into a sequence of comma binary operators.
 ExprResult
 Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
   ParenListExpr *E = dyn_cast<ParenListExpr>(OrigExpr);
@@ -4270,18 +4275,13 @@
   return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get());
 }
 
-ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
-                                           SourceLocation R,
-                                           MultiExprArg Val) {
+ExprResult Sema::ActOnParenListExpr(SourceLocation L,
+                                    SourceLocation R,
+                                    MultiExprArg Val) {
   unsigned nexprs = Val.size();
   Expr **exprs = reinterpret_cast<Expr**>(Val.release());
   assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
-  Expr *expr;
-  if (nexprs == 1)
-    expr = new (Context) ParenExpr(L, R, exprs[0]);
-  else
-    expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R,
-                                       exprs[nexprs-1]->getType());
+  Expr *expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R);
   return Owned(expr);
 }
 

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Feb 11 17:51:47 2012
@@ -4708,6 +4708,13 @@
 
       }
     }
+    if (Kind.getKind() == InitializationKind::IK_Direct &&
+        !Kind.isExplicitCast()) {
+      // Rebuild the ParenListExpr.
+      SourceRange ParenRange = Kind.getParenRange();
+      return S.ActOnParenListExpr(ParenRange.getBegin(), ParenRange.getEnd(),
+                                  move(Args));
+    }
     assert(Kind.getKind() == InitializationKind::IK_Copy ||
            Kind.isExplicitCast());
     return ExprResult(Args.release()[0]);

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Feb 11 17:51:47 2012
@@ -1833,14 +1833,16 @@
     FieldDecl *NewField = FieldsWithMemberInitializers[I].second;
     Expr *OldInit = OldField->getInClassInitializer();
 
-    SourceLocation LParenLoc, RParenLoc;
-    ASTOwningVector<Expr*> NewArgs(*this);
-    if (InstantiateInitializer(OldInit, TemplateArgs, LParenLoc, NewArgs,
-                               RParenLoc))
+    ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
+                                          /*CXXDirectInit=*/false);
+    if (NewInit.isInvalid())
       NewField->setInvalidDecl();
     else {
-      assert(NewArgs.size() == 1 && "wrong number of in-class initializers");
-      ActOnCXXInClassMemberInitializer(NewField, LParenLoc, NewArgs[0]);
+      Expr *Init = NewInit.take();
+      assert(Init && "no-argument initializer in class");
+      assert(!isa<ParenListExpr>(Init) && "call-style init in class");
+      ActOnCXXInClassMemberInitializer(NewField,
+                                       Init->getSourceRange().getBegin(), Init);
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Feb 11 17:51:47 2012
@@ -252,66 +252,6 @@
   return Inst;
 }
 
-/// \brief Instantiate an initializer, breaking it into separate
-/// initialization arguments.
-///
-/// \param Init The initializer to instantiate.
-///
-/// \param TemplateArgs Template arguments to be substituted into the
-/// initializer.
-///
-/// \param NewArgs Will be filled in with the instantiation arguments.
-///
-/// \returns true if an error occurred, false otherwise
-bool Sema::InstantiateInitializer(Expr *Init,
-                            const MultiLevelTemplateArgumentList &TemplateArgs,
-                                  SourceLocation &LParenLoc,
-                                  ASTOwningVector<Expr*> &NewArgs,
-                                  SourceLocation &RParenLoc) {
-  NewArgs.clear();
-  LParenLoc = SourceLocation();
-  RParenLoc = SourceLocation();
-
-  if (!Init)
-    return false;
-
-  if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
-    Init = ExprTemp->getSubExpr();
-
-  while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
-    Init = Binder->getSubExpr();
-
-  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
-    Init = ICE->getSubExprAsWritten();
-
-  if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
-    LParenLoc = ParenList->getLParenLoc();
-    RParenLoc = ParenList->getRParenLoc();
-    return SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(),
-                      true, TemplateArgs, NewArgs);
-  }
-
-  if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) {
-    if (!isa<CXXTemporaryObjectExpr>(Construct)) {
-      if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true,
-                     TemplateArgs, NewArgs))
-        return true;
-
-      // FIXME: Fake locations!
-      LParenLoc = PP.getLocForEndOfToken(Init->getLocStart());
-      RParenLoc = LParenLoc;
-      return false;
-    }
-  }
-
-  ExprResult Result = SubstExpr(Init, TemplateArgs);
-  if (Result.isInvalid())
-    return true;
-
-  NewArgs.push_back(Result.takeAs<Expr>());
-  return false;
-}
-
 Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
   // If this is the variable for an anonymous struct or union,
   // instantiate the anonymous struct/union type first.
@@ -342,7 +282,7 @@
                                  D->getStorageClass(),
                                  D->getStorageClassAsWritten());
   Var->setThreadSpecified(D->isThreadSpecified());
-  Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
+  Var->setInitStyle(D->getInitStyle());
   Var->setCXXForRangeDecl(D->isCXXForRangeDecl());
   Var->setConstexpr(D->isConstexpr());
 
@@ -403,25 +343,16 @@
       SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
 
     // Instantiate the initializer.
-    SourceLocation LParenLoc, RParenLoc;
-    ASTOwningVector<Expr*> InitArgs(SemaRef);
-    if (!SemaRef.InstantiateInitializer(D->getInit(), TemplateArgs, LParenLoc,
-                                        InitArgs, RParenLoc)) {
+    ExprResult Init = SemaRef.SubstInitializer(D->getInit(), TemplateArgs,
+                                        D->getInitStyle() == VarDecl::CallInit);
+    if (!Init.isInvalid()) {
       bool TypeMayContainAuto = true;
-      if (D->hasCXXDirectInitializer()) {
-        // Add the direct initializer to the declaration.
-        SemaRef.AddCXXDirectInitializerToDecl(Var,
-                                              LParenLoc,
-                                              move_arg(InitArgs),
-                                              RParenLoc,
-                                              TypeMayContainAuto);
-      } else if (InitArgs.size() == 0) {
+      if (Init.get()) {
+        bool DirectInit = D->isDirectInit();
+        SemaRef.AddInitializerToDecl(Var, Init.take(), DirectInit,
+                                     TypeMayContainAuto);
+      } else
         SemaRef.ActOnUninitializedDecl(Var, TypeMayContainAuto);
-      } else {
-        assert(InitArgs.size() == 1);
-        Expr *Init = InitArgs.take()[0];
-        SemaRef.AddInitializerToDecl(Var, Init, false, TypeMayContainAuto);
-      }
     } else {
       // FIXME: Not too happy about invalidating the declaration
       // because of a bogus initializer.
@@ -2743,18 +2674,6 @@
   }
 }
 
-static MultiInitializer CreateMultiInitializer(SmallVectorImpl<Expr*> &Args,
-                                               const CXXCtorInitializer *Init) {
-  // FIXME: This is a hack that will do slightly the wrong thing for an
-  // initializer of the form foo({...}).
-  // The right thing to do would be to modify InstantiateInitializer to create
-  // the MultiInitializer.
-  if (Args.size() == 1 && isa<InitListExpr>(Args[0]))
-    return MultiInitializer(Args[0]);
-  return MultiInitializer(Init->getLParenLoc(), Args.data(),
-                          Args.size(), Init->getRParenLoc());
-}
-
 void
 Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
                                  const CXXConstructorDecl *Tmpl,
@@ -2774,9 +2693,6 @@
     if (!Init->isWritten())
       continue;
 
-    SourceLocation LParenLoc, RParenLoc;
-    ASTOwningVector<Expr*> NewArgs(*this);
-
     SourceLocation EllipsisLoc;
 
     if (Init->isPackExpansion()) {
@@ -2804,8 +2720,9 @@
         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
 
         // Instantiate the initializer.
-        if (InstantiateInitializer(Init->getInit(), TemplateArgs,
-                                   LParenLoc, NewArgs, RParenLoc)) {
+        ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs,
+                                               /*CXXDirectInit=*/true);
+        if (TempInit.isInvalid()) {
           AnyErrors = true;
           break;
         }
@@ -2821,9 +2738,8 @@
         }
 
         // Build the initializer.
-        MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
         MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),
-                                                     BaseTInfo, MultiInit,
+                                                     BaseTInfo, TempInit.take(),
                                                      New->getParent(),
                                                      SourceLocation());
         if (NewInit.isInvalid()) {
@@ -2832,15 +2748,15 @@
         }
 
         NewInits.push_back(NewInit.get());
-        NewArgs.clear();
       }
 
       continue;
     }
 
     // Instantiate the initializer.
-    if (InstantiateInitializer(Init->getInit(), TemplateArgs,
-                               LParenLoc, NewArgs, RParenLoc)) {
+    ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs,
+                                           /*CXXDirectInit=*/true);
+    if (TempInit.isInvalid()) {
       AnyErrors = true;
       continue;
     }
@@ -2857,13 +2773,11 @@
         continue;
       }
 
-      MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
-      
       if (Init->isBaseInitializer())
-        NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, MultiInit,
+        NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.take(),
                                        New->getParent(), EllipsisLoc);
       else
-        NewInit = BuildDelegatingInitializer(TInfo, MultiInit, 
+        NewInit = BuildDelegatingInitializer(TInfo, TempInit.take(),
                                   cast<CXXRecordDecl>(CurContext->getParent()));
     } else if (Init->isMemberInitializer()) {
       FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(
@@ -2876,8 +2790,7 @@
         continue;
       }
 
-      MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
-      NewInit = BuildMemberInitializer(Member, MultiInit,
+      NewInit = BuildMemberInitializer(Member, TempInit.take(),
                                        Init->getSourceLocation());
     } else if (Init->isIndirectMemberInitializer()) {
       IndirectFieldDecl *IndirectMember =
@@ -2891,8 +2804,7 @@
         continue;
       }
 
-      MultiInitializer MultiInit(CreateMultiInitializer(NewArgs, Init));
-      NewInit = BuildMemberInitializer(IndirectMember, MultiInit,
+      NewInit = BuildMemberInitializer(IndirectMember, TempInit.take(),
                                        Init->getSourceLocation());
     }
 
@@ -2900,9 +2812,6 @@
       AnyErrors = true;
       New->setInvalidDecl();
     } else {
-      // FIXME: It would be nice if ASTOwningVector had a release function.
-      NewArgs.take();
-
       NewInits.push_back(NewInit.get());
     }
   }
@@ -2915,6 +2824,45 @@
                        AnyErrors);
 }
 
+ExprResult Sema::SubstInitializer(Expr *Init,
+                          const MultiLevelTemplateArgumentList &TemplateArgs,
+                          bool CXXDirectInit) {
+  // Initializers are instantiated like expressions, except that various outer
+  // layers are stripped.
+  if (!Init)
+    return Owned(Init);
+
+  if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
+    Init = ExprTemp->getSubExpr();
+
+  while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
+    Init = Binder->getSubExpr();
+
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
+    Init = ICE->getSubExprAsWritten();
+
+  // If this is a direct-initializer, we take apart CXXConstructExprs.
+  // Everything else is passed through.
+  CXXConstructExpr *Construct;
+  if (!CXXDirectInit || !(Construct = dyn_cast<CXXConstructExpr>(Init)) ||
+      isa<CXXTemporaryObjectExpr>(Construct))
+    return SubstExpr(Init, TemplateArgs);
+
+  ASTOwningVector<Expr*> NewArgs(*this);
+  if (SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true,
+                 TemplateArgs, NewArgs))
+    return ExprError();
+
+  // Treat an empty initializer like none.
+  if (NewArgs.empty())
+    return Owned((Expr*)0);
+
+  // Build a ParenListExpr to represent anything else.
+  // FIXME: Fake locations!
+  SourceLocation Loc = PP.getLocForEndOfToken(Init->getLocStart());
+  return ActOnParenListExpr(Loc, Loc, move_arg(NewArgs));
+}
+
 // TODO: this could be templated if the various decl types used the
 // same method name.
 static bool isInstantiationOf(ClassTemplateDecl *Pattern,

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sat Feb 11 17:51:47 2012
@@ -1646,10 +1646,9 @@
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
-                                        MultiExprArg SubExprs,
-                                        SourceLocation RParenLoc) {
-    return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc, 
-                                               move(SubExprs));
+                                  MultiExprArg SubExprs,
+                                  SourceLocation RParenLoc) {
+    return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
   }
 
   /// \brief Build a new address-of-label expression.

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sat Feb 11 17:51:47 2012
@@ -877,7 +877,7 @@
   VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
   VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++];
   VD->VarDeclBits.ThreadSpecified = Record[Idx++];
-  VD->VarDeclBits.HasCXXDirectInit = Record[Idx++];
+  VD->VarDeclBits.InitStyle = Record[Idx++];
   VD->VarDeclBits.ExceptionVar = Record[Idx++];
   VD->VarDeclBits.NRVOVariable = Record[Idx++];
   VD->VarDeclBits.CXXForRangeDecl = Record[Idx++];

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Sat Feb 11 17:51:47 2012
@@ -656,7 +656,7 @@
   Record.push_back(D->getStorageClass()); // FIXME: stable encoding
   Record.push_back(D->getStorageClassAsWritten());
   Record.push_back(D->isThreadSpecified());
-  Record.push_back(D->hasCXXDirectInitializer());
+  Record.push_back(D->getInitStyle());
   Record.push_back(D->isExceptionVariable());
   Record.push_back(D->isNRVOVariable());
   Record.push_back(D->isCXXForRangeDecl());
@@ -688,7 +688,7 @@
       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
       !D->hasExtInfo() &&
       D->getFirstDeclaration() == D->getMostRecentDecl() &&
-      !D->hasCXXDirectInitializer() &&
+      D->getInitStyle() == VarDecl::CInit &&
       D->getInit() == 0 &&
       !isa<ParmVarDecl>(D) &&
       !SpecInfo)
@@ -728,7 +728,7 @@
       D->getAccess() == AS_none &&
       !D->isModulePrivate() &&
       D->getStorageClass() == 0 &&
-      !D->hasCXXDirectInitializer() && // Can params have this ever?
+      D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
       D->getFunctionScopeDepth() == 0 &&
       D->getObjCDeclQualifier() == 0 &&
       !D->isKNRPromoted() &&

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp?rev=150318&r1=150317&r2=150318&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp Sat Feb 11 17:51:47 2012
@@ -185,7 +185,7 @@
 
   void test_initializers() {
     T copy_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
-    T direct_init(0, static_cast<Types>(0)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+    T direct_init(0, static_cast<Types>(0)); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
     T list_init = { static_cast<Types>(0) }; // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
   }
 

Removed: cfe/trunk/test/Sema/paren-list-expr-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/paren-list-expr-type.cpp?rev=150317&view=auto
==============================================================================
--- cfe/trunk/test/Sema/paren-list-expr-type.cpp (original)
+++ cfe/trunk/test/Sema/paren-list-expr-type.cpp (removed)
@@ -1,17 +0,0 @@
-// RUN: %clang -cc1 -ast-dump %s | not grep NULL
-// Makes sure that we don't introduce null types when handling
-// ParenListExpr.
-
-template<typename T> class X { void f() { X x(*this); } };
-
-template<typename T> class Y { Y() : t(1) {} T t; };
-
-template<typename T> class Z { Z() : b(true) {} const bool b; };
-
-template<typename T> class A : public Z<T> { A() : Z<T>() {} };
-
-class C {};
-template<typename T> class D : public C { D(): C() {} };
-
-void f() { (int)(1, 2); }
-

Added: cfe/trunk/test/SemaTemplate/nested-incomplete-class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/nested-incomplete-class.cpp?rev=150318&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/nested-incomplete-class.cpp (added)
+++ cfe/trunk/test/SemaTemplate/nested-incomplete-class.cpp Sat Feb 11 17:51:47 2012
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template <typename T>
+struct foo {
+  struct bar;
+
+  bar fn() {
+    // Should not get errors about bar being incomplete here.
+    bar b = bar(1, 2);
+    return b;
+  }
+};
+
+template <typename T>
+struct foo<T>::bar {
+  bar(int, int);
+};
+
+void fn() {
+  foo<int>().fn();
+}





More information about the cfe-commits mailing list