Don't ignore linkage when ignoring visibility in the instantiation of a

function template.

llvm-svn: 157480
This commit is contained in:
Rafael Espindola 2012-05-25 16:41:35 +00:00
parent aa58397b3c
commit 340941dc16
2 changed files with 27 additions and 8 deletions

View File

@ -158,7 +158,7 @@ getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
return getLVForTemplateArgumentList(TArgs.data(), TArgs.size(), OnlyTemplate);
}
static bool shouldConsiderTemplateLV(const FunctionDecl *fn,
static bool shouldConsiderTemplateVis(const FunctionDecl *fn,
const FunctionTemplateSpecializationInfo *spec) {
return !fn->hasAttr<VisibilityAttr>() || spec->isExplicitSpecialization();
}
@ -376,12 +376,16 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// this is an explicit specialization with a visibility attribute.
if (FunctionTemplateSpecializationInfo *specInfo
= Function->getTemplateSpecializationInfo()) {
if (shouldConsiderTemplateLV(Function, specInfo)) {
LV.merge(getLVForDecl(specInfo->getTemplate(),
true));
const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
LV.mergeWithMin(getLVForTemplateArgumentList(templateArgs,
OnlyTemplate));
LinkageInfo TempLV = getLVForDecl(specInfo->getTemplate(), true);
const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;
LinkageInfo ArgsLV = getLVForTemplateArgumentList(templateArgs,
OnlyTemplate);
if (shouldConsiderTemplateVis(Function, specInfo)) {
LV.merge(TempLV);
LV.mergeWithMin(ArgsLV);
} else {
LV.mergeLinkage(TempLV);
LV.mergeLinkage(ArgsLV);
}
}
@ -531,7 +535,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
// the template parameters and arguments.
if (FunctionTemplateSpecializationInfo *spec
= MD->getTemplateSpecializationInfo()) {
if (shouldConsiderTemplateLV(MD, spec)) {
if (shouldConsiderTemplateVis(MD, spec)) {
LV.mergeWithMin(getLVForTemplateArgumentList(*spec->TemplateArguments,
OnlyTemplate));
if (!OnlyTemplate)

View File

@ -849,3 +849,18 @@ namespace test45 {
// CHECK: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
// CHECK-HIDDEN: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
}
namespace test46 {
template <typename T>
void foo() {
}
namespace {
struct bar;
}
template DEFAULT void foo<bar>();
void zed() {
foo<bar>();
}
// CHECK: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
// CHECK-HIDDEN: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
}