]> granicus.if.org Git - clang/commitdiff
Don't consider visibility from template parameter lists if we're
authorJohn McCall <rjmccall@apple.com>
Fri, 4 Mar 2011 10:39:25 +0000 (10:39 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 4 Mar 2011 10:39:25 +0000 (10:39 +0000)
computing for a nested decl with explicit visibility.  This is all part
of the general philosophy of explicit visibility attributes, where
any information that was obviously available at the attribute site
should probably be ignored.  Fixes PR9371.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126992 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 6dd47077f3a110f7d7ee667664ef6fa7cdf5560e..cc33d84c94987ed53bdef9783d929f9ba774418c 100644 (file)
@@ -100,9 +100,11 @@ namespace {
 struct LVFlags {
   bool ConsiderGlobalVisibility;
   bool ConsiderVisibilityAttributes;
+  bool ConsiderTemplateParameterTypes;
 
   LVFlags() : ConsiderGlobalVisibility(true), 
-              ConsiderVisibilityAttributes(true) {
+              ConsiderVisibilityAttributes(true),
+              ConsiderTemplateParameterTypes(true) {
   }
 
   /// \brief Returns a set of flags that is only useful for computing the 
@@ -111,6 +113,7 @@ struct LVFlags {
     LVFlags F;
     F.ConsiderGlobalVisibility = false;
     F.ConsiderVisibilityAttributes = false;
+    F.ConsiderTemplateParameterTypes = false;
     return F;
   }
   
@@ -120,6 +123,7 @@ struct LVFlags {
     LVFlags F = *this;
     F.ConsiderGlobalVisibility = false;
     F.ConsiderVisibilityAttributes = false;
+    F.ConsiderTemplateParameterTypes = false;
     return F;
   }
 }; 
@@ -451,8 +455,9 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, LVFlags F) {
 
   //     - a template, unless it is a function template that has
   //       internal linkage (Clause 14);
-  } else if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
-    LV.merge(getLVForTemplateParameterList(Template->getTemplateParameters()));
+  } else if (const TemplateDecl *temp = dyn_cast<TemplateDecl>(D)) {
+    if (F.ConsiderTemplateParameterTypes)
+      LV.merge(getLVForTemplateParameterList(temp->getTemplateParameters()));
 
   //     - a namespace (7.3), unless it is declared within an unnamed
   //       namespace.
@@ -536,7 +541,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
     if (FunctionTemplateSpecializationInfo *Spec
            = MD->getTemplateSpecializationInfo()) {
       LV.merge(getLVForTemplateArgumentList(*Spec->TemplateArguments, F));
-      LV.merge(getLVForTemplateParameterList(
+      if (F.ConsiderTemplateParameterTypes)
+        LV.merge(getLVForTemplateParameterList(
                               Spec->getTemplate()->getTemplateParameters()));
 
       TSK = Spec->getTemplateSpecializationKind();
@@ -571,7 +577,8 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, LVFlags F) {
       // Merge template argument/parameter information for member
       // class template specializations.
       LV.merge(getLVForTemplateArgumentList(Spec->getTemplateArgs(), F));
-      LV.merge(getLVForTemplateParameterList(
+      if (F.ConsiderTemplateParameterTypes)
+        LV.merge(getLVForTemplateParameterList(
                     Spec->getSpecializedTemplate()->getTemplateParameters()));
     }
 
index 931465060b6204b4f0382a7daa7819a21846e7cf..7644e47ff7801af2892ba69ef6cbff191363ab3e 100644 (file)
@@ -411,3 +411,14 @@ namespace Test20 {
     B<A<2> >::test5();
   }
 }
+
+// PR9371
+namespace test21 {
+  enum En { en };
+  template<En> struct A {
+    __attribute__((visibility("default"))) void foo() {}
+  };
+
+  // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
+  template void A<en>::foo();
+}