Store inheritance paths after CastExprs instead of inside them.
This takes some trickery since CastExpr has subclasses (and indeed,
is abstract).
Also, smoosh the CastKind into the bitfield from Expr.
Drops two words of storage from Expr in the common case of expressions
which don't need inheritance paths. Avoids a separate allocation and
another word of overhead in cases needing inheritance paths. Also has
the advantage of not leaking memory, since destructors for AST nodes are
never run.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110507 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 5bac172..9ae9b3a 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -22,13 +22,13 @@
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 @@
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 @@
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 @@
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 @@
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 173aadc..9424776 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -142,7 +142,7 @@
union {
struct {
- const CXXBaseSpecifierArray *BasePath;
+ const CastExpr *BasePath;
const CXXRecordDecl *DerivedClass;
} DerivedToBase;
@@ -152,7 +152,7 @@
} Field;
};
- SubobjectAdjustment(const CXXBaseSpecifierArray *BasePath,
+ SubobjectAdjustment(const CastExpr *BasePath,
const CXXRecordDecl *DerivedClass)
: Kind(DerivedToBaseAdjustment)
{
@@ -236,8 +236,7 @@
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 @@
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 @@
// 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 @@
// 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 219a5f9..0014d82 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -346,7 +346,9 @@
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 4831b5d..61d4ac2 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -572,7 +572,9 @@
// 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 d2ff562..dbafd2b 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -949,7 +949,7 @@
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 @@
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 @@
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 62a118c..255898b 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -403,8 +403,8 @@
// 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 5934da0..af7e069 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1074,12 +1074,14 @@
/// 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 a4d8368..c757878 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -315,7 +315,8 @@
/// 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