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/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 73f47d9..3d690d1 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -673,42 +673,25 @@
 
 CXXBaseOrMemberInitializer::
 CXXBaseOrMemberInitializer(ASTContext &Context,
-                           TypeSourceInfo *TInfo, CXXConstructorDecl *C,
-                           SourceLocation L, 
-                           Expr **Args, unsigned NumArgs,
-                           SourceLocation R)
-  : BaseOrMember(TInfo), Args(0), NumArgs(0), CtorOrAnonUnion(C), 
+                           TypeSourceInfo *TInfo, 
+                           SourceLocation L, Expr *Init, SourceLocation R)
+  : BaseOrMember(TInfo), Init(Init), AnonUnionMember(0),
     LParenLoc(L), RParenLoc(R) 
 {
-  if (NumArgs > 0) {
-    this->NumArgs = NumArgs;
-    this->Args = new (Context) Stmt*[NumArgs];
-    for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
-      this->Args[Idx] = Args[Idx];
-  }
 }
 
 CXXBaseOrMemberInitializer::
 CXXBaseOrMemberInitializer(ASTContext &Context,
                            FieldDecl *Member, SourceLocation MemberLoc,
-                           CXXConstructorDecl *C, SourceLocation L,
-                           Expr **Args, unsigned NumArgs,
-                           SourceLocation R)
-  : BaseOrMember(Member), MemberLocation(MemberLoc), Args(0), NumArgs(0), 
-    CtorOrAnonUnion(C), LParenLoc(L), RParenLoc(R) 
+                           SourceLocation L, Expr *Init, SourceLocation R)
+  : BaseOrMember(Member), MemberLocation(MemberLoc), Init(Init), 
+    AnonUnionMember(0), LParenLoc(L), RParenLoc(R) 
 {
-  if (NumArgs > 0) {
-    this->NumArgs = NumArgs;
-    this->Args = new (Context) Stmt*[NumArgs];
-    for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
-      this->Args[Idx] = Args[Idx];
-  }
 }
 
 void CXXBaseOrMemberInitializer::Destroy(ASTContext &Context) {
-  for (unsigned I = 0; I != NumArgs; ++I)
-    Args[I]->Destroy(Context);
-  Context.Deallocate(Args);
+  if (Init)
+    Init->Destroy(Context);
   this->~CXXBaseOrMemberInitializer();
 }
 
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 32ac53d..a625865 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -17,6 +17,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -403,32 +404,51 @@
           CXXBaseOrMemberInitializer * BMInitializer = (*B);
           if (B != CDecl->init_begin())
             Out << ", ";
-          bool hasArguments = (BMInitializer->arg_begin() !=
-                               BMInitializer->arg_end());
           if (BMInitializer->isMemberInitializer()) {
             FieldDecl *FD = BMInitializer->getMember();
             Out <<  FD->getNameAsString();
+          } else {
+            Out << QualType(BMInitializer->getBaseClass(), 0).getAsString();
           }
-          else // FIXME. skip dependent types for now.
-            if (const RecordType *RT =
-                BMInitializer->getBaseClass()->getAs<RecordType>()) {
-              const CXXRecordDecl *BaseDecl =
-                cast<CXXRecordDecl>(RT->getDecl());
-              Out << BaseDecl->getNameAsString();
-          }
-          if (hasArguments) {
-            Out << "(";
-            for (CXXBaseOrMemberInitializer::const_arg_iterator BE =
-                 BMInitializer->const_arg_begin(),
-                 EE =  BMInitializer->const_arg_end(); BE != EE; ++BE) {
-              if (BE != BMInitializer->const_arg_begin())
-                Out<< ", ";
-              const Expr *Exp = (*BE);
-              Exp->printPretty(Out, Context, 0, Policy, Indentation);
+          
+          Out << "(";
+          if (!BMInitializer->getInit()) {
+            // Nothing to print
+          } else {
+            Expr *Init = BMInitializer->getInit();
+            if (CXXExprWithTemporaries *Tmp
+                  = dyn_cast<CXXExprWithTemporaries>(Init))
+              Init = Tmp->getSubExpr();
+            
+            Init = Init->IgnoreParens();
+            
+            Expr *SimpleInit = 0;
+            Expr **Args = 0;
+            unsigned NumArgs = 0;
+            if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+              Args = ParenList->getExprs();
+              NumArgs = ParenList->getNumExprs();
+            } else if (CXXConstructExpr *Construct
+                                          = dyn_cast<CXXConstructExpr>(Init)) {
+              Args = Construct->getArgs();
+              NumArgs = Construct->getNumArgs();
+            } else
+              SimpleInit = Init;
+            
+            if (SimpleInit)
+              SimpleInit->printPretty(Out, Context, 0, Policy, Indentation);
+            else {
+              for (unsigned I = 0; I != NumArgs; ++I) {
+                if (isa<CXXDefaultArgExpr>(Args[I]))
+                  break;
+                
+                if (I)
+                  Out << ", ";
+                Args[I]->printPretty(Out, Context, 0, Policy, Indentation);
+              }
             }
-            Out << ")";
-          } else
-            Out << "()";
+          }
+          Out << ")";
         }
       }
     }
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 3931bbd..70d0891 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -424,22 +424,26 @@
                                            SourceLocation Loc,
                                            CXXConstructorDecl *D, bool Elidable,
                                            Expr **Args, unsigned NumArgs,
-                                           bool ZeroInitialization) {
+                                           bool ZeroInitialization,
+                                           bool BaseInitialization) {
   return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, 
-                                  Elidable, Args, NumArgs, ZeroInitialization);
+                                  Elidable, Args, NumArgs, ZeroInitialization,
+                                  BaseInitialization);
 }
 
 CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
                                    SourceLocation Loc,
                                    CXXConstructorDecl *D, bool elidable,
                                    Expr **args, unsigned numargs,
-                                   bool ZeroInitialization)
+                                   bool ZeroInitialization,
+                                   bool BaseInitialization)
 : Expr(SC, T,
        T->isDependentType(),
        (T->isDependentType() ||
         CallExpr::hasAnyValueDependentArguments(args, numargs))),
   Constructor(D), Loc(Loc), Elidable(elidable), 
-  ZeroInitialization(ZeroInitialization), Args(0), NumArgs(numargs) 
+  ZeroInitialization(ZeroInitialization), 
+  BaseInitialization(BaseInitialization), Args(0), NumArgs(numargs) 
 {
   if (NumArgs) {
     Args = new (C) Stmt*[NumArgs];