]> granicus.if.org Git - clang/commitdiff
Store inheritance paths after CastExprs instead of inside them.
authorJohn McCall <rjmccall@apple.com>
Sat, 7 Aug 2010 06:22:56 +0000 (06:22 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 7 Aug 2010 06:22:56 +0000 (06:22 +0000)
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

27 files changed:
include/clang/AST/Expr.h
include/clang/AST/ExprCXX.h
lib/AST/ASTImporter.cpp
lib/AST/Expr.cpp
lib/AST/ExprCXX.cpp
lib/AST/StmtDumper.cpp
lib/CodeGen/CGClass.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.h
lib/Frontend/PCHReaderStmt.cpp
lib/Frontend/PCHWriterStmt.cpp
lib/Rewrite/RewriteObjC.cpp
lib/Sema/Sema.cpp
lib/Sema/Sema.h
lib/Sema/SemaCXXCast.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaOverload.cpp

index 79e7822b779db9b503d3b2d5254e0b15d3fd6b97..ccbe526e0cb69535d4235910a1d1133963aff0fe 100644 (file)
@@ -42,7 +42,7 @@ namespace clang {
   class TemplateArgumentListInfo;
 
 /// \brief A simple array of base specifiers.
-typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray;
+typedef llvm::SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
 
 /// Expr - This represents one expression.  Note that Expr's are subclasses of
 /// Stmt.  This allows an expression to be transparently used any place a Stmt
@@ -61,6 +61,8 @@ protected:
   /// (C++ [temp.dep.constexpr]).
   bool ValueDependent : 1;
 
+  enum { BitsRemaining = 30 };
+
   Expr(StmtClass SC, QualType T, bool TD, bool VD)
     : Stmt(SC), TypeDependent(TD), ValueDependent(VD) {
     setType(T);
@@ -1930,13 +1932,10 @@ public:
   };
 
 private:
-  CastKind Kind;
+  unsigned Kind : 5;
+  unsigned BasePathSize : BitsRemaining - 5;
   Stmt *Op;
 
-  /// BasePath - For derived-to-base and base-to-derived casts, the base array
-  /// contains the inheritance path.
-  CXXBaseSpecifierArray BasePath;
-
   void CheckBasePath() const {
 #ifndef NDEBUG
     switch (getCastKind()) {
@@ -1945,7 +1944,7 @@ private:
     case CK_DerivedToBaseMemberPointer:
     case CK_BaseToDerived:
     case CK_BaseToDerivedMemberPointer:
-      assert(!BasePath.empty() && "Cast kind should have a base path!");
+      assert(!path_empty() && "Cast kind should have a base path!");
       break;
 
     // These should not have an inheritance path.
@@ -1971,15 +1970,20 @@ private:
     case CK_MemberPointerToBoolean:
     case CK_AnyPointerToObjCPointerCast:
     case CK_AnyPointerToBlockPointerCast:
-      assert(BasePath.empty() && "Cast kind should not have a base path!");
+      assert(path_empty() && "Cast kind should not have a base path!");
       break;
     }
 #endif
   }
 
+  const CXXBaseSpecifier * const *path_buffer() const {
+    return const_cast<CastExpr*>(this)->path_buffer();
+  }
+  CXXBaseSpecifier **path_buffer();
+
 protected:
   CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op,
-           CXXBaseSpecifierArray BasePath) :
+           unsigned BasePathSize) :
     Expr(SC, ty,
          // Cast expressions are type-dependent if the type is
          // dependent (C++ [temp.dep.expr]p3).
@@ -1987,16 +1991,16 @@ protected:
          // Cast expressions are value-dependent if the type is
          // dependent or if the subexpression is value-dependent.
          ty->isDependentType() || (op && op->isValueDependent())),
-    Kind(kind), Op(op), BasePath(BasePath) {
-      CheckBasePath();
-    }
+    Kind(kind), BasePathSize(BasePathSize), Op(op) {
+    CheckBasePath();
+  }
 
   /// \brief Construct an empty cast.
-  CastExpr(StmtClass SC, EmptyShell Empty)
-    : Expr(SC, Empty) { }
+  CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
+    : Expr(SC, Empty), BasePathSize(BasePathSize) { }
 
 public:
-  CastKind getCastKind() const { return Kind; }
+  CastKind getCastKind() const { return static_cast<CastKind>(Kind); }
   void setCastKind(CastKind K) { Kind = K; }
   const char *getCastKindName() const;
 
@@ -2012,8 +2016,16 @@ public:
     return const_cast<CastExpr *>(this)->getSubExprAsWritten();
   }
 
-  const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
-        CXXBaseSpecifierArray& getBasePath()       { return BasePath; }
+  typedef CXXBaseSpecifier **path_iterator;
+  typedef const CXXBaseSpecifier * const *path_const_iterator;
+  bool path_empty() const { return BasePathSize == 0; }
+  unsigned path_size() const { return BasePathSize; }
+  path_iterator path_begin() { return path_buffer(); }
+  path_iterator path_end() { return path_buffer() + path_size(); }
+  path_const_iterator path_begin() const { return path_buffer(); }
+  path_const_iterator path_end() const { return path_buffer() + path_size(); }
+
+  void setCastPath(const CXXCastPath &Path);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() >= firstCastExprConstant &&
@@ -2056,14 +2068,28 @@ private:
   /// Category - The category this cast produces.
   ResultCategory Category;
 
