Store inheritance paths after CastExprs instead of inside them.
This takes some trickery since CastExpr has subclasses (and indeed,
is abstract).

Also, smoosh the CastKind into the bitfield from Expr.

Drops two words of storage from Expr in the common case of expressions
which don't need inheritance paths.  Avoids a separate allocation and
another word of overhead in cases needing inheritance paths.  Also has
the advantage of not leaking memory, since destructors for AST nodes are
never run.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110507 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 2445381..aeb4db9 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -159,7 +159,7 @@
 void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
                              CastExpr::CastKind Kind, 
                              ImplicitCastExpr::ResultCategory Category,
-                             CXXBaseSpecifierArray BasePath) {
+                             const CXXCastPath *BasePath) {
   QualType ExprTy = Context.getCanonicalType(Expr->getType());
   QualType TypeTy = Context.getCanonicalType(Ty);
 
@@ -178,7 +178,7 @@
   // If this is a derived-to-base cast to a through a virtual base, we
   // need a vtable.
   if (Kind == CastExpr::CK_DerivedToBase && 
-      BasePathInvolvesVirtualBase(BasePath)) {
+      BasePathInvolvesVirtualBase(*BasePath)) {
     QualType T = Expr->getType();
     if (const PointerType *Pointer = T->getAs<PointerType>())
       T = Pointer->getPointeeType();
@@ -188,14 +188,14 @@
   }
 
   if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
-    if (ImpCast->getCastKind() == Kind && BasePath.empty()) {
+    if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
       ImpCast->setType(Ty);
       ImpCast->setCategory(Category);
       return;
     }
   }
 
-  Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, Category);
+  Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, Category);
 }
 
 ImplicitCastExpr::ResultCategory Sema::CastCategory(Expr *E) {
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index eb84417..3570a77 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1179,14 +1179,14 @@
   
   bool CheckPointerConversion(Expr *From, QualType ToType,
                               CastExpr::CastKind &Kind,
-                              CXXBaseSpecifierArray& BasePath,
+                              CXXCastPath& BasePath,
                               bool IgnoreBaseAccess);
   bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
                                  bool InOverloadResolution,
                                  QualType &ConvertedType);
   bool CheckMemberPointerConversion(Expr *From, QualType ToType,
                                     CastExpr::CastKind &Kind,
-                                    CXXBaseSpecifierArray &BasePath,
+                                    CXXCastPath &BasePath,
                                     bool IgnoreBaseAccess);
   bool IsQualificationConversion(QualType FromType, QualType ToType);
   OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
@@ -2831,21 +2831,20 @@
   bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths);
 
   // FIXME: I don't like this name.
-  void BuildBasePathArray(const CXXBasePaths &Paths,
-                          CXXBaseSpecifierArray &BasePath);
+  void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath);
 
-  bool BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath);
+  bool BasePathInvolvesVirtualBase(const CXXCastPath &BasePath);
 
   bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                     SourceLocation Loc, SourceRange Range,
-                                    CXXBaseSpecifierArray *BasePath = 0,
+                                    CXXCastPath *BasePath = 0,
                                     bool IgnoreAccess = false);
   bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                     unsigned InaccessibleBaseID,
                                     unsigned AmbigiousBaseConvID,
                                     SourceLocation Loc, SourceRange Range,
                                     DeclarationName Name,
-                                    CXXBaseSpecifierArray *BasePath);
+                                    CXXCastPath *BasePath);
 
   std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
 
@@ -4257,8 +4256,7 @@
   void ImpCastExprToType(Expr *&Expr, QualType Type, CastExpr::CastKind Kind,
                          ImplicitCastExpr::ResultCategory Category =
                           ImplicitCastExpr::RValue,
-                         CXXBaseSpecifierArray BasePath =
-                          CXXBaseSpecifierArray());
+                         const CXXCastPath *BasePath = 0);
 
   // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
   // functions and arrays to their respective pointers (C99 6.3.2.1).
@@ -4524,7 +4522,7 @@
   /// CheckCastTypes - Check type constraints for casting between types under
   /// C semantics, or forward to CXXCheckCStyleCast in C++.
   bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
-                      CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath,
+                      CastExpr::CastKind &Kind, CXXCastPath &BasePath,
                       bool FunctionalStyle = false);
 
   // CheckVectorCast - check type constraints for vectors.
