]> granicus.if.org Git - clang/commitdiff
We were computing the visibility and linkage of template parameters, but
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 11 Jun 2012 14:29:58 +0000 (14:29 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 11 Jun 2012 14:29:58 +0000 (14:29 +0000)
only using the linkage.

Use and test both, documenting that considering the visibility and linkage
of template parameters is a difference from gcc.

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

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

index 3a002918163f2cf3f3d2167a4de9c557ee5ee1cc..ab7ff116dd863ab449d6e398bb0fa1883a7e0ee8 100644 (file)
@@ -381,7 +381,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
       LinkageInfo ArgsLV = getLVForTemplateArgumentList(templateArgs,
                                                         OnlyTemplate);
       if (shouldConsiderTemplateVis(Function, specInfo)) {
-        LV.merge(TempLV);
+        LV.mergeWithMin(TempLV);
         LV.mergeWithMin(ArgsLV);
       } else {
         LV.mergeLinkage(TempLV);
@@ -412,7 +412,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
       LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
                                                         OnlyTemplate);
       if (shouldConsiderTemplateVis(spec)) {
-        LV.merge(TempLV);
+        LV.mergeWithMin(TempLV);
         LV.mergeWithMin(ArgsLV);
       } else {
         LV.mergeLinkage(TempLV);
@@ -544,7 +544,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
       if (shouldConsiderTemplateVis(MD, spec)) {
         LV.mergeWithMin(ArgsLV);
         if (!OnlyTemplate)
-          LV.merge(ParamsLV);
+          LV.mergeWithMin(ParamsLV);
       } else {
         LV.mergeLinkage(ArgsLV);
         if (!OnlyTemplate)
@@ -569,7 +569,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
       if (shouldConsiderTemplateVis(spec)) {
         LV.mergeWithMin(ArgsLV);
         if (!OnlyTemplate)
-          LV.merge(ParamsLV);
+          LV.mergeWithMin(ParamsLV);
       } else {
         LV.mergeLinkage(ArgsLV);
         if (!OnlyTemplate)
index d302214df44208187703dc655f81ed32f3a7a9d1..a398a45e585c01b6cd4738bec04b2a620cf2fe3f 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
 
 #define HIDDEN __attribute__((visibility("hidden")))
 #define PROTECTED __attribute__((visibility("protected")))
@@ -79,6 +79,25 @@ namespace test41 {
   // CHECK-HIDDEN: @_ZN6test413barE = external hidden global
 }
 
+namespace test48 {
+  // Test that we use the visibility of struct foo when instantiating the
+  // template. Note that is a case where we disagree with gcc, it produces
+  // a default symbol.
+  struct HIDDEN foo {
+  };
+  DEFAULT foo x;
+
+  struct bar {
+    template<foo *z>
+    struct zed {
+    };
+  };
+
+  bar::zed<&x> y;
+  // CHECK: _ZN6test481yE = hidden global
+  // CHECK-HIDDEN: _ZN6test481yE = hidden global
+}
+
 // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
 // CHECK: @_ZN5Test71aE = hidden global
 // CHECK: @_ZN5Test71bE = global
@@ -881,3 +900,77 @@ namespace test47 {
   // CHECK: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
   // CHECK-HIDDEN: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
 }
+
+namespace test49 {
+  // Test that we use the visibility of struct foo when instantiating the
+  // template. Note that is a case where we disagree with gcc, it produces
+  // a default symbol.
+
+  struct HIDDEN foo {
+  };
+
+  DEFAULT foo x;
+
+  struct bar {
+    template<foo *z>
+    void zed() {
+    }
+  };
+
+  template void bar::zed<&x>();
+  // CHECK: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
+}
+
+namespace test50 {
+  // Test that we use the visibility of struct foo when instantiating the
+  // template. Note that is a case where we disagree with gcc, it produces
+  // a default symbol.
+
+  struct HIDDEN foo {
+  };
+  DEFAULT foo x;
+  template<foo *z>
+  struct DEFAULT bar {
+    void zed() {
+    }
+  };
+  template void bar<&x>::zed();
+  // CHECK: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
+}
+
+namespace test51 {
+  // Test that we use the visibility of struct foo when instantiating the
+  // template. Note that is a case where we disagree with gcc, it produces
+  // a default symbol.
+
+  struct HIDDEN foo {
+  };
+  DEFAULT foo x;
+  template<foo *z>
+  void DEFAULT zed() {
+  }
+  template void zed<&x>();
+  // CHECK: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
+  // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
+}
+
+namespace test52 {
+  // Test that we use the linkage of struct foo when instantiating the
+  // template. Note that is a case where we disagree with gcc, it produces
+  // an external symbol.
+
+  namespace {
+    struct foo {
+    };
+  }
+  template<foo *x>
+  void zed() {
+  }
+  void f() {
+    zed<nullptr>();
+  }
+  // CHECK: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
+  // CHECK-HIDDEN: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
+}