forked from OSchip/llvm-project
Move emitCXXStructor to CGCXXABI.
A followup patch will address the code duplication. llvm-svn: 217807
This commit is contained in:
parent
33d585cb25
commit
91f68b43c3
|
@ -196,37 +196,6 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
|
||||||
return false;
|
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(
|
llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor(
|
||||||
const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo,
|
const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo,
|
||||||
llvm::FunctionType *FnType, bool DontDefer) {
|
llvm::FunctionType *FnType, bool DontDefer) {
|
||||||
|
@ -253,52 +222,6 @@ llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor(
|
||||||
DontDefer));
|
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,
|
static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
|
||||||
GlobalDecl GD,
|
GlobalDecl GD,
|
||||||
llvm::Type *Ty,
|
llvm::Type *Ty,
|
||||||
|
|
|
@ -504,6 +504,10 @@ public:
|
||||||
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
|
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
|
||||||
const VarDecl *VD,
|
const VarDecl *VD,
|
||||||
QualType LValType);
|
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:
|
// Create an instance of a C++ ABI class:
|
||||||
|
|
|
@ -1404,9 +1404,9 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
|
||||||
// Make sure to emit the definition(s) before we emit the thunks.
|
// Make sure to emit the definition(s) before we emit the thunks.
|
||||||
// This is necessary for the generation of certain thunks.
|
// This is necessary for the generation of certain thunks.
|
||||||
if (const auto *CD = dyn_cast<CXXConstructorDecl>(Method))
|
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))
|
else if (const auto *DD = dyn_cast<CXXDestructorDecl>(Method))
|
||||||
emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
|
ABI->emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
|
||||||
else
|
else
|
||||||
EmitGlobalFunctionDefinition(GD, GV);
|
EmitGlobalFunctionDefinition(GD, GV);
|
||||||
|
|
||||||
|
|
|
@ -1091,10 +1091,6 @@ private:
|
||||||
void EmitLinkageSpec(const LinkageSpecDecl *D);
|
void EmitLinkageSpec(const LinkageSpecDecl *D);
|
||||||
void CompleteDIClassType(const CXXMethodDecl* 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.
|
/// \brief Emit the function that initializes C++ thread_local variables.
|
||||||
void EmitCXXThreadLocalInitFunc();
|
void EmitCXXThreadLocalInitFunc();
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,8 @@ public:
|
||||||
classifyRTTIUniqueness(QualType CanTy,
|
classifyRTTIUniqueness(QualType CanTy,
|
||||||
llvm::GlobalValue::LinkageTypes Linkage) const;
|
llvm::GlobalValue::LinkageTypes Linkage) const;
|
||||||
friend class ItaniumRTTIBuilder;
|
friend class ItaniumRTTIBuilder;
|
||||||
|
|
||||||
|
void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ARMCXXABI : public ItaniumCXXABI {
|
class ARMCXXABI : public ItaniumCXXABI {
|
||||||
|
@ -2996,3 +2998,80 @@ ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
|
||||||
assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
|
assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
|
||||||
return RUK_NonUniqueVisible;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -525,6 +525,8 @@ public:
|
||||||
llvm::Value *&This, llvm::Value *MemPtr,
|
llvm::Value *&This, llvm::Value *MemPtr,
|
||||||
const MemberPointerType *MPT) override;
|
const MemberPointerType *MPT) override;
|
||||||
|
|
||||||
|
void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
|
typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
|
||||||
typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
|
typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
|
||||||
|
@ -2870,3 +2872,80 @@ MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
|
||||||
const VPtrInfo *Info) {
|
const VPtrInfo *Info) {
|
||||||
return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue