aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-10-30 09:18:49 +0000
committerJohn McCall <rjmccall@apple.com>2010-10-30 09:18:49 +0000
commitee30102a9ef32cdbf0afe0e4c07a53d265a18f98 (patch)
tree9096eabecf5823d218bdea2988971ad2bd4cc727 /lib/AST/Decl.cpp
parentd99d0e8276dd320deaee02824602bc335ea1c770 (diff)
GCC faithfully calculates visibility for variables independently of
whether it's a declaration or not, then ignores that information for declarations unless it was explicitly given. It's not totally clear how that should be mapped into a sane system, but make an effort. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117780 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp42
1 files changed, 19 insertions, 23 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index dbd14e067a..2d29a6a9ca 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -255,21 +255,17 @@ static LVPair getLVForNamespaceScopeDecl(const NamedDecl *D,
//
// 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 && !ExplicitVisibility &&
- !Var->isExternC()) {
+ if (Context.getLangOptions().CPlusPlus && !Var->isExternC()) {
LVPair TypeLV = Var->getType()->getLinkageAndVisibility();
if (TypeLV.first != ExternalLinkage)
return LVPair(UniqueExternalLinkage, DefaultVisibility);
-
- // Otherwise, ignore type visibility for declarations.
- if (!isDeclaration)
+ if (!isDeclaration && !ExplicitVisibility)
LV.second = minVisibility(LV.second, TypeLV.second);
}
// Don't consider -fvisibility for pure declarations.
- if (isDeclaration) {
+ if (isDeclaration)
ConsiderGlobalVisibility = false;
- }
if (!Context.getLangOptions().CPlusPlus &&
(Var->getStorageClass() == SC_Extern ||
@@ -524,24 +520,24 @@ static LVPair getLVForClassMember(const NamedDecl *D,
// Static data members.
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- // If we don't have explicit visibility information in the
- // hierarchy, apply the LV from its type. See the comment about
- // namespace-scope variables for justification for this
- // optimization.
- if (!HasExplicitVisibility) {
- LVPair TypeLV = VD->getType()->getLinkageAndVisibility();
- if (TypeLV.first != ExternalLinkage)
- LV.first = minLinkage(LV.first, UniqueExternalLinkage);
- LV.second = minVisibility(LV.second, TypeLV.second);
+ bool IsDefinition = (VD->getDefinition() &&
+ VD->getTemplateSpecializationKind()
+ != TSK_ExplicitInstantiationDeclaration);
+
+ // GCC just ignores the visibility of a variable declaration
+ // unless it's explicit.
+ if (!IsDefinition && !HasExplicitVisibility) {
+ LV.second = DefaultVisibility;
+ ConsiderGlobalVisibility = false;
}
- // Ignore global visibility if it's an extern template or
- // just a declaration.
- if (ConsiderGlobalVisibility)
- ConsiderGlobalVisibility =
- (VD->getDefinition() &&
- VD->getTemplateSpecializationKind()
- != TSK_ExplicitInstantiationDeclaration);
+ // Modify the variable's linkage by its type, but ignore the
+ // type's visibility unless it's a definition.
+ LVPair TypeLV = VD->getType()->getLinkageAndVisibility();
+ if (TypeLV.first != ExternalLinkage)
+ LV.first = minLinkage(LV.first, UniqueExternalLinkage);
+ if (IsDefinition && !HasExplicitVisibility)
+ LV.second = minVisibility(LV.second, TypeLV.second);
}
// Suppress -fvisibility if we have explicit visibility on any of