summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/ItaniumCXXABI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/ItaniumCXXABI.cpp')
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index bcc0f166203..877d32cc5f8 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/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<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);
+}
OpenPOWER on IntegriCloud