aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-06-11 14:29:58 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-06-11 14:29:58 +0000
commitedb4b626130cc8268b1d7a3f9a9fdc7fb4c3a2bb (patch)
treea26267f1afdf5dd02f68990e18e6f5f4414f0b4c
parent74bb710e73229ce0ad3bb27c8689c0276e8ec131 (diff)
We were computing the visibility and linkage of template parameters, but
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
-rw-r--r--lib/AST/Decl.cpp8
-rw-r--r--test/CodeGenCXX/visibility.cpp97
2 files changed, 99 insertions, 6 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 3a00291816..ab7ff116dd 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -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)
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index d302214df4..a398a45e58 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -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
+}