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.

llvm-svn: 158309
This commit is contained in:
Rafael Espindola 2012-06-11 14:29:58 +00:00
parent 1162fa0a97
commit a486f48e5b
2 changed files with 99 additions and 6 deletions

View 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)

View 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
}