Restore r117644, this time properly ignoring -fvisibility and type visibility

for namespace-scope variable declarations.

Apply visibility in IR gen to variables that are merely declared
and never defined.  We were previously emitting these with default
visibility unless they were declared with private_extern.

Ignore global visibility settings when computing visibility for
a declaration's context, and key several conditions on whether a
visibility attribute exists anywhere in the hierarchy as opposed
to whether it exists at the current level.

llvm-svn: 117729
This commit is contained in:
John McCall
2010-10-29 22:22:43 +00:00
parent 67a6f32c59
commit 37bb6c9832
4 changed files with 212 additions and 64 deletions

View File

@@ -164,6 +164,17 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type,
getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
}
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) {
switch (V) {
case DefaultVisibility: return llvm::GlobalValue::DefaultVisibility;
case HiddenVisibility: return llvm::GlobalValue::HiddenVisibility;
case ProtectedVisibility: return llvm::GlobalValue::ProtectedVisibility;
}
llvm_unreachable("unknown visibility!");
return llvm::GlobalValue::DefaultVisibility;
}
void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
const NamedDecl *D) const {
// Internal definitions always have default visibility.
@@ -172,15 +183,7 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
return;
}
switch (D->getVisibility()) {
case DefaultVisibility:
return GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
case HiddenVisibility:
return GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
case ProtectedVisibility:
return GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
}
llvm_unreachable("unknown visibility!");
GV->setVisibility(GetLLVMVisibility(D->getVisibility()));
}
/// Set the symbol visibility of type information (vtable and RTTI)
@@ -934,15 +937,18 @@ CodeGenModule::GetOrCreateLLVMGlobal(llvm::StringRef MangledName,
// handling.
GV->setConstant(DeclIsConstantGlobal(Context, D));
// FIXME: Merge with other attribute handling code.
if (D->getStorageClass() == SC_PrivateExtern)
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
// Set linkage and visibility in case we never see a definition.
std::pair<Linkage,Visibility> LV = D->getLinkageAndVisibility();
if (LV.first != ExternalLinkage) {
GV->setLinkage(llvm::GlobalValue::InternalLinkage);
} else {
if (D->hasAttr<DLLImportAttr>())
GV->setLinkage(llvm::GlobalValue::DLLImportLinkage);
else if (D->hasAttr<WeakAttr>() || D->hasAttr<WeakImportAttr>())
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
if (D->hasAttr<DLLImportAttr>())
GV->setLinkage(llvm::GlobalValue::DLLImportLinkage);
else if (D->hasAttr<WeakAttr>() ||
D->hasAttr<WeakImportAttr>())
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
GV->setVisibility(GetLLVMVisibility(LV.second));
}
GV->setThreadLocal(D->isThreadSpecified());
}