-public:
-  ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, 
-                   CXXBaseSpecifierArray BasePath, ResultCategory Cat)
-    : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath), Category(Cat) { }
+  ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
+                   unsigned BasePathLength, ResultCategory Cat)
+    : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePathLength),
+      Category(Cat) { }
 
   /// \brief Construct an empty implicit cast.
-  explicit ImplicitCastExpr(EmptyShell Shell)
-    : CastExpr(ImplicitCastExprClass, Shell) { }
+  explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
+    : CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
+
+public:
+  enum OnStack_t { OnStack };
+  ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
+                   ResultCategory Cat)
+    : CastExpr(ImplicitCastExprClass, ty, kind, op, 0),
+      Category(Cat) { }
+
+  static ImplicitCastExpr *Create(ASTContext &Context, QualType T,
+                                  CastKind Kind, Expr *Operand,
+                                  const CXXCastPath *BasePath,
+                                  ResultCategory Cat);
+
+  static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
 
   virtual SourceRange getSourceRange() const {
     return getSubExpr()->getSourceRange();
@@ -2104,13 +2130,12 @@ class ExplicitCastExpr : public CastExpr {
 
 protected:
   ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind,
-                   Expr *op, CXXBaseSpecifierArray BasePath,
-                   TypeSourceInfo *writtenTy)
-    : CastExpr(SC, exprTy, kind, op, BasePath), TInfo(writtenTy) {}
+                   Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy)
+    : CastExpr(SC, exprTy, kind, op, PathSize), TInfo(writtenTy) {}
 
   /// \brief Construct an empty explicit cast.
-  ExplicitCastExpr(StmtClass SC, EmptyShell Shell)
-    : CastExpr(SC, Shell) { }
+  ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+    : CastExpr(SC, Shell, PathSize) { }
 
 public:
   /// getTypeInfoAsWritten - Returns the type source info for the type
@@ -2135,16 +2160,24 @@ public:
 class CStyleCastExpr : public ExplicitCastExpr {
   SourceLocation LPLoc; // the location of the left paren
   SourceLocation RPLoc; // the location of the right paren
-public:
+
   CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op,
-                 CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                 unsigned PathSize, TypeSourceInfo *writtenTy,
                  SourceLocation l, SourceLocation r)
-    : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, BasePath,
+    : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, PathSize,
                        writtenTy), LPLoc(l), RPLoc(r) {}
 
   /// \brief Construct an empty C-style explicit cast.
-  explicit CStyleCastExpr(EmptyShell Shell)
-    : ExplicitCastExpr(CStyleCastExprClass, Shell) { }
+  explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
+
+public:
+  static CStyleCastExpr *Create(ASTContext &Context, QualType T, CastKind K,
+                                Expr *Op, const CXXCastPath *BasePath,
+                                TypeSourceInfo *WrittenTy, SourceLocation L,
+                                SourceLocation R);
+
+  static CStyleCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
 
   SourceLocation getLParenLoc() const { return LPLoc; }
   void setLParenLoc(SourceLocation L) { LPLoc = L; }
index 733c0944f3ab0655917898ac21db2d629928dc86..3b59bb513a4ba7a97de2276d6de574e9ec22082b 100644 (file)
@@ -121,12 +121,12 @@ private:
 
 protected:
   CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op,
-                   CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                   unsigned PathSize, TypeSourceInfo *writtenTy,
                    SourceLocation l)
-    : ExplicitCastExpr(SC, ty, kind, op, BasePath, writtenTy), Loc(l) {}
+    : ExplicitCastExpr(SC, ty, kind, op, PathSize, writtenTy), Loc(l) {}
 
-  explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell)
-    : ExplicitCastExpr(SC, Shell) { }
+  explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(SC, Shell, PathSize) { }
 
 public:
   const char *getCastName() const;
@@ -158,14 +158,22 @@ public:
 /// This expression node represents a C++ static cast, e.g.,
 /// @c static_cast<int>(1.0).
 class CXXStaticCastExpr : public CXXNamedCastExpr {
-public:
   CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op, 
-                    CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                    unsigned pathSize, TypeSourceInfo *writtenTy,
                     SourceLocation l)
-    : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, BasePath, writtenTy, l) {}
+    : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, pathSize,
+                       writtenTy, l) {}
 
-  explicit CXXStaticCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { }
+  explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
+    : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { }
+
+public:
+  static CXXStaticCastExpr *Create(ASTContext &Context, QualType T,
+                                   CastKind K, Expr *Op,
+                                   const CXXCastPath *Path,
+                                   TypeSourceInfo *Written, SourceLocation L);
+  static CXXStaticCastExpr *CreateEmpty(ASTContext &Context,
+                                        unsigned PathSize);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXStaticCastExprClass;
@@ -180,15 +188,23 @@ public:
 /// This expression node represents a dynamic cast, e.g.,
 /// @c dynamic_cast<Derived*>(BasePtr).
 class CXXDynamicCastExpr : public CXXNamedCastExpr {
-public:
   CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op, 
-                     CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+                     unsigned pathSize, TypeSourceInfo *writtenTy,
                      SourceLocation l)
-    : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, BasePath,
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, pathSize,
                        writtenTy, l) {}
 
-  explicit CXXDynamicCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { }
+  explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
+    : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { }
+
+public:
+  static CXXDynamicCastExpr *Create(ASTContext &Context, QualType T,
+                                    CastKind Kind, Expr *Op,
+                                    const CXXCastPath *Path,
+                                    TypeSourceInfo *Written, SourceLocation L);
+  
+  static CXXDynamicCastExpr *CreateEmpty(ASTContext &Context,
+                                         unsigned pathSize);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXDynamicCastExprClass;
@@ -203,15 +219,22 @@ public:
 /// This expression node represents a reinterpret cast, e.g.,
 /// @c reinterpret_cast<int>(VoidPtr).
 class CXXReinterpretCastExpr : public CXXNamedCastExpr {
-public:
   CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op, 
-                         CXXBaseSpecifierArray BasePath,
+                         unsigned pathSize,
                          TypeSourceInfo *writtenTy, SourceLocation l)
-    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, BasePath,
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, pathSize,
                        writtenTy, l) {}
 
-  explicit CXXReinterpretCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty) { }
+  CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
+    : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { }
+
+public:
+  static CXXReinterpretCastExpr *Create(ASTContext &Context, QualType T,
+                                        CastKind Kind, Expr *Op,
+                                        const CXXCastPath *Path,
+                                 TypeSourceInfo *WrittenTy, SourceLocation L);
+  static CXXReinterpretCastExpr *CreateEmpty(ASTContext &Context,
+                                             unsigned pathSize);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXReinterpretCastExprClass;
@@ -225,14 +248,18 @@ public:
 /// This expression node represents a const cast, e.g.,
 /// @c const_cast<char*>(PtrToConstChar).
 class CXXConstCastExpr : public CXXNamedCastExpr {
-public:
   CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy,
                    SourceLocation l)
     : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op, 
-                       CXXBaseSpecifierArray(), writtenTy, l) {}
+                       0, writtenTy, l) {}
 
   explicit CXXConstCastExpr(EmptyShell Empty)
-    : CXXNamedCastExpr(CXXConstCastExprClass, Empty) { }
+    : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { }
+
+public:
+  static CXXConstCastExpr *Create(ASTContext &Context, QualType T, Expr *Op,
+                                  TypeSourceInfo *WrittenTy, SourceLocation L);
+  static CXXConstCastExpr *CreateEmpty(ASTContext &Context);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == CXXConstCastExprClass;
@@ -788,17 +815,27 @@ public:
 class CXXFunctionalCastExpr : public ExplicitCastExpr {
   SourceLocation TyBeginLoc;
   SourceLocation RParenLoc;
-public:
+
   CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy,
                         SourceLocation tyBeginLoc, CastKind kind,
-                        Expr *castExpr, CXXBaseSpecifierArray BasePath,
+                        Expr *castExpr, unsigned pathSize,
                         SourceLocation rParenLoc) 
     : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr, 
-                       BasePath, writtenTy),
+                       pathSize, writtenTy),
       TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
 
-  explicit CXXFunctionalCastExpr(EmptyShell Shell)
-    : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell) { }
+  explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
+    : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { }
+
+public:
+  static CXXFunctionalCastExpr *Create(ASTContext &Context, QualType T,
+                                       TypeSourceInfo *Written,
+                                       SourceLocation TyBeginLoc,
+                                       CastKind Kind, Expr *Op,
+                                       const CXXCastPath *Path,
+                                       SourceLocation RPLoc);
+  static CXXFunctionalCastExpr *CreateEmpty(ASTContext &Context,
+                                            unsigned PathSize);
 
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
   void setTypeBeginLoc(SourceLocation L) { TyBeginLoc = L; }
index b5fa362adb44663de7345f35600121b39c0de9cd..5e8586f2a06985658bce87239eee0ea38cdd321e 100644 (file)
@@ -123,6 +123,8 @@ namespace {
     Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
     Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
     Expr *VisitCStyleCastExpr(CStyleCastExpr *E);
+
+    bool ImportCasePath(CastExpr *E, CXXCastPath &Path);
   };
 }
 
@@ -2886,6 +2888,13 @@ Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
                                           Importer.Import(E->getOperatorLoc()));
 }
 
+bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
+  if (E->path_empty()) return false;
+
+  // TODO: import cast paths
+  return true;
+}
+
 Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
@@ -2894,13 +2903,13 @@ Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
   Expr *SubExpr = Importer.Import(E->getSubExpr());
   if (!SubExpr)
     return 0;
-  
-  // FIXME: Initialize the base path.
-  assert(E->getBasePath().empty() && "FIXME: Must copy base path!");
-  CXXBaseSpecifierArray BasePath;
-  return new (Importer.getToContext()) ImplicitCastExpr(T, E->getCastKind(),
-                                                        SubExpr, BasePath,
-                                                        E->getCategory());
+
+  CXXCastPath BasePath;
+  if (ImportCastPath(E, BasePath))
+    return 0;
+
+  return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
+                                  SubExpr, &BasePath, E->getCategory());
 }
 
 Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
@@ -2916,13 +2925,14 @@ Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
   if (!TInfo && E->getTypeInfoAsWritten())
     return 0;
   
