diff options
author | John McCall <rjmccall@apple.com> | 2010-10-26 04:59:26 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-10-26 04:59:26 +0000 |
commit | ac65c6208d48b0f9b4661c30c28997a280ac5ba6 (patch) | |
tree | ead6d222141d69c1252b787ec497789c559be297 /lib/AST/Decl.cpp | |
parent | 1235b0ebb16618bf41a9e7234d5e2690faf97d37 (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.cpp | 14 |
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)) { |