aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-10-26 04:59:26 +0000
committerJohn McCall <rjmccall@apple.com>2010-10-26 04:59:26 +0000
commitac65c6208d48b0f9b4661c30c28997a280ac5ba6 (patch)
treeead6d222141d69c1252b787ec497789c559be297 /lib/AST/Decl.cpp
parent1235b0ebb16618bf41a9e7234d5e2690faf97d37 (diff)
A couple of tweaks to the visibility rules:
- tags with C linkage should ignore visibility=hidden - functions and variables with explicit visibility attributes should ignore the linkage of their types Either of these should be sufficient to fix PR8457. Also, FileCheck-ize a test case. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117351 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 42e762d56a..5cc745d40d 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -212,9 +212,13 @@ static LVPair getLVForNamespaceScopeDecl(const NamedDecl *D) {
// given variable or function shall be identical...
// C does not have an equivalent rule.
//
+ // Ignore this if we've got an explicit attribute; the user
+ // probably knows what they're doing.
+ //
// Note that we don't want to make the variable non-external
// because of this, but unique-external linkage suits us.
- if (Context.getLangOptions().CPlusPlus && !Var->isExternC()) {
+ if (Context.getLangOptions().CPlusPlus && !Var->isExternC() &&
+ !Var->hasAttr<VisibilityAttr>()) {
LVPair TypeLV = Var->getType()->getLinkageAndVisibility();
if (TypeLV.first != ExternalLinkage)
return LVPair(UniqueExternalLinkage, DefaultVisibility);
@@ -247,7 +251,8 @@ static LVPair getLVForNamespaceScopeDecl(const NamedDecl *D) {
} else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// Modify the function's LV by the LV of its type unless this is
// C or extern "C". See the comment above about variables.
- if (Context.getLangOptions().CPlusPlus && !Function->isExternC()) {
+ if (Context.getLangOptions().CPlusPlus && !Function->isExternC() &&
+ !Function->hasAttr<VisibilityAttr>()) {
LVPair TypeLV = Function->getType()->getLinkageAndVisibility();
if (TypeLV.first != ExternalLinkage)
return LVPair(UniqueExternalLinkage, DefaultVisibility);
@@ -321,8 +326,11 @@ static LVPair getLVForNamespaceScopeDecl(const NamedDecl *D) {
ConsiderDashFVisibility = false;
}
+ // Consider -fvisibility unless the type has C linkage.
if (ConsiderDashFVisibility)
- ConsiderDashFVisibility = Tag->isDefinition();
+ ConsiderDashFVisibility =
+ (Context.getLangOptions().CPlusPlus &&
+ !Tag->getDeclContext()->isExternCContext());
// - an enumerator belonging to an enumeration with external linkage;
} else if (isa<EnumConstantDecl>(D)) {