-  // FIXME: Initialize the base path.
-  assert(E->getBasePath().empty() && "FIXME: Must copy base path!");
-  CXXBaseSpecifierArray BasePath;
-  return new (Importer.getToContext()) CStyleCastExpr(T, E->getCastKind(),
-                                                      SubExpr, BasePath, TInfo,
-                                            Importer.Import(E->getLParenLoc()),
-                                            Importer.Import(E->getRParenLoc()));
+  CXXCastPath BasePath;
+  if (ImportCastPath(E, BasePath))
+    return 0;
+
+  return CStyleCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
+                                SubExpr, &BasePath, TInfo,
+                                Importer.Import(E->getLParenLoc()),
+                                Importer.Import(E->getRParenLoc()));
 }
 
 ASTImporter::ASTImporter(Diagnostic &Diags,
index 7642c0de2cb92762c65a2dd2b5d4cd60c898e266..d85162a34261eb43c50e53fc1112d8135f2bb56a 100644 (file)
@@ -747,6 +747,66 @@ Expr *CastExpr::getSubExprAsWritten() {
   return SubExpr;
 }
 
+CXXBaseSpecifier **CastExpr::path_buffer() {
+  switch (getStmtClass()) {
+#define ABSTRACT_STMT(x)
+#define CASTEXPR(Type, Base) \
+  case Stmt::Type##Class: \
+    return reinterpret_cast<CXXBaseSpecifier**>(static_cast<Type*>(this)+1);
+#define STMT(Type, Base)
+#include "clang/AST/StmtNodes.inc"
+  default:
+    llvm_unreachable("non-cast expressions not possible here");
+    return 0;
+  }
+}
+
+void CastExpr::setCastPath(const CXXCastPath &Path) {
+  assert(Path.size() == path_size());
+  memcpy(path_buffer(), Path.data(), Path.size() * sizeof(CXXBaseSpecifier*));
+}
+
+ImplicitCastExpr *ImplicitCastExpr::Create(ASTContext &C, QualType T,
+                                           CastKind Kind, Expr *Operand,
+                                           const CXXCastPath *BasePath,
+                                           ResultCategory Cat) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer =
+    C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  ImplicitCastExpr *E =
+    new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, Cat);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(ASTContext &C,
+                                                unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(ImplicitCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) ImplicitCastExpr(EmptyShell(), PathSize);
+}
+
+
+CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T,
+                                       CastKind K, Expr *Op,
+                                       const CXXCastPath *BasePath,
+                                       TypeSourceInfo *WrittenTy,
+                                       SourceLocation L, SourceLocation R) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer =
+    C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  CStyleCastExpr *E =
+    new (Buffer) CStyleCastExpr(T, K, Op, PathSize, WrittenTy, L, R);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CStyleCastExpr *CStyleCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CStyleCastExpr(EmptyShell(), PathSize);
+}
+
 /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
 /// corresponds to, e.g. "<<=".
 const char *BinaryOperator::getOpcodeStr(Opcode Op) {
index 7c2a8934a592018b18b438ad0ad6f9ac9f93577a..490783316ed65d2abab422dc82dbd4ac9d7c31c8 100644 (file)
@@ -460,6 +460,100 @@ const char *CXXNamedCastExpr::getCastName() const {
   }
 }
 
+CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T,
+                                             CastKind K, Expr *Op,
+                                             const CXXCastPath *BasePath,
+                                             TypeSourceInfo *WrittenTy,
+                                             SourceLocation L) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXStaticCastExpr *E =
+    new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C,
+                                                  unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXStaticCastExpr(EmptyShell(), PathSize);
+}
+
+CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T,
+                                               CastKind K, Expr *Op,
+                                               const CXXCastPath *BasePath,
+                                               TypeSourceInfo *WrittenTy,
+                                               SourceLocation L) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXDynamicCastExpr *E =
+    new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C,
+                                                    unsigned PathSize) {
+  void *Buffer =
+    C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXDynamicCastExpr(EmptyShell(), PathSize);
+}
+
+CXXReinterpretCastExpr *
+CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op,
+                               const CXXCastPath *BasePath,
+                               TypeSourceInfo *WrittenTy, SourceLocation L) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer =
+    C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXReinterpretCastExpr *E =
+    new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXReinterpretCastExpr *
+CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
+  void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize);
+}
+
+CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op,
+                                           TypeSourceInfo *WrittenTy,
+                                           SourceLocation L) {
+  return new (C) CXXConstCastExpr(T, Op, WrittenTy, L);
+}
+
+CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) {
+  return new (C) CXXConstCastExpr(EmptyShell());
+}
+
+CXXFunctionalCastExpr *
+CXXFunctionalCastExpr::Create(ASTContext &C, QualType T,
+                              TypeSourceInfo *Written, SourceLocation L,
+                              CastKind K, Expr *Op, const CXXCastPath *BasePath,
+                               SourceLocation R) {
+  unsigned PathSize = (BasePath ? BasePath->size() : 0);
+  void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  CXXFunctionalCastExpr *E =
+    new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R);
+  if (PathSize) E->setCastPath(*BasePath);
+  return E;
+}
+
+CXXFunctionalCastExpr *
+CXXFunctionalCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) {
+  void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr)
+                            + PathSize * sizeof(CXXBaseSpecifier*));
+  return new (Buffer) CXXFunctionalCastExpr(EmptyShell(), PathSize);
+}
+
+
 CXXDefaultArgExpr *
 CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, 
                           ParmVarDecl *Param, Expr *SubExpr) {
index c878a55e0e6440bc963f1e9e38681c21e36dbeab..f8f149541e1addf08d6a91f7738742b379a47ada 100644 (file)
@@ -308,13 +308,13 @@ void StmtDumper::VisitExpr(Expr *Node) {
 }
 
 static void DumpBasePath(llvm::raw_ostream &OS, CastExpr *Node) {
-  if (Node->getBasePath().empty())
+  if (Node->path_empty())
     return;
 
   OS << " (";
   bool First = true;
-  for (CXXBaseSpecifierArray::iterator I = Node->getBasePath().begin(),
-       E = Node->getBasePath().end(); I != E; ++I) {
+  for (CastExpr::path_iterator
+         I = Node->path_begin(), E = Node->path_end(); I != E; ++I) {
     const CXXBaseSpecifier *Base = *I;
     if (!First)
       OS << " -> ";
index 5bac172b0ee370861ebc5bc1da550d7763045077..9ae9b3a80032339091dfc07d4ddfc137978a9021 100644 (file)
@@ -22,13 +22,13 @@ using namespace CodeGen;
 static uint64_t 
 ComputeNonVirtualBaseClassOffset(ASTContext &Context, 
                                  const CXXRecordDecl *DerivedClass,
-                                 CXXBaseSpecifierArray::iterator Start,
-                                 CXXBaseSpecifierArray::iterator End) {
+                                 CastExpr::path_const_iterator Start,
+                                 CastExpr::path_const_iterator End) {
   uint64_t Offset = 0;
   
   const CXXRecordDecl *RD = DerivedClass;
   
-  for (CXXBaseSpecifierArray::iterator I = Start; I != End; ++I) {
+  for (CastExpr::path_const_iterator I = Start; I != End; ++I) {
     const CXXBaseSpecifier *Base = *I;
     assert(!Base->isVirtual() && "Should not see virtual bases here!");
 
@@ -50,12 +50,13 @@ ComputeNonVirtualBaseClassOffset(ASTContext &Context,
 
 llvm::Constant *
 CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
-                                        const CXXBaseSpecifierArray &BasePath) {
-  assert(!BasePath.empty() && "Base path should not be empty!");
+                                   CastExpr::path_const_iterator PathBegin,
+                                   CastExpr::path_const_iterator PathEnd) {
+  assert(PathBegin != PathEnd && "Base path should not be empty!");
 
   uint64_t Offset = 
-    ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 
-                                     BasePath.begin(), BasePath.end());
+    ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl,
+                                     PathBegin, PathEnd);
   if (!Offset)
     return 0;
   
@@ -131,11 +132,12 @@ ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ThisPtr,
 llvm::Value *
 CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 
                                        const CXXRecordDecl *Derived,
-                                       const CXXBaseSpecifierArray &BasePath, 
+                                       CastExpr::path_const_iterator PathBegin,
+                                       CastExpr::path_const_iterator PathEnd,
                                        bool NullCheckValue) {
-  assert(!BasePath.empty() && "Base path should not be empty!");
+  assert(PathBegin != PathEnd && "Base path should not be empty!");
 
-  CXXBaseSpecifierArray::iterator Start = BasePath.begin();
+  CastExpr::path_const_iterator Start = PathBegin;
   const CXXRecordDecl *VBase = 0;
   
   // Get the virtual base.
@@ -147,11 +149,11 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
   
   uint64_t NonVirtualOffset = 
     ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived,
-                                     Start, BasePath.end());
+                                     Start, PathEnd);
 
   // Get the base pointer type.
   const llvm::Type *BasePtrTy = 
-    ConvertType((BasePath.end()[-1])->getType())->getPointerTo();
+    ConvertType((PathEnd[-1])->getType())->getPointerTo();
   
   if (!NonVirtualOffset && !VBase) {
     // Just cast back.
@@ -206,16 +208,17 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
 llvm::Value *
 CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
                                           const CXXRecordDecl *Derived,
-                                          const CXXBaseSpecifierArray &BasePath,
+                                        CastExpr::path_const_iterator PathBegin,
+                                          CastExpr::path_const_iterator PathEnd,
                                           bool NullCheckValue) {
-  assert(!BasePath.empty() && "Base path should not be empty!");
+  assert(PathBegin != PathEnd && "Base path should not be empty!");
 
   QualType DerivedTy =
     getContext().getCanonicalType(getContext().getTagDeclType(Derived));
   const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
   
   llvm::Value *NonVirtualOffset =
-    CGM.GetNonVirtualBaseClassOffset(Derived, BasePath);
+    CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
   
   if (!NonVirtualOffset) {
     // No offset, we can just cast back.
index 173aadc91a06d4d6dd8c87c1fa6b3c198a379ce5..9424776898b4dd90fffac9f40a9cf7843ecdb798 100644 (file)
@@ -142,7 +142,7 @@ struct SubobjectAdjustment {
   
   union {
     struct {
-      const CXXBaseSpecifierArray *BasePath;
+      const CastExpr *BasePath;
       const CXXRecordDecl *DerivedClass;
     } DerivedToBase;
     
@@ -152,7 +152,7 @@ struct SubobjectAdjustment {
     } Field;
   };
   
-  SubobjectAdjustment(const CXXBaseSpecifierArray *BasePath, 
+  SubobjectAdjustment(const CastExpr *BasePath, 
                       const CXXRecordDecl *DerivedClass)
     : Kind(DerivedToBaseAdjustment) 
   {
@@ -236,8 +236,7 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
           E = CE->getSubExpr();
           CXXRecordDecl *Derived 
             = cast<CXXRecordDecl>(E->getType()->getAs<RecordType>()->getDecl());
-          Adjustments.push_back(SubobjectAdjustment(&CE->getBasePath(), 
-                                                    Derived));
+          Adjustments.push_back(SubobjectAdjustment(CE, Derived));
           continue;
         }
 
@@ -291,7 +290,8 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
           Object = 
               CGF.GetAddressOfBaseClass(Object, 
                                         Adjustment.DerivedToBase.DerivedClass, 
-                                        *Adjustment.DerivedToBase.BasePath, 
+                              Adjustment.DerivedToBase.BasePath->path_begin(),
+                              Adjustment.DerivedToBase.BasePath->path_end(),
                                         /*NullCheckValue=*/false);
           break;
             
@@ -1820,7 +1820,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
     // Perform the derived-to-base conversion
     llvm::Value *Base = 
       GetAddressOfBaseClass(This, DerivedClassDecl, 
-                            E->getBasePath(), /*NullCheckValue=*/false);
+                            E->path_begin(), E->path_end(),
+                            /*NullCheckValue=*/false);
     
     return LValue::MakeAddr(Base, MakeQualifiers(E->getType()));
   }
@@ -1836,7 +1837,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
     // Perform the base-to-derived conversion
     llvm::Value *Derived = 
       GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, 
-                               E->getBasePath(),/*NullCheckValue=*/false);
+                               E->path_begin(), E->path_end(),
+                               /*NullCheckValue=*/false);
     
     return LValue::MakeAddr(Derived, MakeQualifiers(E->getType()));
   }
index 219a5f9153290e0e321a1de64461b901ef5e00cf..0014d8291e895aba87b218fba3cc1e30f7423f81 100644 (file)
@@ -346,7 +346,9 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
       std::swap(DerivedDecl, BaseDecl);
 
     if (llvm::Constant *Adj = 
-          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, E->getBasePath())) {
+          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
+                                               E->path_begin(),
+                                               E->path_end())) {
       if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
         SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
       else
index 4831b5dabe0aaa340aaeb6ee67a4939332763bf9..61d4ac26cf380ca94f543ef3a867cfa7919d7428 100644 (file)
@@ -572,7 +572,9 @@ public:
         
         // Check if we need to update the adjustment.
         if (llvm::Constant *Offset = 
-            CGM.GetNonVirtualBaseClassOffset(DerivedClass, E->getBasePath())) {
+            CGM.GetNonVirtualBaseClassOffset(DerivedClass,
+                                             E->path_begin(),
+                                             E->path_end())) {
           llvm::Constant *Values[2];
         
           Values[0] = CS->getOperand(0);
index d2ff5623cbe351aa4c85afe2e7416a312ca69816..dbafd2bffe8e52ff2b390493b6c0371807671f62 100644 (file)
@@ -949,7 +949,7 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
       DestTy->getCXXRecordDeclForPointerType();
     
     return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl, 
-                                        CE->getBasePath(), 
+                                        CE->path_begin(), CE->path_end(),
                                         ShouldNullCheckClassCastValue(CE));
   }
   case CastExpr::CK_UncheckedDerivedToBase:
@@ -960,7 +960,7 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
       cast<CXXRecordDecl>(DerivedClassTy->getDecl());
 
     return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl, 
-                                     CE->getBasePath(),
+                                     CE->path_begin(), CE->path_end(),
                                      ShouldNullCheckClassCastValue(CE));
   }
   case CastExpr::CK_Dynamic: {
@@ -1011,7 +1011,9 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
       std::swap(DerivedDecl, BaseDecl);
 
     if (llvm::Constant *Adj = 
-          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl, CE->getBasePath())){
+          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
+                                               CE->path_begin(),
+                                               CE->path_end())) {
       if (CE->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
         Src = Builder.CreateNSWSub(Src, Adj, "adj");
       else
index 62a118cb02e2d54f05eb1f7febee711398c48cc8..255898b0aa75178f2092b475eac0b1e94a2bd0b8 100644 (file)
@@ -403,8 +403,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
     // Objective-C pointer types, we can always bit cast the RHS in these cases.
     if (getContext().getCanonicalType(Ivar->getType()) !=
         getContext().getCanonicalType(ArgDecl->getType())) {
-      ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg,
-                                 CXXBaseSpecifierArray(),
+      ImplicitCastExpr ArgCasted(ImplicitCastExpr::OnStack,
+                                 Ivar->getType(), CastExpr::CK_BitCast, &Arg,
                                  ImplicitCastExpr::RValue);
       BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign,
                             Ivar->getType(), Loc);
index 5934da0ef913fdfcc017be7f036dcdb42aeaee91..af7e0696f492b78d5fea13166092d0eb72b091b4 100644 (file)
@@ -1074,12 +1074,14 @@ public:
   /// load of 'this' and returns address of the base class.
   llvm::Value *GetAddressOfBaseClass(llvm::Value *Value, 
                                      const CXXRecordDecl *Derived,
-                                     const CXXBaseSpecifierArray &BasePath, 
+                                     CastExpr::path_const_iterator PathBegin,
+                                     CastExpr::path_const_iterator PathEnd,
                                      bool NullCheckValue);
 
   llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
                                         const CXXRecordDecl *Derived,
-                                        const CXXBaseSpecifierArray &BasePath,
+                                        CastExpr::path_const_iterator PathBegin,
+                                        CastExpr::path_const_iterator PathEnd,
                                         bool NullCheckValue);
 
   llvm::Value *GetVirtualBaseClassOffset(llvm::Value *This,
index a4d8368d4d9edc164ae244b60dc4dff733c65f6b..c7578788a5728e593aba108b04144e54f84afa63 100644 (file)
@@ -315,7 +315,8 @@ public:
   /// a class. Returns null if the offset is 0. 
   llvm::Constant *
   GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
-                               const CXXBaseSpecifierArray &BasePath);
+                               CastExpr::path_const_iterator PathBegin,
+                               CastExpr::path_const_iterator PathEnd);
   
   /// GetStringForStringLiteral - Return the appropriate bytes for a string
   /// literal, properly padded to match the literal type. If only the address of
