From: Rafael Espindola Date: Mon, 11 Jun 2012 14:29:58 +0000 (+0000) Subject: We were computing the visibility and linkage of template parameters, but X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=edb4b626130cc8268b1d7a3f9a9fdc7fb4c3a2bb;p=clang 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 --- 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 + 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 + 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 + 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 + 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 + void zed() { + } + void f() { + zed(); + } + // CHECK: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv + // CHECK-HIDDEN: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv +}