Revert "Revert "Make CXXNewExpr contain only a single initialier, and not hold the used constructor itself.""

This reintroduces commit r150682 with a fix for the Bullet benchmark crash.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150685 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index f9f7ba5..4b19031 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2041,10 +2041,7 @@
     if (isTypeDependent())
       CT = CT_Dependent;
     else
-      CT = MergeCanThrow(
-        CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew()),
-        CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getConstructor(),
-                       /*NullThrows*/false));
+      CT = CanCalleeThrow(C, this, cast<CXXNewExpr>(this)->getOperatorNew());
     if (CT == CT_Can)
       return CT;
     return MergeCanThrow(CT, CanSubExprsThrow(C, this));
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index e09d880..718010b 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -45,30 +45,26 @@
 
 // CXXNewExpr
 CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
-                       Expr **placementArgs, unsigned numPlaceArgs,
-                       SourceRange TypeIdParens, Expr *arraySize,
-                       CXXConstructorDecl *constructor, bool initializer,
-                       Expr **constructorArgs, unsigned numConsArgs,
-                       bool HadMultipleCandidates,
                        FunctionDecl *operatorDelete,
-                       bool usualArrayDeleteWantsSize, QualType ty,
-                       TypeSourceInfo *AllocatedTypeInfo,
-                       SourceLocation startLoc, SourceLocation endLoc,
-                       SourceLocation constructorLParen,
-                       SourceLocation constructorRParen)
+                       bool usualArrayDeleteWantsSize,
+                       Expr **placementArgs, unsigned numPlaceArgs,
+                       SourceRange typeIdParens, Expr *arraySize,
+                       InitializationStyle initializationStyle,
+                       Expr *initializer, QualType ty,
+                       TypeSourceInfo *allocatedTypeInfo,
+                       SourceLocation startLoc, SourceRange directInitRange)
   : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
          ty->isDependentType(), ty->isDependentType(),
          ty->isInstantiationDependentType(),
          ty->containsUnexpandedParameterPack()),
-    GlobalNew(globalNew), Initializer(initializer),
-    UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
-    HadMultipleCandidates(HadMultipleCandidates),
-    SubExprs(0), OperatorNew(operatorNew),
-    OperatorDelete(operatorDelete), Constructor(constructor),
-    AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
-    StartLoc(startLoc), EndLoc(endLoc), ConstructorLParen(constructorLParen),
-    ConstructorRParen(constructorRParen) {
-  AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs);
+    GlobalNew(globalNew), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
+    SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
+    AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
+    StartLoc(startLoc), DirectInitRange(directInitRange) {
+  assert((initializer != 0 || initializationStyle == NoInit) &&
+         "Only NoInit can have no initializer.");
+  StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
+  AllocateArgsArray(C, arraySize != 0, numPlaceArgs, initializer != 0);
   unsigned i = 0;
   if (Array) {
     if (arraySize->isInstantiationDependent())
@@ -80,6 +76,16 @@
     SubExprs[i++] = arraySize;
   }
 
+  if (initializer) {
+    if (initializer->isInstantiationDependent())
+      ExprBits.InstantiationDependent = true;
+
+    if (initializer->containsUnexpandedParameterPack())
+      ExprBits.ContainsUnexpandedParameterPack = true;
+
+    SubExprs[i++] = initializer;
+  }
+
   for (unsigned j = 0; j < NumPlacementArgs; ++j) {
     if (placementArgs[j]->isInstantiationDependent())
       ExprBits.InstantiationDependent = true;
@@ -88,25 +94,15 @@
 
     SubExprs[i++] = placementArgs[j];
   }
-
-  for (unsigned j = 0; j < NumConstructorArgs; ++j) {
-    if (constructorArgs[j]->isInstantiationDependent())
-      ExprBits.InstantiationDependent = true;
-    if (constructorArgs[j]->containsUnexpandedParameterPack())
-      ExprBits.ContainsUnexpandedParameterPack = true;
-
-    SubExprs[i++] = constructorArgs[j];
-  }
 }
 
 void CXXNewExpr::AllocateArgsArray(ASTContext &C, bool isArray,
-                                   unsigned numPlaceArgs, unsigned numConsArgs){
+                                   unsigned numPlaceArgs, bool hasInitializer){
   assert(SubExprs == 0 && "SubExprs already allocated");
   Array = isArray;
   NumPlacementArgs = numPlaceArgs;
-  NumConstructorArgs = numConsArgs; 
-  
-  unsigned TotalSize = Array + NumPlacementArgs + NumConstructorArgs;
+
+  unsigned TotalSize = Array + hasInitializer + NumPlacementArgs;
   SubExprs = new (C) Stmt*[TotalSize];
 }
 