index 6a11529b02c26f35f4505f322c50396b195e10d7..d5d527d32e3ab60a61ae0b7db59e01d2ef24bc0a 100644 (file)
@@ -559,14 +559,15 @@ void PCHStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
 
 void PCHStmtReader::VisitCastExpr(CastExpr *E) {
   VisitExpr(E);
+  unsigned NumBaseSpecs = Record[Idx++];
+  assert(NumBaseSpecs == E->path_size());
   E->setSubExpr(Reader.ReadSubExpr());
   E->setCastKind((CastExpr::CastKind)Record[Idx++]);
-  CXXBaseSpecifierArray &BasePath = E->getBasePath();
-  unsigned NumBaseSpecs = Record[Idx++];
+  CastExpr::path_iterator BaseI = E->path_begin();
   while (NumBaseSpecs--) {
     CXXBaseSpecifier *BaseSpec = new (*Reader.getContext()) CXXBaseSpecifier;
     *BaseSpec = Reader.ReadCXXBaseSpecifier(DeclsCursor, Record, Idx);
-    BasePath.push_back(BaseSpec);
+    *BaseI++ = BaseSpec;
   }
 }
 
@@ -1495,11 +1496,13 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
       break;
 
     case pch::EXPR_IMPLICIT_CAST:
-      S = new (Context) ImplicitCastExpr(Empty);
+      S = ImplicitCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[PCHStmtReader::NumExprFields]);
       break;
 
     case pch::EXPR_CSTYLE_CAST:
-      S = new (Context) CStyleCastExpr(Empty);
+      S = CStyleCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[PCHStmtReader::NumExprFields]);
       break;
 
     case pch::EXPR_COMPOUND_LITERAL:
@@ -1638,23 +1641,27 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
       break;
 
     case pch::EXPR_CXX_STATIC_CAST:
-      S = new (Context) CXXStaticCastExpr(Empty);
+      S = CXXStaticCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[PCHStmtReader::NumExprFields]);
       break;
 
     case pch::EXPR_CXX_DYNAMIC_CAST:
-      S = new (Context) CXXDynamicCastExpr(Empty);
+      S = CXXDynamicCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[PCHStmtReader::NumExprFields]);
       break;
 
     case pch::EXPR_CXX_REINTERPRET_CAST:
-      S = new (Context) CXXReinterpretCastExpr(Empty);
+      S = CXXReinterpretCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[PCHStmtReader::NumExprFields]);
       break;
 
     case pch::EXPR_CXX_CONST_CAST:
-      S = new (Context) CXXConstCastExpr(Empty);
+      S = CXXConstCastExpr::CreateEmpty(*Context);
       break;
 
     case pch::EXPR_CXX_FUNCTIONAL_CAST:
-      S = new (Context) CXXFunctionalCastExpr(Empty);
+      S = CXXFunctionalCastExpr::CreateEmpty(*Context,
+                       /*PathSize*/ Record[PCHStmtReader::NumExprFields]);
       break;
 
     case pch::EXPR_CXX_BOOL_LITERAL:
index eee409b047dea48ab4aa447bbe70c58ee9d78ad8..3a65785b0f797bd717aabfa2bfcea15bc65dcfad 100644 (file)
@@ -567,13 +567,13 @@ void PCHStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
 
 void PCHStmtWriter::VisitCastExpr(CastExpr *E) {
   VisitExpr(E);
+  Record.push_back(E->path_size());
   Writer.AddStmt(E->getSubExpr());
   Record.push_back(E->getCastKind()); // FIXME: stable encoding
-  CXXBaseSpecifierArray &BasePath = E->getBasePath();
-  Record.push_back(BasePath.size());
-  for (CXXBaseSpecifierArray::iterator I = BasePath.begin(), E = BasePath.end();
-       I != E; ++I)
-    Writer.AddCXXBaseSpecifier(**I, Record);
+
+  for (CastExpr::path_iterator
+         PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
+    Writer.AddCXXBaseSpecifier(**PI, Record);
 }
 
 void PCHStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
index 9c52aa5f52c52769884bbd64a1f824627f4acaf2..45c707fe29f203e508e03541a5fd1c6daa7bef43 100644 (file)
@@ -459,8 +459,8 @@ namespace {
   CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
                                            CastExpr::CastKind Kind, Expr *E) {
     TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
-    return new (Ctx) CStyleCastExpr(Ty, Kind, E, CXXBaseSpecifierArray(), TInfo,
-                                    SourceLocation(), SourceLocation());
+    return CStyleCastExpr::Create(*Ctx, Ty, Kind, E, 0, TInfo,
+                                  SourceLocation(), SourceLocation());
   }
 }
 
@@ -2106,9 +2106,8 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
   // Now, we cast the reference to a pointer to the objc_msgSend type.
   QualType pToFunc = Context->getPointerType(msgSendType);
   ImplicitCastExpr *ICE = 
-    new (Context) ImplicitCastExpr(pToFunc, CastExpr::CK_Unknown,
-                                   DRE, CXXBaseSpecifierArray(),
-                                   ImplicitCastExpr::RValue);
+    ImplicitCastExpr::Create(*Context, pToFunc, CastExpr::CK_Unknown,
+                             DRE, 0, ImplicitCastExpr::RValue);
 
   const FunctionType *FT = msgSendType->getAs<FunctionType>();
 
index 244538147e53ddfd4325db9435c05d88a0c21a13..aeb4db987db5de6776245836691deeaa18a1352a 100644 (file)
@@ -159,7 +159,7 @@ Sema::~Sema() {
 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 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
   // 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 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
   }
 
   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) {
index eb84417c33af0a34e4df4b9eff1fe4c1c4c1dc53..3570a774b364dc00c045ced2fc5ae14f7b48ea5e 100644 (file)
@@ -1179,14 +1179,14 @@ public:
   
   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 @@ public:
   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 @@ public:
   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 @@ public:
   /// 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 @@ public:
   /// 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.
index 519d5692a3cc284e34f79b496e764ed720853054..53352661da53bcce377990b0408aeaba3b49fe83 100644 (file)
@@ -47,12 +47,12 @@ static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 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 @@ static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr,
                                                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 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
                                    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 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
   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 @@ static void
 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 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 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 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
                                    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 @@ TryCastResult
 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 @@ TryCastResult
 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 @@ TryCastResult
 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 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
                              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 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
 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.
index 0fcc0a755940930f1ca00d378c8257d704c6a58a..e8223668425fb08961ab23301e8acfd216a10d1c 100644 (file)
@@ -524,9 +524,9 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
     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 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
     // 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 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
     // 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);
   }
 
index 5cef15050424abbd32b467ceba5687e5fb79959a..200b8fd681086eca05e684b935010127db94c4a3 100644 (file)
@@ -6803,11 +6803,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
 
     // 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
index c5705dfa9e743a6aa7fa32392844b5e2ccfc9a5b..08fa97b5e2ca2f8ddd12b844c91d23d4e33340d8 100644 (file)
@@ -720,7 +720,7 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) {
 }
 
 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 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
 
   // 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 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                    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 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
 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 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
     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 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
       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 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
                       Context.getCVRQualifiedType(BaseType,
                                       CopyAssignOperator->getTypeQualifiers()),
                       CastExpr::CK_UncheckedDerivedToBase, 
-                      ImplicitCastExpr::LValue, CXXBaseSpecifierArray(Base));
+                      ImplicitCastExpr::LValue, &BasePath);
     To = Owned(ToE);
 
     // Build the copy.
index 82a2bb2982c40ef1aec1545b3998094e5fb2ac32..920c235945ccfc52d57f1fcbe5978e5e6c62780a 100644 (file)
@@ -1491,7 +1491,7 @@ Sema::PerformObjectMemberConversion(Expr *&From,
     // 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 @@ Sema::PerformObjectMemberConversion(Expr *&From,
       if (PointerConversions)
         QType = Context.getPointerType(QType);
       ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
-                        Category, BasePath);
+                        Category, &BasePath);
 
       FromType = QType;
       FromRecordType = QRecordType;
@@ -1527,7 +1527,7 @@ Sema::PerformObjectMemberConversion(Expr *&From,
     // 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 @@ Sema::PerformObjectMemberConversion(Expr *&From,
       if (PointerConversions)
         UType = Context.getPointerType(UType);
       ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
-                        Category, BasePath);
+                        Category, &BasePath);
       FromType = UType;
       FromRecordType = URecordType;
     }
@@ -1546,14 +1546,14 @@ Sema::PerformObjectMemberConversion(Expr *&From,
     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 @@ static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
 /// 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 @@ Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty,
   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
index 1e5735d6f83522c3010afe312bec0eaa5f953df6..b1d601551412b755ad5615cea850c982222a6577 100644 (file)
@@ -533,18 +533,18 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
   //
   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 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
 
     
     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 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
   }
 
   case ICK_Derived_To_Base: {
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (CheckDerivedToBaseConversion(From->getType(), 
                                      ToType.getNonReferenceType(),
                                      From->getLocStart(),
@@ -1861,7 +1861,8 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
       return true;
 
     ImpCastExprToType(From, ToType.getNonReferenceType(),
-                      CastExpr::CK_DerivedToBase, CastCategory(From), BasePath);
+                      CastExpr::CK_DerivedToBase, CastCategory(From),
+                      &BasePath);
     break;
   }
 
@@ -1994,10 +1995,10 @@ QualType Sema::CheckPointerToMemberOperands(
     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())) {
index 5aa649bdc92e731e6d47811b3b75a0d99df5accd..5ffb6481206f0c243f0779648823bc2985baa40a 100644 (file)
@@ -3585,7 +3585,7 @@ InitializationSequence::Perform(Sema &S,
       // 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 @@ InitializationSequence::Perform(Sema &S,
               (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 @@ InitializationSequence::Perform(Sema &S,
       
       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)
index 5dfbe09709fbdaae23f730210af0e89bc7706ce5..27e6c2c2a3467f9c0b15dec6e8585cdc7bc64dc0 100644 (file)
@@ -1663,7 +1663,7 @@ bool Sema::FunctionArgTypesAreEqual(FunctionProtoType*  OldType,
 /// 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 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
 /// 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 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
   // 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 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
     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)) {