diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-11 14:29:58 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-06-11 14:29:58 +0000 |
commit | edb4b626130cc8268b1d7a3f9a9fdc7fb4c3a2bb (patch) | |
tree | a26267f1afdf5dd02f68990e18e6f5f4414f0b4c | |
parent | 74bb710e73229ce0ad3bb27c8689c0276e8ec131 (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.cpp | 8 | ||||
-rw-r--r-- | test/CodeGenCXX/visibility.cpp | 97 |
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 +} |