@@ -115,6 +111,17 @@
     castAs<FunctionProtoType>()->isNothrow(Ctx);
 }
 
+SourceLocation CXXNewExpr::getEndLoc() const {
+  switch (getInitializationStyle()) {
+  case NoInit:
+    return AllocatedTypeInfo->getTypeLoc().getEndLoc();
+  case CallInit:
+    return DirectInitRange.getEnd();
+  case ListInit:
+    return getInitializer()->getSourceRange().getEnd();
+  }
+}
+
 // CXXDeleteExpr
 QualType CXXDeleteExpr::getDestroyedType() const {
   const Expr *Arg = getArgument();
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 7df8f6f..4843716 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2351,10 +2351,20 @@
     Out << '_';
     mangleType(New->getAllocatedType());
     if (New->hasInitializer()) {
+      // FIXME: Does this mean "parenthesized initializer"?
       Out << "pi";
-      for (CXXNewExpr::const_arg_iterator I = New->constructor_arg_begin(),
-             E = New->constructor_arg_end(); I != E; ++I)
-        mangleExpression(*I);
+      const Expr *Init = New->getInitializer();
+      if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
+        // Directly inline the initializers.
+        for (CXXConstructExpr::const_arg_iterator I = CCE->arg_begin(),
+                                                  E = CCE->arg_end();
+             I != E; ++I)
+          mangleExpression(*I);
+      } else if (const ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
+        for (unsigned i = 0, e = PLE->getNumExprs(); i != e; ++i)
+          mangleExpression(PLE->getExpr(i));
+      } else
+        mangleExpression(Init);
     }
     Out << 'E';
     break;
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 746049b..c83bfad 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1390,17 +1390,13 @@
   if (E->isParenTypeId())
     OS << ")";
 
-  if (E->hasInitializer()) {
-    OS << "(";
-    unsigned NumCons = E->getNumConstructorArgs();
-    if (NumCons > 0) {
-      PrintExpr(E->getConstructorArg(0));
-      for (unsigned i = 1; i < NumCons; ++i) {
-        OS << ", ";
-        PrintExpr(E->getConstructorArg(i));
-      }
-    }
-    OS << ")";
+  CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
+  if (InitStyle) {
+    if (InitStyle == CXXNewExpr::CallInit)
+      OS << "(";
+    PrintExpr(E->getInitializer());
+    if (InitStyle == CXXNewExpr::CallInit)
+      OS << ")";
   }
 }
 
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 1d58fd7..fdd0c85 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -825,13 +825,11 @@
   VisitType(S->getAllocatedType());
   VisitDecl(S->getOperatorNew());
   VisitDecl(S->getOperatorDelete());
-  VisitDecl(S->getConstructor());
   ID.AddBoolean(S->isArray());
   ID.AddInteger(S->getNumPlacementArgs());
   ID.AddBoolean(S->isGlobalNew());
   ID.AddBoolean(S->isParenTypeId());
-  ID.AddBoolean(S->hasInitializer());
-  ID.AddInteger(S->getNumConstructorArgs());
+  ID.AddInteger(S->getInitializationStyle());
 }
 
 void