From 0cf10ac9abd09d38fc4b143f54e2917d8c1d0af6 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 25 May 2012 14:47:05 +0000 Subject: [PATCH] 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 --- clang/lib/AST/Decl.cpp | 24 +++++++++++++++--------- clang/test/CodeGenCXX/visibility.cpp | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 7b7fa4276245..979971c7c391 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -163,7 +163,8 @@ static bool shouldConsiderTemplateLV(const FunctionDecl *fn, return !fn->hasAttr() || spec->isExplicitSpecialization(); } -static bool shouldConsiderTemplateLV(const ClassTemplateSpecializationDecl *d) { +static bool +shouldConsiderTemplateVis(const ClassTemplateSpecializationDecl *d) { return !d->hasAttr() || d->isExplicitSpecialization(); } @@ -399,14 +400,19 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D, // linkage of the template and template arguments. if (const ClassTemplateSpecializationDecl *spec = dyn_cast(Tag)) { - if (shouldConsiderTemplateLV(spec)) { - // From the template. - LV.merge(getLVForDecl(spec->getSpecializedTemplate(), true)); + // From the template. + LinkageInfo TempLV = getLVForDecl(spec->getSpecializedTemplate(), true); - // The arguments at which the template was instantiated. - const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs(); - LV.mergeWithMin(getLVForTemplateArgumentList(TemplateArgs, - OnlyTemplate)); + // The arguments at which the template was instantiated. + const TemplateArgumentList &TemplateArgs = spec->getTemplateArgs(); + LinkageInfo ArgsLV = getLVForTemplateArgumentList(TemplateArgs, + 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(D)) { if (const ClassTemplateSpecializationDecl *spec = dyn_cast(RD)) { - if (shouldConsiderTemplateLV(spec)) { + if (shouldConsiderTemplateVis(spec)) { // Merge template argument/parameter information for member // class template specializations. LV.mergeWithMin(getLVForTemplateArgumentList(spec->getTemplateArgs(), diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp index 587030854d1a..d88968431485 100644 --- a/clang/test/CodeGenCXX/visibility.cpp +++ b/clang/test/CodeGenCXX/visibility.cpp @@ -818,3 +818,17 @@ namespace test43 { // CHECK: define hidden void @_ZN6test433barINS_3fooEEEvv // CHECK-HIDDEN: define hidden void @_ZN6test433barINS_3fooEEEvv } + +namespace test44 { + template + struct foo { + foo() {} + }; + namespace { + struct bar; + } + template struct DEFAULT foo; + foo x; + // CHECK: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev + // CHECK-HIDDEN: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev +}