: StaticLocalLinkage;
}
- // 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.
- if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
- Context.getTargetInfo().getTriple().isMacOSX())
- return GVA_Internal;
-
switch (VD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
// Set the llvm linkage type as appropriate.
llvm::GlobalValue::LinkageTypes Linkage =
getLLVMLinkageVarDefinition(D, GV->isConstant());
+
+ // 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.
+ if (const auto *VD = dyn_cast<VarDecl>(D))
+ if (!VD->isStaticLocal() && VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+ Context.getTargetInfo().getTriple().isMacOSX())
+ Linkage = llvm::GlobalValue::InternalLinkage;
+
GV->setLinkage(Linkage);
if (D->hasAttr<DLLImportAttr>())
GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
/// Get the appropriate linkage for the wrapper function. This is essentially
/// the weak form of the variable's linkage; every translation unit which wneeds
/// the wrapper emits a copy, and we want the linker to merge them.
-static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(
- llvm::GlobalValue::LinkageTypes VarLinkage) {
+static llvm::GlobalValue::LinkageTypes
+getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
+ llvm::GlobalValue::LinkageTypes VarLinkage =
+ CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false);
+
// For internal linkage variables, we don't need an external or weak wrapper.
if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
return VarLinkage;
+
+ // All accesses to the thread_local variable go through the thread wrapper.
+ // However, this means that we cannot allow the thread wrapper to get inlined
+ // into any functions.
+ if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+ CGM.getTarget().getTriple().isMacOSX())
+ return llvm::GlobalValue::WeakAnyLinkage;
return llvm::GlobalValue::WeakODRLinkage;
}
RetTy = RetTy->getPointerElementType();
llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false);
- llvm::Function *Wrapper = llvm::Function::Create(
- FnTy, getThreadLocalWrapperLinkage(
- CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false)),
- WrapperName.str(), &CGM.getModule());
+ llvm::Function *Wrapper =
+ llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),
+ WrapperName.str(), &CGM.getModule());
// Always resolve references to the wrapper at link time.
if (!Wrapper->hasLocalLinkage())
Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);