diff options
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 117 |
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; |
