Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:

  - CXXBaseOrMemberInitializer now contains only a single initializer
    rather than a set of initialiation arguments + a constructor. The
    single initializer covers all aspects of initialization, including
    constructor calls as necessary but also cleanup of temporaries
    created by the initializer (which we never handled
    before!).

  - Rework + simplify code generation for CXXBaseOrMemberInitializers,
    since we can now just emit the initializer as an initializer.

  - Switched base and member initialization over to the new
    initialization code (InitializationSequence), so that it

  - Improved diagnostics for the new initialization code when
    initializing bases and members, to match the diagnostics produced
    by the previous (special-purpose) code.

  - Simplify the representation of type-checked constructor initializers in
    templates; instead of keeping the fully-type-checked AST, which is
    rather hard to undo at template instantiation time, throw away the
    type-checked AST and store the raw expressions in the AST. This
    simplifies instantiation, but loses a little but of information in
    the AST.

  - When type-checking implicit base or member initializers within a
    dependent context, don't add the generated initializers into the
    AST, because they'll look like they were explicit.

  - Record in CXXConstructExpr when the constructor call is to
  initialize a base class, so that CodeGen does not have to infer it
  from context. This ensures that we call the right kind of
  constructor.

There are also a few "opportunity" fixes here that were needed to not
regress, for example:

  - Diagnose default-initialization of a const-qualified class that
    does not have a user-declared default constructor. We had this
    diagnostic specifically for bases and members, but missed it for
    variables. That's fixed now.

  - When defining the implicit constructors, destructor, and
    copy-assignment operator, set the CurContext to that constructor
    when we're defining the body.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94952 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a2f1f63..d526962 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1830,7 +1830,8 @@
                            const MultiLevelTemplateArgumentList &TemplateArgs) {
 
   llvm::SmallVector<MemInitTy*, 4> NewInits;
-
+  bool AnyErrors = false;
+  
   // Instantiate all the initializers.
   for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(),
                                             InitsEnd = Tmpl->init_end();
@@ -1838,26 +1839,38 @@
     CXXBaseOrMemberInitializer *Init = *Inits;
 
     ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
+    llvm::SmallVector<SourceLocation, 4> CommaLocs;
 
     // Instantiate all the arguments.
-    for (ExprIterator Args = Init->arg_begin(), ArgsEnd = Init->arg_end();
-         Args != ArgsEnd; ++Args) {
-      OwningExprResult NewArg = SubstExpr(*Args, TemplateArgs);
-
-      if (NewArg.isInvalid())
-        New->setInvalidDecl();
-      else
-        NewArgs.push_back(NewArg.takeAs<Expr>());
+    Expr *InitE = Init->getInit();
+    if (!InitE) {
+      // Nothing to instantiate;
+    } else if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(InitE)) {
+      if (InstantiateInitializationArguments(*this, ParenList->getExprs(),
+                                             ParenList->getNumExprs(),
+                                             TemplateArgs, CommaLocs, 
+                                             NewArgs)) {
+        AnyErrors = true;
+        continue;
+      }
+    } else {
+      OwningExprResult InitArg = SubstExpr(InitE, TemplateArgs);
+      if (InitArg.isInvalid()) {
+        AnyErrors = true;
+        continue;
+      }
+      
+      NewArgs.push_back(InitArg.release());
     }
-
+    
     MemInitResult NewInit;
-
     if (Init->isBaseInitializer()) {
       TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(), 
                                             TemplateArgs, 
                                             Init->getSourceLocation(), 
                                             New->getDeclName());
       if (!BaseTInfo) {
+        AnyErrors = true;
         New->setInvalidDecl();
         continue;
       }
@@ -1885,9 +1898,10 @@
                                        Init->getRParenLoc());
     }
 
-    if (NewInit.isInvalid())
+    if (NewInit.isInvalid()) {
+      AnyErrors = true;
       New->setInvalidDecl();
-    else {
+    } else {
       // FIXME: It would be nice if ASTOwningVector had a release function.
       NewArgs.take();
 
@@ -1899,7 +1913,8 @@
   ActOnMemInitializers(DeclPtrTy::make(New),
                        /*FIXME: ColonLoc */
                        SourceLocation(),
-                       NewInits.data(), NewInits.size());
+                       NewInits.data(), NewInits.size(),
+                       AnyErrors);
 }
 
 // TODO: this could be templated if the various decl types used the