CodeGen: Clean up CommonLinkage calculation
No functionality change. llvm-svn: 205972
This commit is contained in:
parent
cd3bb59aa2
commit
9832a3d1e0
|
@ -1928,6 +1928,34 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
|
|||
DI->EmitGlobalVariable(GV, D);
|
||||
}
|
||||
|
||||
static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
|
||||
// Don't give variables common linkage if -fno-common was specified unless it
|
||||
// was overridden by a NoCommon attribute.
|
||||
if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
|
||||
return true;
|
||||
|
||||
// C11 6.9.2/2:
|
||||
// A declaration of an identifier for an object that has file scope without
|
||||
// an initializer, and without a storage-class specifier or with the
|
||||
// storage-class specifier static, constitutes a tentative definition.
|
||||
if (D->getInit() || D->hasExternalStorage())
|
||||
return true;
|
||||
|
||||
// A variable cannot be both common and exist in a section.
|
||||
if (D->hasAttr<SectionAttr>())
|
||||
return true;
|
||||
|
||||
// Thread local vars aren't considered common linkage.
|
||||
if (D->getTLSKind())
|
||||
return true;
|
||||
|
||||
// Tentative definitions marked with WeakImportAttr are true definitions.
|
||||
if (D->hasAttr<WeakImportAttr>())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::GlobalValue::LinkageTypes
|
||||
CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) {
|
||||
GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
|
||||
|
@ -1950,21 +1978,18 @@ CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) {
|
|||
return llvm::GlobalVariable::WeakAnyLinkage;
|
||||
} else if (Linkage == GVA_TemplateInstantiation || Linkage == GVA_StrongODR)
|
||||
return llvm::GlobalVariable::WeakODRLinkage;
|
||||
else if (!getLangOpts().CPlusPlus &&
|
||||
((!CodeGenOpts.NoCommon && !D->hasAttr<NoCommonAttr>()) ||
|
||||
D->hasAttr<CommonAttr>()) &&
|
||||
!D->hasExternalStorage() && !D->getInit() &&
|
||||
!D->hasAttr<SectionAttr>() && !D->getTLSKind() &&
|
||||
!D->hasAttr<WeakImportAttr>()) {
|
||||
// Thread local vars aren't considered common linkage.
|
||||
return llvm::GlobalVariable::CommonLinkage;
|
||||
} else if (D->getTLSKind() == VarDecl::TLS_Dynamic &&
|
||||
getTarget().getTriple().isMacOSX())
|
||||
else if (D->getTLSKind() == VarDecl::TLS_Dynamic &&
|
||||
getTarget().getTriple().isMacOSX())
|
||||
// On Darwin, the backing variable for a C++11 thread_local variable always
|
||||
// has internal linkage; all accesses should just be calls to the
|
||||
// Itanium-specified entry point, which has the normal linkage of the
|
||||
// variable.
|
||||
return llvm::GlobalValue::InternalLinkage;
|
||||
// C++ doesn't have tentative definitions and thus cannot have common linkage.
|
||||
else if (!getLangOpts().CPlusPlus &&
|
||||
!isVarDeclStrongDefinition(D, CodeGenOpts.NoCommon))
|
||||
return llvm::GlobalVariable::CommonLinkage;
|
||||
|
||||
return llvm::GlobalVariable::ExternalLinkage;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue