r217807 - Move emitCXXStructor to CGCXXABI.
Rafael Espindola
rafael.espindola at gmail.com
Mon Sep 15 12:20:10 PDT 2014
Author: rafael
Date: Mon Sep 15 14:20:10 2014
New Revision: 217807
URL: http://llvm.org/viewvc/llvm-project?rev=217807&view=rev
Log:
Move emitCXXStructor to CGCXXABI.
A followup patch will address the code duplication.
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGCXXABI.h
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=217807&r1=217806&r2=217807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Mon Sep 15 14:20:10 2014
@@ -196,37 +196,6 @@ bool CodeGenModule::TryEmitDefinitionAsA
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<llvm::Function>(
- 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::getAdd
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<llvm::Function>(
- 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<CXXConstructorDecl>(MD)) {
- emitCXXConstructor(*this, CD, Type);
- return;
- }
- emitCXXDestructor(*this, cast<CXXDestructorDecl>(MD), Type);
-}
-
static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
GlobalDecl GD,
llvm::Type *Ty,
Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=217807&r1=217806&r2=217807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Mon Sep 15 14:20:10 2014
@@ -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:
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=217807&r1=217806&r2=217807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Sep 15 14:20:10 2014
@@ -1404,9 +1404,9 @@ void CodeGenModule::EmitGlobalDefinition
// 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<CXXConstructorDecl>(Method))
- emitCXXStructor(CD, getFromCtorType(GD.getCtorType()));
+ ABI->emitCXXStructor(CD, getFromCtorType(GD.getCtorType()));
else if (const auto *DD = dyn_cast<CXXDestructorDecl>(Method))
- emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
+ ABI->emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
else
EmitGlobalFunctionDefinition(GD, GV);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=217807&r1=217806&r2=217807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Sep 15 14:20:10 2014
@@ -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();
Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=217807&r1=217806&r2=217807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Mon Sep 15 14:20:10 2014
@@ -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 Itaniu
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<llvm::Function>(
+ 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<llvm::Function>(
+ 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<CXXConstructorDecl>(MD)) {
+ emitCXXConstructor(CGM, CD, Type);
+ return;
+ }
+ emitCXXDestructor(CGM, cast<CXXDestructorDecl>(MD), Type);
+}
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=217807&r1=217806&r2=217807&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Mon Sep 15 14:20:10 2014
@@ -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<const CXXRecordDecl *, CharUnits> VFTableIdTy;
typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
@@ -2870,3 +2872,80 @@ MicrosoftCXXABI::getMSCompleteObjectLoca
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<llvm::Function>(
+ 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<llvm::Function>(
+ 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<CXXConstructorDecl>(MD)) {
+ emitCXXConstructor(CGM, CD, Type);
+ return;
+ }
+ emitCXXDestructor(CGM, cast<CXXDestructorDecl>(MD), Type);
+}
More information about the cfe-commits
mailing list