[cfe-commits] r121459 - in /cfe/trunk: include/clang/Sema/Sema.h lib/AST/Decl.cpp lib/Sema/SemaAttr.cpp lib/Sema/SemaDeclCXX.cpp test/CodeGenCXX/pragma-visibility.cpp test/CodeGenCXX/visibility-inlines-hidden.cpp

John McCall rjmccall at apple.com
Thu Dec 9 18:59:44 PST 2010


Author: rjmccall
Date: Thu Dec  9 20:59:44 2010
New Revision: 121459

URL: http://llvm.org/viewvc/llvm-project?rev=121459&view=rev
Log:
Treat visibility on an enclosing namespace as a non-explicit source of
visibility.  Fixes PR8713.

I've disabled a test which was testing that you can #pragma pop visibility
to get out of a namespace's visibility attribute.  We should probably just
diagnose that as an error unless it's instrumental to someone's system
headers.


Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CodeGenCXX/pragma-visibility.cpp
    cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=121459&r1=121458&r2=121459&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Dec  9 20:59:44 2010
@@ -3957,9 +3957,9 @@
   /// FreePackedContext - Deallocate and null out PackContext.
   void FreePackedContext();
 
-  /// PushVisibilityAttr - Note that we've entered a context with a
-  /// visibility attribute.
-  void PushVisibilityAttr(const VisibilityAttr *Attr);
+  /// PushNamespaceVisibilityAttr - Note that we've entered a
+  /// namespace with a visibility attribute.
+  void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr);
 
   /// AddPushedVisibilityAttribute - If '#pragma GCC visibility' was used,
   /// add an appropriate visibility attribute.

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=121459&r1=121458&r2=121459&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Thu Dec  9 20:59:44 2010
@@ -249,6 +249,20 @@
     if (const VisibilityAttr *VA = GetExplicitVisibility(D)) {
       LV.setVisibility(GetVisibilityFromAttr(VA), 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()) {
+        if (!isa<NamespaceDecl>(DC)) continue;
+        if (const VisibilityAttr *VA =
+              cast<NamespaceDecl>(DC)->getAttr<VisibilityAttr>()) {
+          LV.setVisibility(GetVisibilityFromAttr(VA), false);
+          F.ConsiderGlobalVisibility = false;
+          break;
+        }
+      }
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=121459&r1=121458&r2=121459&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Thu Dec  9 20:59:44 2010
@@ -296,8 +296,8 @@
   }
 }
 
-typedef std::vector<std::pair<VisibilityAttr::VisibilityType,
-                              SourceLocation> > VisStack;
+typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
+enum { NoVisibility = (unsigned) -1 };
 
 void Sema::AddPushedVisibilityAttribute(Decl *D) {
   if (!VisContext)
@@ -307,7 +307,11 @@
     return;
 
   VisStack *Stack = static_cast<VisStack*>(VisContext);
-  VisibilityAttr::VisibilityType type = Stack->back().first;
+  unsigned rawType = Stack->back().first;
+  if (rawType == NoVisibility) return;
+
+  VisibilityAttr::VisibilityType type
+    = (VisibilityAttr::VisibilityType) rawType;
   SourceLocation loc = Stack->back().second;
 
   D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
@@ -319,8 +323,7 @@
   VisContext = 0;
 }
 
-static void PushPragmaVisibility(Sema &S, VisibilityAttr::VisibilityType type,
-                                 SourceLocation loc) {
+static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
   // Put visibility on stack.
   if (!S.VisContext)
     S.VisContext = new VisStack;
@@ -353,8 +356,12 @@
   }
 }
 
-void Sema::PushVisibilityAttr(const VisibilityAttr *Attr) {
-  PushPragmaVisibility(*this, Attr->getVisibility(), Attr->getLocation());
+void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr) {
+  // Visibility calculations will consider the namespace's visibility.
+  // Here we just want to note that we're in a visibility context
+  // which overrides any enclosing #pragma context, but doesn't itself
+  // contribute visibility.
+  PushPragmaVisibility(*this, NoVisibility, SourceLocation());
 }
 
 void Sema::PopPragmaVisibility() {

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=121459&r1=121458&r2=121459&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Dec  9 20:59:44 2010
@@ -3194,8 +3194,8 @@
 
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
 
-  if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
-    PushVisibilityAttr(attr);
+  if (const VisibilityAttr *Attr = Namespc->getAttr<VisibilityAttr>())
+    PushNamespaceVisibilityAttr(Attr);
 
   if (II) {
     // C++ [namespace.def]p2:

Modified: cfe/trunk/test/CodeGenCXX/pragma-visibility.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pragma-visibility.cpp?rev=121459&r1=121458&r2=121459&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pragma-visibility.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/pragma-visibility.cpp Thu Dec  9 20:59:44 2010
@@ -63,10 +63,12 @@
 #pragma GCC visibility pop
 }
 
+// We used to test this, but it's insane, so unless it happens in
+// headers, we should not support it.
 namespace n __attribute((visibility("hidden"))) {
   extern int foofoo; // FIXME: Shouldn't be necessary, but otherwise the pragma
                      //        gets to Sema before the namespace!
   #pragma GCC visibility pop
   void h() {}
-  // CHECK: define void @_ZN1n1hEv
+  // CHECK disabled: define void @_ZN1n1hEv
 }

Modified: cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp?rev=121459&r1=121458&r2=121459&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/visibility-inlines-hidden.cpp Thu Dec  9 20:59:44 2010
@@ -79,3 +79,21 @@
 // CHECK: declare void @_ZN5test11A3fooEv
 // CHECK: declare void @_ZN5test11AD1Ev
 }
+
+// PR8713
+namespace test2 {
+  struct A {};
+  template <class T> class B {};
+  typedef B<A> arg;
+
+  namespace ns __attribute__((visibility("default"))) {
+    template <class T> inline void foo() {}
+    extern template void foo<arg>();
+  }
+
+  void test() {
+    ns::foo<arg>();
+  }
+
+  // CHECK: define available_externally void @_ZN5test22ns3fooINS_1BINS_1AEEEEEvv()
+}





More information about the cfe-commits mailing list