diff options
-rw-r--r-- | include/clang/AST/Expr.h | 99 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 91 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 38 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 60 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 94 | ||||
-rw-r--r-- | lib/AST/StmtDumper.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 33 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 6 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderStmt.cpp | 27 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterStmt.cpp | 10 | ||||
-rw-r--r-- | lib/Rewrite/RewriteObjC.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 21 | ||||
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 54 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 27 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 19 |
27 files changed, 493 insertions, 235 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 79e7822b77..ccbe526e0c 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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; } diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 733c0944f3..3b59bb513a 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -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; } diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index b5fa362adb..5e8586f2a0 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -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, diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 7642c0de2c..d85162a342 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -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) { diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 7c2a8934a5..490783316e 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -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) { diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index c878a55e0e..f8f149541e 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -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 << " -> "; diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 5bac172b0e..9ae9b3a800 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -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. diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 173aadc91a..9424776898 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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())); } diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 219a5f9153..0014d8291e 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -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 diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 4831b5dabe..61d4ac26cf 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -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); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index d2ff5623cb..dbafd2bffe 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -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 diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 62a118cb02..255898b0aa 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -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); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 5934da0ef9..af7e0696f4 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -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, diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index a4d8368d4d..c7578788a5 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -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 diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index 6a11529b02..d5d527d32e 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -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: diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index eee409b047..3a65785b0f 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -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) { diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp index 9c52aa5f52..45c707fe29 100644 --- a/lib/Rewrite/RewriteObjC.cpp +++ b/lib/Rewrite/RewriteObjC.cpp @@ -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>(); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 244538147e..aeb4db987d 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -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) { diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index eb84417c33..3570a774b3 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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. diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 519d5692a3..53352661da 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -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. diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 0fcc0a7559..e822366842 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -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); } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 5cef150504..200b8fd681 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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 diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c5705dfa9e..08fa97b5e2 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 82a2bb2982..920c235945 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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 diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 1e5735d6f8..b1d6015514 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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())) { diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 5aa649bdc9..5ffb648120 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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) diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 5dfbe09709..27e6c2c2a3 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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)) { |