When ignoring visibility in an instantiation, still consider the linkage.

Similar fixes for function and member template to follow as I write the
testcases.

llvm-svn: 157470
This commit is contained in:
Rafael Espindola 2012-05-25 14:47:05 +00:00
parent 4d71d0f9fa
commit 0cf10ac9ab
2 changed files with 29 additions and 9 deletions

View File

@ -163,7 +163,8 @@ static bool shouldConsiderTemplateLV(const FunctionDecl *fn,
return !fn->hasAttr<VisibilityAttr>() || spec->isExplicitSpecialization(); return !fn->hasAttr<VisibilityAttr>() || spec->isExplicitSpecialization();
} }
static bool shouldConsiderTemplateLV(const ClassTemplateSpecializationDecl *d) { static bool
shouldConsiderTemplateVis(const ClassTemplateSpecializationDecl *d) {
return !d->hasAttr<VisibilityAttr>() || d->isExplicitSpecialization(); return !d->hasAttr<VisibilityAttr>() || d->isExplicitSpecialization();
} }
@ -399,14 +400,19 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// linkage of the template and template arguments. // linkage of the template and template arguments.
if (const ClassTemplateSpecializationDecl *spec if (const ClassTemplateSpecializationDecl *spec
= dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
if (shouldConsiderTemplateLV(spec)) { // From the template.
// From the template. LinkageInfo TempLV = getLVForDecl(spec->getSpecializedTemplate(), true);
LV.merge(getLVForDecl(spec->getSpecializedTemplate(), true));
// The arguments at which the template was instantiated. // The arguments at which the template was instantiated.
const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs(); const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs();
LV.mergeWithMin(getLVForTemplateArgumentList(TemplateArgs, LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs,
OnlyTemplate)); OnlyTemplate);
if (shouldConsiderTemplateVis(spec)) {
LV.merge(TempLV);
LV.mergeWithMin(ArgsLV);
} else {
LV.mergeLinkage(TempLV);
LV.mergeLinkage(ArgsLV);
} }
} }
@ -540,7 +546,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D, bool OnlyTemplate) {
} else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
if (const ClassTemplateSpecializationDecl *spec if (const ClassTemplateSpecializationDecl *spec
= dyn_cast<ClassTemplateSpecializationDecl>(RD)) { = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
if (shouldConsiderTemplateLV(spec)) { if (shouldConsiderTemplateVis(spec)) {
// Merge template argument/parameter information for member // Merge template argument/parameter information for member
// class template specializations. // class template specializations.
LV.mergeWithMin(getLVForTemplateArgumentList(spec->getTemplateArgs(), LV.mergeWithMin(getLVForTemplateArgumentList(spec->getTemplateArgs(),

View File

@ -818,3 +818,17 @@ namespace test43 {
// CHECK: define hidden void @_ZN6test433barINS_3fooEEEvv // CHECK: define hidden void @_ZN6test433barINS_3fooEEEvv
// CHECK-HIDDEN: define hidden void @_ZN6test433barINS_3fooEEEvv // CHECK-HIDDEN: define hidden void @_ZN6test433barINS_3fooEEEvv
} }
namespace test44 {
template <typename T>
struct foo {
foo() {}
};
namespace {
struct bar;
}
template struct DEFAULT foo<bar>;
foo<bar> x;
// CHECK: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
// CHECK-HIDDEN: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
}