aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp80
1 files changed, 44 insertions, 36 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 2f8a17afbcd1..545c5ef9f827 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -35,7 +35,7 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
return true;
// Producing an alias to a base class ctor/dtor can degrade debug quality
- // as the debugger cannot tell them appart.
+ // as the debugger cannot tell them apart.
if (getCodeGenOpts().OptimizationLevel == 0)
return true;
@@ -44,6 +44,10 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
if (!D->hasTrivialBody())
return true;
+ // For exported destructors, we need a full definition.
+ if (D->hasAttr<DLLExportAttr>())
+ return true;
+
const CXXRecordDecl *Class = D->getParent();
// If we need to manipulate a VTT parameter, give up.
@@ -56,22 +60,20 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
// If any field has a non-trivial destructor, we have to emit the
// destructor separately.
- for (CXXRecordDecl::field_iterator I = Class->field_begin(),
- E = Class->field_end(); I != E; ++I)
+ for (const auto *I : Class->fields())
if (I->getType().isDestructedType())
return true;
// Try to find a unique base class with a non-trivial destructor.
- const CXXRecordDecl *UniqueBase = 0;
- for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
- E = Class->bases_end(); I != E; ++I) {
+ const CXXRecordDecl *UniqueBase = nullptr;
+ for (const auto &I : Class->bases()) {
// We're in the base destructor, so skip virtual bases.
- if (I->isVirtual()) continue;
+ if (I.isVirtual()) continue;
// Skip base classes with trivial destructors.
- const CXXRecordDecl *Base
- = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ const auto *Base =
+ cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
if (Base->hasTrivialDestructor()) continue;
// If we've already found a base class with a non-trivial
@@ -113,7 +115,7 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
if (!getCodeGenOpts().CXXCtorDtorAliases)
return true;
- // The alias will use the linkage of the referrent. If we can't
+ // The alias will use the linkage of the referent. If we can't
// support aliases with that linkage, fail.
llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
@@ -136,20 +138,20 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
llvm::PointerType *AliasType
= getTypes().GetFunctionType(AliasDecl)->getPointerTo();
- // Find the referrent. Some aliases might require a bitcast, in
+ // Find the referent. Some aliases might require a bitcast, in
// which case the caller is responsible for ensuring the soundness
// of these semantics.
- llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
+ auto *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
llvm::Constant *Aliasee = Ref;
if (Ref->getType() != AliasType)
Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType);
// Instead of creating as alias to a linkonce_odr, replace all of the uses
- // of the aliassee.
+ // of the aliasee.
if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) &&
(TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage ||
!TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) {
- // FIXME: An extern template instanciation will create functions with
+ // FIXME: An extern template instantiation will create functions with
// linkage "AvailableExternally". In libc++, some classes also define
// members with attribute "AlwaysInline" and expect no reference to
// be generated. It is desirable to reenable this optimisation after
@@ -174,8 +176,8 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
return true;
// Create the alias with no name.
- llvm::GlobalAlias *Alias =
- new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
+ auto *Alias = llvm::GlobalAlias::create(AliasType->getElementType(), 0,
+ Linkage, "", Aliasee, &getModule());
// Switch any previous uses to the alias.
if (Entry) {
@@ -196,11 +198,13 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor,
CXXCtorType ctorType) {
- // The complete constructor is equivalent to the base constructor
- // for classes with no virtual bases. Try to emit it as an alias.
- if (getTarget().getCXXABI().hasConstructorVariants() &&
- !ctor->getParent()->getNumVBases() &&
- (ctorType == Ctor_Complete || ctorType == Ctor_Base)) {
+ if (!getTarget().getCXXABI().hasConstructorVariants()) {
+ // If there are no constructor variants, always emit the complete destructor.
+ ctorType = Ctor_Complete;
+ } else if (!ctor->getParent()->getNumVBases() &&
+ (ctorType == Ctor_Complete || ctorType == Ctor_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 =
!TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete),
GlobalDecl(ctor, Ctor_Base), true);
@@ -211,20 +215,21 @@ void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor,
const CGFunctionInfo &fnInfo =
getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType);
- llvm::Function *fn =
- cast<llvm::Function>(GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo));
+ auto *fn = cast<llvm::Function>(
+ GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo, true));
setFunctionLinkage(GlobalDecl(ctor, ctorType), fn);
CodeGenFunction(*this).GenerateCode(GlobalDecl(ctor, ctorType), fn, fnInfo);
- SetFunctionDefinitionAttributes(ctor, fn);
+ setFunctionDefinitionAttributes(ctor, fn);
SetLLVMFunctionAttributesForDefinition(ctor, fn);
}
llvm::GlobalValue *
CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,
CXXCtorType ctorType,
- const CGFunctionInfo *fnInfo) {
+ const CGFunctionInfo *fnInfo,
+ bool DontDefer) {
GlobalDecl GD(ctor, ctorType);
StringRef name = getMangledName(GD);
@@ -236,7 +241,8 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,
llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo);
return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
- /*ForVTable=*/false));
+ /*ForVTable=*/false,
+ DontDefer));
}
void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,
@@ -266,13 +272,13 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,
const CGFunctionInfo &fnInfo =
getTypes().arrangeCXXDestructor(dtor, dtorType);
- llvm::Function *fn =
- cast<llvm::Function>(GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo));
+ auto *fn = cast<llvm::Function>(
+ GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo, nullptr, true));
setFunctionLinkage(GlobalDecl(dtor, dtorType), fn);
CodeGenFunction(*this).GenerateCode(GlobalDecl(dtor, dtorType), fn, fnInfo);
- SetFunctionDefinitionAttributes(dtor, fn);
+ setFunctionDefinitionAttributes(dtor, fn);
SetLLVMFunctionAttributesForDefinition(dtor, fn);
}
@@ -280,7 +286,8 @@ llvm::GlobalValue *
CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
const CGFunctionInfo *fnInfo,
- llvm::FunctionType *fnType) {
+ llvm::FunctionType *fnType,
+ bool DontDefer) {
GlobalDecl GD(dtor, dtorType);
StringRef name = getMangledName(GD);
@@ -292,7 +299,8 @@ CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
fnType = getTypes().GetFunctionType(*fnInfo);
}
return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
- /*ForVTable=*/false));
+ /*ForVTable=*/false,
+ DontDefer));
}
static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
@@ -331,9 +339,9 @@ CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
QualType T = QualType(QTy, 0);
const RecordType *RT = T->getAs<RecordType>();
assert(RT && "BuildAppleKextVirtualCall - Qual type must be record");
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-
- if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
+ const auto *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+ if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD))
return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD);
return ::BuildAppleKextVirtualCall(*this, MD, Ty, RD);
@@ -346,7 +354,7 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall(
const CXXDestructorDecl *DD,
CXXDtorType Type,
const CXXRecordDecl *RD) {
- const CXXMethodDecl *MD = cast<CXXMethodDecl>(DD);
+ const auto *MD = cast<CXXMethodDecl>(DD);
// FIXME. Dtor_Base dtor is always direct!!
// It need be somehow inline expanded into the caller.
// -O does that. But need to support -O0 as well.
@@ -357,5 +365,5 @@ CodeGenFunction::BuildAppleKextVirtualDestructorCall(
llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo);
return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD);
}
- return 0;
+ return nullptr;
}