summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp117
1 files changed, 51 insertions, 66 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index e9a92ae0f01c..8346ee3aa6a8 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -180,11 +180,7 @@ CharUnits CodeGenModule::computeNonVirtualBaseClassOffset(
// Get the layout.
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
- const auto *BaseDecl =
- cast<CXXRecordDecl>(
- Base->getType()->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
-
+ const auto *BaseDecl = Base->getType()->castAsCXXRecordDecl();
// Add the offset.
Offset += Layout.getBaseClassOffset(BaseDecl);
@@ -302,9 +298,7 @@ Address CodeGenFunction::GetAddressOfBaseClass(
// *start* with a step down to the correct virtual base subobject,
// and hence will not require any further steps.
if ((*Start)->isVirtual()) {
- VBase = cast<CXXRecordDecl>(
- (*Start)->getType()->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
+ VBase = (*Start)->getType()->castAsCXXRecordDecl();
++Start;
}
@@ -559,10 +553,7 @@ static void EmitBaseInitializer(CodeGenFunction &CGF,
Address ThisPtr = CGF.LoadCXXThisAddress();
- const Type *BaseType = BaseInit->getBaseClass();
- const auto *BaseClassDecl =
- cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *BaseClassDecl = BaseInit->getBaseClass()->castAsCXXRecordDecl();
bool isBaseVirtual = BaseInit->isBaseVirtual();
@@ -1267,10 +1258,7 @@ namespace {
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) {
const Type *BaseType = BaseInit->getBaseClass();
- const auto *BaseClassDecl =
- cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
- return BaseClassDecl->isDynamicClass();
+ return BaseType->castAsCXXRecordDecl()->isDynamicClass();
}
/// EmitCtorPrologue - This routine generates necessary code to initialize
@@ -1283,10 +1271,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
const CXXRecordDecl *ClassDecl = CD->getParent();
- CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
- E = CD->init_end();
-
- // Virtual base initializers first, if any. They aren't needed if:
+ // Virtual base initializers aren't needed if:
// - This is a base ctor variant
// - There are no vbases
// - The class is abstract, so a complete object of it cannot be constructed
@@ -1308,15 +1293,36 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
assert(BaseCtorContinueBB);
}
- for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
- if (!ConstructVBases)
- continue;
- SaveAndRestore ThisRAII(CXXThisValue);
- if (CGM.getCodeGenOpts().StrictVTablePointers &&
- CGM.getCodeGenOpts().OptimizationLevel > 0 &&
- isInitializerOfDynamicClass(*B))
- CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
- EmitBaseInitializer(*this, ClassDecl, *B);
+ // Create three separate ranges for the different types of initializers.
+ auto AllInits = CD->inits();
+
+ // Find the boundaries between the three groups.
+ auto VirtualBaseEnd = std::find_if(
+ AllInits.begin(), AllInits.end(), [](const CXXCtorInitializer *Init) {
+ return !(Init->isBaseInitializer() && Init->isBaseVirtual());
+ });
+
+ auto NonVirtualBaseEnd = std::find_if(VirtualBaseEnd, AllInits.end(),
+ [](const CXXCtorInitializer *Init) {
+ return !Init->isBaseInitializer();
+ });
+
+ // Create the three ranges.
+ auto VirtualBaseInits = llvm::make_range(AllInits.begin(), VirtualBaseEnd);
+ auto NonVirtualBaseInits =
+ llvm::make_range(VirtualBaseEnd, NonVirtualBaseEnd);
+ auto MemberInits = llvm::make_range(NonVirtualBaseEnd, AllInits.end());
+
+ // Process virtual base initializers, if necessary.
+ if (ConstructVBases) {
+ for (CXXCtorInitializer *Initializer : VirtualBaseInits) {
+ SaveAndRestore ThisRAII(CXXThisValue);
+ if (CGM.getCodeGenOpts().StrictVTablePointers &&
+ CGM.getCodeGenOpts().OptimizationLevel > 0 &&
+ isInitializerOfDynamicClass(Initializer))
+ CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
+ EmitBaseInitializer(*this, ClassDecl, Initializer);
+ }
}
if (BaseCtorContinueBB) {
@@ -1326,14 +1332,14 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
}
// Then, non-virtual base initializers.
- for (; B != E && (*B)->isBaseInitializer(); B++) {
- assert(!(*B)->isBaseVirtual());
+ for (CXXCtorInitializer *Initializer : NonVirtualBaseInits) {
+ assert(!Initializer->isBaseVirtual());
SaveAndRestore ThisRAII(CXXThisValue);
if (CGM.getCodeGenOpts().StrictVTablePointers &&
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
- isInitializerOfDynamicClass(*B))
+ isInitializerOfDynamicClass(Initializer))
CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
- EmitBaseInitializer(*this, ClassDecl, *B);
+ EmitBaseInitializer(*this, ClassDecl, Initializer);
}
InitializeVTablePointers(ClassDecl);
@@ -1341,8 +1347,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
// And finally, initialize class members.
FieldConstructionScope FCS(*this, LoadCXXThisAddress());
ConstructorMemcpyizer CM(*this, CD, Args);
- for (; B != E; B++) {
- CXXCtorInitializer *Member = (*B);
+ for (CXXCtorInitializer *Member : MemberInits) {
assert(!Member->isBaseInitializer());
assert(Member->isAnyMemberInitializer() &&
"Delegating initializer on non-delegating constructor");
@@ -1377,10 +1382,7 @@ HasTrivialDestructorBody(ASTContext &Context,
if (I.isVirtual())
continue;
- const CXXRecordDecl *NonVirtualBase =
- cast<CXXRecordDecl>(
- I.getType()->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *NonVirtualBase = I.getType()->castAsCXXRecordDecl();
if (!HasTrivialDestructorBody(Context, NonVirtualBase,
MostDerivedClassDecl))
return false;
@@ -1389,10 +1391,7 @@ HasTrivialDestructorBody(ASTContext &Context,
if (BaseClassDecl == MostDerivedClassDecl) {
// Check virtual bases.
for (const auto &I : BaseClassDecl->vbases()) {
- const auto *VirtualBase =
- cast<CXXRecordDecl>(
- I.getType()->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
+ const auto *VirtualBase = I.getType()->castAsCXXRecordDecl();
if (!HasTrivialDestructorBody(Context, VirtualBase,
MostDerivedClassDecl))
return false;
@@ -1408,13 +1407,10 @@ FieldHasTrivialDestructorBody(ASTContext &Context,
{
QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
- const RecordType *RT = FieldBaseElementType->getAs<RecordType>();
- if (!RT)
+ auto *FieldClassDecl = FieldBaseElementType->getAsCXXRecordDecl();
+ if (!FieldClassDecl)
return true;
- auto *FieldClassDecl =
- cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
-
// The destructor for an implicit anonymous union member is never invoked.
if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
return true;
@@ -1502,6 +1498,8 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
// we'd introduce *two* handler blocks. In the Microsoft ABI, we
// always delegate because we might not have a definition in this TU.
switch (DtorType) {
+ case Dtor_Unified:
+ llvm_unreachable("not expecting a unified dtor");
case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
case Dtor_Deleting: llvm_unreachable("already handled deleting case");
@@ -1907,11 +1905,7 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
// We push them in the forward order so that they'll be popped in
// the reverse order.
for (const auto &Base : ClassDecl->vbases()) {
- auto *BaseClassDecl =
- cast<CXXRecordDecl>(
- Base.getType()->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
-
+ auto *BaseClassDecl = Base.getType()->castAsCXXRecordDecl();
if (BaseClassDecl->hasTrivialDestructor()) {
// Under SanitizeMemoryUseAfterDtor, poison the trivial base class
// memory. For non-trival base classes the same is done in the class
@@ -2130,10 +2124,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor,
void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
Address addr,
QualType type) {
- const RecordType *rtype = type->castAs<RecordType>();
- const auto *record =
- cast<CXXRecordDecl>(rtype->getOriginalDecl())->getDefinitionOrSelf();
- const CXXDestructorDecl *dtor = record->getDestructor();
+ const CXXDestructorDecl *dtor = type->castAsCXXRecordDecl()->getDestructor();
assert(!dtor->isTrivial());
CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
/*Delegating=*/false, addr, type);
@@ -2652,10 +2643,7 @@ void CodeGenFunction::getVTablePointers(BaseSubobject Base,
// Traverse bases.
for (const auto &I : RD->bases()) {
- auto *BaseDecl = cast<CXXRecordDecl>(
- I.getType()->castAs<RecordType>()->getOriginalDecl())
- ->getDefinitionOrSelf();
-
+ auto *BaseDecl = I.getType()->castAsCXXRecordDecl();
// Ignore classes without a vtable.
if (!BaseDecl->isDynamicClass())
continue;
@@ -2850,13 +2838,10 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
if (!getLangOpts().CPlusPlus)
return;
- auto *ClassTy = T->getAs<RecordType>();
- if (!ClassTy)
+ const auto *ClassDecl = T->getAsCXXRecordDecl();
+ if (!ClassDecl)
return;
- const auto *ClassDecl =
- cast<CXXRecordDecl>(ClassTy->getOriginalDecl())->getDefinitionOrSelf();
-
if (!ClassDecl->isCompleteDefinition() || !ClassDecl->isDynamicClass())
return;