]> granicus.if.org Git - clang/commitdiff
GCC faithfully calculates visibility for variables independently of
authorJohn McCall <rjmccall@apple.com>
Sat, 30 Oct 2010 09:18:49 +0000 (09:18 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 30 Oct 2010 09:18:49 +0000 (09:18 +0000)
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

lib/AST/Decl.cpp
test/CodeGenCXX/visibility.cpp

index dbd14e067a36ddbbb3552f2ffc6d1c2a77594498..2d29a6a9cab2539bb991ffa0be29b3b79ad445a4 100644 (file)
@@ -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
index a55544573de909397ee918065fef5fb326f74dca..2272d1fa5e4f0325dcbf9b96f9051cc22d92afe9 100644 (file)
@@ -20,6 +20,8 @@
 // CHECK-HIDDEN: @_ZN6Test131C1aE = global
 // CHECK: @_ZN6Test143varE = external global
 // CHECK-HIDDEN: @_ZN6Test143varE = external global
+// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
+// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
 // CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant 
 
 namespace Test1 {
@@ -218,3 +220,17 @@ namespace Test14 {
 
   struct A *test() { return var; }
 }
+
+// rdar://problem/8613093
+namespace Test15 {
+  struct A {};
+  template <class T> struct Temp {
+    struct Inner {
+      static char buffer[0];
+    };
+  };
+
+  char *test() {
+    return Temp<A>::Inner::buffer;
+  }
+}