@@ -4545,8 +4543,7 @@
   /// CXXCheckCStyleCast - Check constraints of a C-style or function-style
   /// cast under C++ semantics.
   bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
-                          CastExpr::CastKind &Kind,
-                          CXXBaseSpecifierArray &BasePath,
+                          CastExpr::CastKind &Kind, CXXCastPath &BasePath,
                           bool FunctionalStyle);
 
   /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index 519d569..5335266 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -47,12 +47,12 @@
 static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                             const SourceRange &OpRange,
                             CastExpr::CastKind &Kind,
-                            CXXBaseSpecifierArray &BasePath);
+                            CXXCastPath &BasePath);
 static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                              const SourceRange &OpRange,
                              const SourceRange &DestRange,
                              CastExpr::CastKind &Kind,
-                             CXXBaseSpecifierArray &BasePath);
+                             CXXCastPath &BasePath);
 
 static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType);
 
@@ -74,27 +74,27 @@
                                                const SourceRange &OpRange,
                                                unsigned &msg,
                                                CastExpr::CastKind &Kind,
-                                               CXXBaseSpecifierArray &BasePath);
+                                               CXXCastPath &BasePath);
 static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType,
                                               QualType DestType, bool CStyle,
                                               const SourceRange &OpRange,
                                               unsigned &msg,
                                               CastExpr::CastKind &Kind,
-                                              CXXBaseSpecifierArray &BasePath);
+                                              CXXCastPath &BasePath);
 static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
                                        CanQualType DestType, bool CStyle,
                                        const SourceRange &OpRange,
                                        QualType OrigSrcType,
                                        QualType OrigDestType, unsigned &msg,
                                        CastExpr::CastKind &Kind,
-                                       CXXBaseSpecifierArray &BasePath);
+                                       CXXCastPath &BasePath);
 static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
                                                QualType SrcType,
                                                QualType DestType,bool CStyle,
                                                const SourceRange &OpRange,
                                                unsigned &msg,
                                                CastExpr::CastKind &Kind,
-                                               CXXBaseSpecifierArray &BasePath);
+                                               CXXCastPath &BasePath);
 
 static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr,
                                            QualType DestType, bool CStyle,
@@ -106,7 +106,7 @@
                                    const SourceRange &OpRange,
                                    unsigned &msg,
                                    CastExpr::CastKind &Kind,
-                                   CXXBaseSpecifierArray &BasePath);
+                                   CXXCastPath &BasePath);
 static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
                                   bool CStyle, unsigned &msg);
 static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
@@ -153,39 +153,39 @@
   case tok::kw_const_cast:
     if (!TypeDependent)
       CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
-    return Owned(new (Context) CXXConstCastExpr(
+    return Owned(CXXConstCastExpr::Create(Context,
                                         DestType.getNonLValueExprType(Context),
-                                                Ex, DestTInfo, OpLoc));
+                                          Ex, DestTInfo, OpLoc));
 
   case tok::kw_dynamic_cast: {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (!TypeDependent)
       CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath);
-    return Owned(new (Context)CXXDynamicCastExpr(
+    return Owned(CXXDynamicCastExpr::Create(Context,
                                           DestType.getNonLValueExprType(Context),
-                                                 Kind, Ex, BasePath, DestTInfo,
-                                                 OpLoc));
+                                            Kind, Ex, &BasePath, DestTInfo,
+                                            OpLoc));
   }
   case tok::kw_reinterpret_cast: {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
     if (!TypeDependent)
       CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
-    return Owned(new (Context) CXXReinterpretCastExpr(
+    return Owned(CXXReinterpretCastExpr::Create(Context,
                                   DestType.getNonLValueExprType(Context),
-                                  Kind, Ex, CXXBaseSpecifierArray(), 
+                                  Kind, Ex, 0,
                                   DestTInfo, OpLoc));
   }
   case tok::kw_static_cast: {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (!TypeDependent)
       CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath);
     
-    return Owned(new (Context) CXXStaticCastExpr(
+    return Owned(CXXStaticCastExpr::Create(Context,
                                          DestType.getNonLValueExprType(Context),
-                                                 Kind, Ex, BasePath,
-                                                 DestTInfo, OpLoc));
+                                           Kind, Ex, &BasePath,
+                                           DestTInfo, OpLoc));
   }
   }
 
@@ -308,7 +308,7 @@
 CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                  const SourceRange &OpRange,
                  const SourceRange &DestRange, CastExpr::CastKind &Kind,
-                 CXXBaseSpecifierArray &BasePath) {
+                 CXXCastPath &BasePath) {
   QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
   DestType = Self.Context.getCanonicalType(DestType);
 
@@ -477,7 +477,7 @@
 void
 CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                 const SourceRange &OpRange, CastExpr::CastKind &Kind,
-                CXXBaseSpecifierArray &BasePath) {
+                CXXCastPath &BasePath) {
   // This test is outside everything else because it's the only case where
   // a non-lvalue-reference target type does not lead to decay.
   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
@@ -503,7 +503,7 @@
                                    QualType DestType, bool CStyle,
                                    const SourceRange &OpRange, unsigned &msg,
                                    CastExpr::CastKind &Kind,
-                                   CXXBaseSpecifierArray &BasePath) {
+                                   CXXCastPath &BasePath) {
   // The order the tests is not entirely arbitrary. There is one conversion
   // that can be handled in two different ways. Given:
   // struct A {};
@@ -664,7 +664,7 @@
 TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
                            bool CStyle, const SourceRange &OpRange,
                            unsigned &msg, CastExpr::CastKind &Kind,
-                           CXXBaseSpecifierArray &BasePath) {
+                           CXXCastPath &BasePath) {
   // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be
   //   cast to type "reference to cv2 D", where D is a class derived from B,
   //   if a valid standard conversion from "pointer to D" to "pointer to B"
@@ -699,7 +699,7 @@
 TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType,
                          bool CStyle, const SourceRange &OpRange,
                          unsigned &msg, CastExpr::CastKind &Kind,
-                         CXXBaseSpecifierArray &BasePath) {
+                         CXXCastPath &BasePath) {
   // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class
   //   type, can be converted to an rvalue of type "pointer to cv2 D", where D
   //   is a class derived from B, if a valid standard conversion from "pointer
@@ -733,7 +733,7 @@
 TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
                   bool CStyle, const SourceRange &OpRange, QualType OrigSrcType,
                   QualType OrigDestType, unsigned &msg, 
-                  CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath) {
+                  CastExpr::CastKind &Kind, CXXCastPath &BasePath) {
   // We can only work with complete types. But don't complain if it doesn't work
   if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, Self.PDiag(0)) ||
       Self.RequireCompleteType(OpRange.getBegin(), DestType, Self.PDiag(0)))
@@ -841,7 +841,7 @@
                              QualType DestType, bool CStyle, 
                              const SourceRange &OpRange,
                              unsigned &msg, CastExpr::CastKind &Kind,
-                             CXXBaseSpecifierArray &BasePath) {
+                             CXXCastPath &BasePath) {
   const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
   if (!DestMemPtr)
     return TC_NotApplicable;
@@ -1254,7 +1254,7 @@
 bool 
 Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
                          CastExpr::CastKind &Kind, 
-                         CXXBaseSpecifierArray &BasePath,
+                         CXXCastPath &BasePath,
                          bool FunctionalStyle) {
   // This test is outside everything else because it's the only case where
   // a non-lvalue-reference target type does not lead to decay.
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 0fcc0a7..e822366 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -524,9 +524,9 @@
     cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID,
                                            TUScope, false, DRE->getLocStart()));
 
-  // The first argument is by definition correct, we use it's type as the type
-  // of the entire operation. Walk the remaining arguments promoting them to
-  // the deduced value type.
+  // The first argument --- the pointer --- has a fixed type; we
+  // deduce the types of the rest of the arguments accordingly.  Walk
+  // the remaining arguments, converting them to the deduced value type.
   for (unsigned i = 0; i != NumFixed; ++i) {
     Expr *Arg = TheCall->getArg(i+1);
 
@@ -541,7 +541,7 @@
     // GCC does an implicit conversion to the pointer or integer ValType.  This
     // can fail in some cases (1i -> int**), check for this error case now.
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath))
       return ExprError();
 
@@ -551,7 +551,7 @@
     // pass in 42.  The 42 gets converted to char.  This is even more strange
     // for things like 45.123 -> char, etc.
     // FIXME: Do this check.
-    ImpCastExprToType(Arg, ValType, Kind);
+    ImpCastExprToType(Arg, ValType, Kind, ImplicitCastExpr::RValue, &BasePath);
     TheCall->setArg(i+1, Arg);
   }
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5cef150..200b8fd 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -6803,11 +6803,11 @@
 
     // Adjust the Expr initializer and type.
     if (ECD->getInitExpr())
-      ECD->setInitExpr(new (Context) ImplicitCastExpr(NewTy,
-                                                      CastExpr::CK_IntegralCast,
-                                                      ECD->getInitExpr(),
-                                                      CXXBaseSpecifierArray(),
-                                                     ImplicitCastExpr::RValue));
+      ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy,
+                                                CastExpr::CK_IntegralCast,
+                                                ECD->getInitExpr(),
+                                                /*base paths*/ 0,
+                                                ImplicitCastExpr::RValue));
     if (getLangOptions().CPlusPlus)
       // C++ [dcl.enum]p4: Following the closing brace of an
       // enum-specifier, each enumerator has the type of its
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index c5705df..08fa97b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -720,7 +720,7 @@
 }
 
 void Sema::BuildBasePathArray(const CXXBasePaths &Paths, 
-                              CXXBaseSpecifierArray &BasePathArray) {
+                              CXXCastPath &BasePathArray) {
   assert(BasePathArray.empty() && "Base path array must be empty!");
   assert(Paths.isRecordingPaths() && "Must record paths!");
   
@@ -739,14 +739,14 @@
 
   // Now add all bases.
   for (unsigned I = Start, E = Path.size(); I != E; ++I)
-    BasePathArray.push_back(Path[I].Base);
+    BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base));
 }
 
 /// \brief Determine whether the given base path includes a virtual
 /// base class.
-bool Sema::BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath) {
-  for (CXXBaseSpecifierArray::iterator B = BasePath.begin(), 
-                                    BEnd = BasePath.end();
+bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) {
+  for (CXXCastPath::const_iterator B = BasePath.begin(), 
+                                BEnd = BasePath.end();
        B != BEnd; ++B)
     if ((*B)->isVirtual())
       return true;
@@ -768,7 +768,7 @@
                                    unsigned AmbigiousBaseConvID,
                                    SourceLocation Loc, SourceRange Range,
                                    DeclarationName Name,
-                                   CXXBaseSpecifierArray *BasePath) {
+                                   CXXCastPath *BasePath) {
   // First, determine whether the path from Derived to Base is
   // ambiguous. This is slightly more expensive than checking whether
   // the Derived to Base conversion exists, because here we need to
@@ -826,7 +826,7 @@
 bool
 Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                    SourceLocation Loc, SourceRange Range,
-                                   CXXBaseSpecifierArray *BasePath,
+                                   CXXCastPath *BasePath,
                                    bool IgnoreAccess) {
   return CheckDerivedToBaseConversion(Derived, Base,
                                       IgnoreAccess ? 0
@@ -1534,10 +1534,12 @@
     QualType ArgTy = 
       SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(), 
                                        ParamType.getQualifiers());
+
+    CXXCastPath BasePath;
+    BasePath.push_back(BaseSpec);
     SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
                               CastExpr::CK_UncheckedDerivedToBase,
-                              ImplicitCastExpr::LValue,
-                              CXXBaseSpecifierArray(BaseSpec));
+                              ImplicitCastExpr::LValue, &BasePath);
 
     InitializationKind InitKind
       = InitializationKind::CreateDirect(Constructor->getLocation(),
@@ -4856,12 +4858,15 @@
       continue;
     }
 
+    CXXCastPath BasePath;
+    BasePath.push_back(Base);
+
     // Construct the "from" expression, which is an implicit cast to the
     // appropriately-qualified base type.
     Expr *From = OtherRef->Retain();
     ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals),
                       CastExpr::CK_UncheckedDerivedToBase,
-                      ImplicitCastExpr::LValue, CXXBaseSpecifierArray(Base));
+                      ImplicitCastExpr::LValue, &BasePath);
 
     // Dereference "this".
     OwningExprResult To = CreateBuiltinUnaryOp(Loc, UnaryOperator::Deref,
@@ -4873,7 +4878,7 @@
                       Context.getCVRQualifiedType(BaseType,
                                       CopyAssignOperator->getTypeQualifiers()),
                       CastExpr::CK_UncheckedDerivedToBase, 
-                      ImplicitCastExpr::LValue, CXXBaseSpecifierArray(Base));
+                      ImplicitCastExpr::LValue, &BasePath);
     To = Owned(ToE);
 
     // Build the copy.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 82a2bb2..920c235 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1491,7 +1491,7 @@
     // type of the object type, in which case we just ignore it.
     // Otherwise build the appropriate casts.
     if (IsDerivedFrom(FromRecordType, QRecordType)) {
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath BasePath;
       if (CheckDerivedToBaseConversion(FromRecordType, QRecordType,
                                        FromLoc, FromRange, &BasePath))
         return true;
@@ -1499,7 +1499,7 @@
       if (PointerConversions)
         QType = Context.getPointerType(QType);
       ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
-                        Category, BasePath);
+                        Category, &BasePath);
 
       FromType = QType;
       FromRecordType = QRecordType;
@@ -1527,7 +1527,7 @@
     // conversion is non-trivial.
     if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) {
       assert(IsDerivedFrom(FromRecordType, URecordType));
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath BasePath;
       if (CheckDerivedToBaseConversion(FromRecordType, URecordType,
                                        FromLoc, FromRange, &BasePath))
         return true;
@@ -1536,7 +1536,7 @@
       if (PointerConversions)
         UType = Context.getPointerType(UType);
       ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
-                        Category, BasePath);
+                        Category, &BasePath);
       FromType = UType;
       FromRecordType = URecordType;
     }
@@ -1546,14 +1546,14 @@
     IgnoreAccess = true;
   }
 
-  CXXBaseSpecifierArray BasePath;
+  CXXCastPath BasePath;
   if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType,
                                    FromLoc, FromRange, &BasePath,
                                    IgnoreAccess))
     return true;
 
   ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
-                    Category, BasePath);
+                    Category, &BasePath);
   return false;
 }
 
@@ -3894,7 +3894,7 @@
 /// CheckCastTypes - Check type constraints for casting between types.
 bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
                           CastExpr::CastKind& Kind,
-                          CXXBaseSpecifierArray &BasePath,
+                          CXXCastPath &BasePath,
                           bool FunctionalStyle) {
   if (getLangOptions().CPlusPlus)
     return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath,
@@ -4064,16 +4064,16 @@
   Expr *castExpr = static_cast<Expr*>(Op.get());
 
   CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-  CXXBaseSpecifierArray BasePath;
+  CXXCastPath BasePath;
   if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr,
                      Kind, BasePath))
     return ExprError();
 
   Op.release();
-  return Owned(new (Context) CStyleCastExpr(
+  return Owned(CStyleCastExpr::Create(Context,
                                     Ty->getType().getNonLValueExprType(Context),
-                                            Kind, castExpr, BasePath, Ty,
-                                            LParenLoc, RParenLoc));
+                                      Kind, castExpr, &BasePath, Ty,
+                                      LParenLoc, RParenLoc));
 }
 
 /// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 1e5735d..b1d6015 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -533,18 +533,18 @@
   //
   if (NumExprs == 1) {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, BasePath,
                        /*FunctionalStyle=*/true))
       return ExprError();
 
     exprs.release();
 
-    return Owned(new (Context) CXXFunctionalCastExpr(
+    return Owned(CXXFunctionalCastExpr::Create(Context,
                                               Ty.getNonLValueExprType(Context),
-                                                     TInfo, TyBeginLoc, Kind,
-                                                     Exprs[0], BasePath,
-                                                     RParenLoc));
+                                               TInfo, TyBeginLoc, Kind,
+                                               Exprs[0], &BasePath,
+                                               RParenLoc));
   }
 
   if (Ty->isRecordType()) {
@@ -1823,22 +1823,22 @@
 
     
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
       return true;
-    ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, BasePath);
+    ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, &BasePath);
     break;
   }
   
   case ICK_Pointer_Member: {
     CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (CheckMemberPointerConversion(From, ToType, Kind, BasePath,
                                      IgnoreBaseAccess))
       return true;
     if (CheckExceptionSpecCompatibility(From, ToType))
       return true;
-    ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, BasePath);
+    ImpCastExprToType(From, ToType, Kind, ImplicitCastExpr::RValue, &BasePath);
     break;
   }
   case ICK_Boolean_Conversion: {
@@ -1851,7 +1851,7 @@
   }
 
   case ICK_Derived_To_Base: {
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (CheckDerivedToBaseConversion(From->getType(), 
                                      ToType.getNonReferenceType(),
                                      From->getLocStart(),
@@ -1861,7 +1861,8 @@
       return true;
 
     ImpCastExprToType(From, ToType.getNonReferenceType(),
-                      CastExpr::CK_DerivedToBase, CastCategory(From), BasePath);
+                      CastExpr::CK_DerivedToBase, CastCategory(From),
+                      &BasePath);
     break;
   }
 
@@ -1994,10 +1995,10 @@
     ImplicitCastExpr::ResultCategory Category =
         isIndirect ? ImplicitCastExpr::RValue : CastCategory(lex);
 
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     BuildBasePathArray(Paths, BasePath);
     ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, Category,
-                      BasePath);
+                      &BasePath);
   }
 
   if (isa<CXXScalarValueInitExpr>(rex->IgnoreParens())) {
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 5aa649b..5ffb648 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -3585,7 +3585,7 @@
       // We have a derived-to-base cast that produces either an rvalue or an
       // lvalue. Perform that cast.
       
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath BasePath;
 
       // Casts to inaccessible base classes are allowed with C-style casts.
       bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
@@ -3610,10 +3610,11 @@
               (Step->Kind == SK_CastDerivedToBaseXValue ?
                    ImplicitCastExpr::XValue :
                    ImplicitCastExpr::RValue);
-      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type,
-                                                    CastExpr::CK_DerivedToBase,
-                                                    (Expr*)CurInit.release(),
-                                                    BasePath, Category));
+      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+                                                 Step->Type,
+                                                 CastExpr::CK_DerivedToBase,
+                                                 (Expr*)CurInit.release(),
+                                                 &BasePath, Category));
       break;
     }
         
@@ -3748,10 +3749,9 @@
       
       CurInitExpr = CurInit.takeAs<Expr>();
       // FIXME: xvalues
-      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
-                                                         CastKind, 
-                                                         CurInitExpr,
-                                                        CXXBaseSpecifierArray(),
+      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+                                                 CurInitExpr->getType(),
+                                                 CastKind, CurInitExpr, 0,
                IsLvalue ? ImplicitCastExpr::LValue : ImplicitCastExpr::RValue));
       
       if (RequiresCopy)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 5dfbe09..27e6c2c 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1663,7 +1663,7 @@
 /// error, or returns false otherwise.
 bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
                                   CastExpr::CastKind &Kind,
-                                  CXXBaseSpecifierArray& BasePath,
+                                  CXXCastPath& BasePath,
                                   bool IgnoreBaseAccess) {
   QualType FromType = From->getType();
 
@@ -1755,7 +1755,7 @@
 /// otherwise.
 bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
                                         CastExpr::CastKind &Kind,
-                                        CXXBaseSpecifierArray &BasePath,
+                                        CXXCastPath &BasePath,
                                         bool IgnoreBaseAccess) {
   QualType FromType = From->getType();
   const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>();
@@ -3725,10 +3725,10 @@
   // well-formed.
   DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
                             From->getLocStart());
-  ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()),
+  ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack,
+                                Context.getPointerType(Conversion->getType()),
                                 CastExpr::CK_FunctionToPointerDecay,
-                                &ConversionRef, CXXBaseSpecifierArray(),
-                                ImplicitCastExpr::RValue);
+                                &ConversionRef, ImplicitCastExpr::RValue);
 
   // Note that it is safe to allocate CallExpr on the stack here because
   // there are 0 arguments (i.e., nothing is allocated using ASTContext's
@@ -7636,13 +7636,14 @@
     assert(Context.hasSameType(ICE->getSubExpr()->getType(), 
                                SubExpr->getType()) &&
            "Implicit cast type cannot be determined from overload");
+    assert(ICE->path_empty() && "fixing up hierarchy conversion?");
     if (SubExpr == ICE->getSubExpr())
       return ICE->Retain();
     
-    return new (Context) ImplicitCastExpr(ICE->getType(), 
-                                          ICE->getCastKind(),
-                                          SubExpr, CXXBaseSpecifierArray(),
-                                          ICE->getCategory());
+    return ImplicitCastExpr::Create(Context, ICE->getType(), 
+                                    ICE->getCastKind(),
+                                    SubExpr, 0,
+                                    ICE->getCategory());
   } 
   
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {