From: Rafael Espindola Date: Mon, 15 Sep 2014 19:20:10 +0000 (+0000) Subject: Move emitCXXStructor to CGCXXABI. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0433216bc05ec3e6ea8553230c6dbee9ae832416;p=clang Move emitCXXStructor to CGCXXABI. A followup patch will address the code duplication. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@217807 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index aa53691d77..58611e83ee 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -196,37 +196,6 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, return false; } -static void emitCXXConstructor(CodeGenModule &CGM, - const CXXConstructorDecl *ctor, - StructorType ctorType) { - if (!CGM.getTarget().getCXXABI().hasConstructorVariants()) { - // If there are no constructor variants, always emit the complete - // destructor. - ctorType = StructorType::Complete; - } else if (!ctor->getParent()->getNumVBases() && - (ctorType == StructorType::Complete || - ctorType == StructorType::Base)) { - // The complete constructor is equivalent to the base constructor - // for classes with no virtual bases. Try to emit it as an alias. - bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias( - GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true); - if (ctorType == StructorType::Complete && ProducedAlias) - return; - } - - const CGFunctionInfo &fnInfo = - CGM.getTypes().arrangeCXXStructorDeclaration(ctor, ctorType); - - auto *fn = cast( - CGM.getAddrOfCXXStructor(ctor, ctorType, &fnInfo, nullptr, true)); - GlobalDecl GD(ctor, toCXXCtorType(ctorType)); - CGM.setFunctionLinkage(GD, fn); - CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo); - - CGM.setFunctionDefinitionAttributes(ctor, fn); - CGM.SetLLVMFunctionAttributesForDefinition(ctor, fn); -} - llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor( const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo, llvm::FunctionType *FnType, bool DontDefer) { @@ -253,52 +222,6 @@ llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor( DontDefer)); } -static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, - StructorType dtorType) { - // The complete destructor is equivalent to the base destructor for - // classes with no virtual bases, so try to emit it as an alias. - if (!dtor->getParent()->getNumVBases() && - (dtorType == StructorType::Complete || dtorType == StructorType::Base)) { - bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias( - GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true); - if (ProducedAlias) { - if (dtorType == StructorType::Complete) - return; - if (dtor->isVirtual()) - CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete)); - } - } - - // The base destructor is equivalent to the base destructor of its - // base class if there is exactly one non-virtual base class with a - // non-trivial destructor, there are no fields with a non-trivial - // destructor, and the body of the destructor is trivial. - if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor)) - return; - - const CGFunctionInfo &fnInfo = - CGM.getTypes().arrangeCXXStructorDeclaration(dtor, dtorType); - - auto *fn = cast( - CGM.getAddrOfCXXStructor(dtor, dtorType, &fnInfo, nullptr, true)); - - GlobalDecl GD(dtor, toCXXDtorType(dtorType)); - CGM.setFunctionLinkage(GD, fn); - CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo); - - CGM.setFunctionDefinitionAttributes(dtor, fn); - CGM.SetLLVMFunctionAttributesForDefinition(dtor, fn); -} - -void CodeGenModule::emitCXXStructor(const CXXMethodDecl *MD, - StructorType Type) { - if (auto *CD = dyn_cast(MD)) { - emitCXXConstructor(*this, CD, Type); - return; - } - emitCXXDestructor(*this, cast(MD), Type); -} - static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF, GlobalDecl GD, llvm::Type *Ty, diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h index cf2cccd991..b7ce0b07e5 100644 --- a/lib/CodeGen/CGCXXABI.h +++ b/lib/CodeGen/CGCXXABI.h @@ -504,6 +504,10 @@ public: virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType); + + /// Emit a single constructor/destructor with the given type from a C++ + /// constructor Decl. + virtual void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) = 0; }; // Create an instance of a C++ ABI class: diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index b9986fc179..9938c2401f 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1404,9 +1404,9 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { // Make sure to emit the definition(s) before we emit the thunks. // This is necessary for the generation of certain thunks. if (const auto *CD = dyn_cast(Method)) - emitCXXStructor(CD, getFromCtorType(GD.getCtorType())); + ABI->emitCXXStructor(CD, getFromCtorType(GD.getCtorType())); else if (const auto *DD = dyn_cast(Method)) - emitCXXStructor(DD, getFromDtorType(GD.getDtorType())); + ABI->emitCXXStructor(DD, getFromDtorType(GD.getDtorType())); else EmitGlobalFunctionDefinition(GD, GV); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 1ae09c84cc..f0daa5169f 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -1091,10 +1091,6 @@ private: void EmitLinkageSpec(const LinkageSpecDecl *D); void CompleteDIClassType(const CXXMethodDecl* D); - /// Emit a single constructor/destructor with the given type from a C++ - /// constructor Decl. - void emitCXXStructor(const CXXMethodDecl *D, StructorType Type); - /// \brief Emit the function that initializes C++ thread_local variables. void EmitCXXThreadLocalInitFunc(); diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index bcc0f16620..877d32cc5f 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -274,6 +274,8 @@ public: classifyRTTIUniqueness(QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const; friend class ItaniumRTTIBuilder; + + void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override; }; class ARMCXXABI : public ItaniumCXXABI { @@ -2996,3 +2998,80 @@ ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness( assert(Linkage == llvm::GlobalValue::WeakODRLinkage); return RUK_NonUniqueVisible; } + +static void emitCXXConstructor(CodeGenModule &CGM, + const CXXConstructorDecl *ctor, + StructorType ctorType) { + if (!CGM.getTarget().getCXXABI().hasConstructorVariants()) { + // If there are no constructor variants, always emit the complete + // destructor. + ctorType = StructorType::Complete; + } else if (!ctor->getParent()->getNumVBases() && + (ctorType == StructorType::Complete || + ctorType == StructorType::Base)) { + // The complete constructor is equivalent to the base constructor + // for classes with no virtual bases. Try to emit it as an alias. + bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias( + GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true); + if (ctorType == StructorType::Complete && ProducedAlias) + return; + } + + const CGFunctionInfo &fnInfo = + CGM.getTypes().arrangeCXXStructorDeclaration(ctor, ctorType); + + auto *fn = cast( + CGM.getAddrOfCXXStructor(ctor, ctorType, &fnInfo, nullptr, true)); + GlobalDecl GD(ctor, toCXXCtorType(ctorType)); + CGM.setFunctionLinkage(GD, fn); + CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo); + + CGM.setFunctionDefinitionAttributes(ctor, fn); + CGM.SetLLVMFunctionAttributesForDefinition(ctor, fn); +} + +static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, + StructorType dtorType) { + // The complete destructor is equivalent to the base destructor for + // classes with no virtual bases, so try to emit it as an alias. + if (!dtor->getParent()->getNumVBases() && + (dtorType == StructorType::Complete || dtorType == StructorType::Base)) { + bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias( + GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true); + if (ProducedAlias) { + if (dtorType == StructorType::Complete) + return; + if (dtor->isVirtual()) + CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete)); + } + } + + // The base destructor is equivalent to the base destructor of its + // base class if there is exactly one non-virtual base class with a + // non-trivial destructor, there are no fields with a non-trivial + // destructor, and the body of the destructor is trivial. + if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor)) + return; + + const CGFunctionInfo &fnInfo = + CGM.getTypes().arrangeCXXStructorDeclaration(dtor, dtorType); + + auto *fn = cast( + CGM.getAddrOfCXXStructor(dtor, dtorType, &fnInfo, nullptr, true)); + + GlobalDecl GD(dtor, toCXXDtorType(dtorType)); + CGM.setFunctionLinkage(GD, fn); + CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo); + + CGM.setFunctionDefinitionAttributes(dtor, fn); + CGM.SetLLVMFunctionAttributesForDefinition(dtor, fn); +} + +void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD, + StructorType Type) { + if (auto *CD = dyn_cast(MD)) { + emitCXXConstructor(CGM, CD, Type); + return; + } + emitCXXDestructor(CGM, cast(MD), Type); +} diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 553112110c..51446bba74 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -525,6 +525,8 @@ public: llvm::Value *&This, llvm::Value *MemPtr, const MemberPointerType *MPT) override; + void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override; + private: typedef std::pair VFTableIdTy; typedef llvm::DenseMap VTablesMapTy; @@ -2870,3 +2872,80 @@ MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD, const VPtrInfo *Info) { return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info); } + +static void emitCXXConstructor(CodeGenModule &CGM, + const CXXConstructorDecl *ctor, + StructorType ctorType) { + if (!CGM.getTarget().getCXXABI().hasConstructorVariants()) { + // If there are no constructor variants, always emit the complete + // destructor. + ctorType = StructorType::Complete; + } else if (!ctor->getParent()->getNumVBases() && + (ctorType == StructorType::Complete || + ctorType == StructorType::Base)) { + // The complete constructor is equivalent to the base constructor + // for classes with no virtual bases. Try to emit it as an alias. + bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias( + GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true); + if (ctorType == StructorType::Complete && ProducedAlias) + return; + } + + const CGFunctionInfo &fnInfo = + CGM.getTypes().arrangeCXXStructorDeclaration(ctor, ctorType); + + auto *fn = cast( + CGM.getAddrOfCXXStructor(ctor, ctorType, &fnInfo, nullptr, true)); + GlobalDecl GD(ctor, toCXXCtorType(ctorType)); + CGM.setFunctionLinkage(GD, fn); + CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo); + + CGM.setFunctionDefinitionAttributes(ctor, fn); + CGM.SetLLVMFunctionAttributesForDefinition(ctor, fn); +} + +static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, + StructorType dtorType) { + // The complete destructor is equivalent to the base destructor for + // classes with no virtual bases, so try to emit it as an alias. + if (!dtor->getParent()->getNumVBases() && + (dtorType == StructorType::Complete || dtorType == StructorType::Base)) { + bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias( + GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true); + if (ProducedAlias) { + if (dtorType == StructorType::Complete) + return; + if (dtor->isVirtual()) + CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete)); + } + } + + // The base destructor is equivalent to the base destructor of its + // base class if there is exactly one non-virtual base class with a + // non-trivial destructor, there are no fields with a non-trivial + // destructor, and the body of the destructor is trivial. + if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor)) + return; + + const CGFunctionInfo &fnInfo = + CGM.getTypes().arrangeCXXStructorDeclaration(dtor, dtorType); + + auto *fn = cast( + CGM.getAddrOfCXXStructor(dtor, dtorType, &fnInfo, nullptr, true)); + + GlobalDecl GD(dtor, toCXXDtorType(dtorType)); + CGM.setFunctionLinkage(GD, fn); + CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo); + + CGM.setFunctionDefinitionAttributes(dtor, fn); + CGM.SetLLVMFunctionAttributesForDefinition(dtor, fn); +} + +void MicrosoftCXXABI::emitCXXStructor(const CXXMethodDecl *MD, + StructorType Type) { + if (auto *CD = dyn_cast(MD)) { + emitCXXConstructor(CGM, CD, Type); + return; + } + emitCXXDestructor(CGM, cast(MD), Type); +}