aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Expr.h99
-rw-r--r--include/clang/AST/ExprCXX.h91
-rw-r--r--lib/AST/ASTImporter.cpp38
-rw-r--r--lib/AST/Expr.cpp60
-rw-r--r--lib/AST/ExprCXX.cpp94
-rw-r--r--lib/AST/StmtDumper.cpp6
-rw-r--r--lib/CodeGen/CGClass.cpp33
-rw-r--r--lib/CodeGen/CGExpr.cpp16
-rw-r--r--lib/CodeGen/CGExprAgg.cpp4
-rw-r--r--lib/CodeGen/CGExprConstant.cpp4
-rw-r--r--lib/CodeGen/CGExprScalar.cpp8
-rw-r--r--lib/CodeGen/CGObjC.cpp4
-rw-r--r--lib/CodeGen/CodeGenFunction.h6
-rw-r--r--lib/CodeGen/CodeGenModule.h3
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp27
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp10
-rw-r--r--lib/Rewrite/RewriteObjC.cpp9
-rw-r--r--lib/Sema/Sema.cpp8
-rw-r--r--lib/Sema/Sema.h21
-rw-r--r--lib/Sema/SemaCXXCast.cpp54
-rw-r--r--lib/Sema/SemaChecking.cpp10
-rw-r--r--lib/Sema/SemaDecl.cpp10
-rw-r--r--lib/Sema/SemaDeclCXX.cpp27
-rw-r--r--lib/Sema/SemaExpr.cpp22
-rw-r--r--lib/Sema/SemaExprCXX.cpp27
-rw-r--r--lib/Sema/SemaInit.cpp18
-rw-r--r--lib/Sema/SemaOverload.cpp19
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>()->getDe