diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-04-14 15:21:19 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-04-14 15:21:19 +0000 |
commit | 767f7c7558779e7feb4fe10960726dbf01e69a9f (patch) | |
tree | 4485f7093c59a1155b46d002ad3b1cfd4e719739 | |
parent | 8fb9fb66d415ee40447277f649ecdb12b4964385 (diff) |
Consider visibility attributes last, so that they take precedence.
I am working on a cleaner fix, but this gets the case in PR12552 passing.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154749 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/Decl.cpp | 42 | ||||
-rw-r--r-- | test/CodeGenCXX/visibility.cpp | 12 |
2 files changed, 33 insertions, 21 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 399f2e48ab..7d608a3ba8 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -281,27 +281,6 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { LinkageInfo LV; LV.mergeVisibility(Context.getLangOpts().getVisibilityMode()); - if (F.ConsiderVisibilityAttributes) { - if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) { - LV.setVisibility(*Vis, true); - F.ConsiderGlobalVisibility = false; - } else { - // If we're declared in a namespace with a visibility attribute, - // use that namespace's visibility, but don't call it explicit. - for (const DeclContext *DC = D->getDeclContext(); - !isa<TranslationUnitDecl>(DC); - DC = DC->getParent()) { - const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC); - if (!ND) continue; - if (llvm::Optional<Visibility> Vis = ND->getExplicitVisibility()) { - LV.setVisibility(*Vis, true); - F.ConsiderGlobalVisibility = false; - break; - } - } - } - } - // C++ [basic.link]p4: // A name having namespace scope has external linkage if it is the @@ -478,6 +457,27 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) { return LinkageInfo::none(); } + if (F.ConsiderVisibilityAttributes) { + if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) { + LV.setVisibility(*Vis, true); + F.ConsiderGlobalVisibility = false; + } else { + // If we're declared in a namespace with a visibility attribute, + // use that namespace's visibility, but don't call it explicit. + for (const DeclContext *DC = D->getDeclContext(); + !isa<TranslationUnitDecl>(DC); + DC = DC->getParent()) { + const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC); + if (!ND) continue; + if (llvm::Optional<Visibility> Vis = ND->getExplicitVisibility()) { + LV.setVisibility(*Vis, true); + F.ConsiderGlobalVisibility = false; + break; + } + } + } + } + // If we ended up with non-external linkage, visibility should // always be default. if (LV.linkage() != ExternalLinkage) diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp index 59fd7c26f0..88a456fe57 100644 --- a/test/CodeGenCXX/visibility.cpp +++ b/test/CodeGenCXX/visibility.cpp @@ -28,6 +28,18 @@ namespace test28 { // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global } +namespace test29 { +#pragma GCC visibility push(hidden) + struct RECT { + int top; + }; + __attribute__ ((visibility ("default"))) extern RECT data_rect; + RECT data_rect = { -1}; +#pragma GCC visibility pop + // CHECK: @_ZN6test299data_rectE = global + // CHECK-HIDDEN: @_ZN6test299data_rectE = global +} + // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 // CHECK: @_ZN5Test71aE = hidden global // CHECK: @_ZN5Test71bE = global |