diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index c5c2edf1bfe3a..8ab1b9708a7ab 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -244,62 +244,6 @@ LinkageInfo LinkageComputer::getLVForType(const Type &T, return getTypeLinkageAndVisibility(&T); } -/// Get the most restrictive linkage for the types in the given -/// template parameter list. For visibility purposes, template -/// parameters are part of the signature of a template. -LinkageInfo LinkageComputer::getLVForTemplateParameterList( - const TemplateParameterList *Params, LVComputationKind computation) { - LinkageInfo LV; - for (const NamedDecl *P : *Params) { - // Template type parameters are the most common and never - // contribute to visibility, pack or not. - if (isa(P)) - continue; - - // Non-type template parameters can be restricted by the value type, e.g. - // template class A { ... }; - // We have to be careful here, though, because we can be dealing with - // dependent types. - if (const auto *NTTP = dyn_cast(P)) { - // Handle the non-pack case first. - if (!NTTP->isExpandedParameterPack()) { - if (!NTTP->getType()->isDependentType()) { - LV.merge(getLVForType(*NTTP->getType(), computation)); - } - continue; - } - - // Look at all the types in an expanded pack. - for (unsigned i = 0, n = NTTP->getNumExpansionTypes(); i != n; ++i) { - QualType type = NTTP->getExpansionType(i); - if (!type->isDependentType()) - LV.merge(getTypeLinkageAndVisibility(type)); - } - continue; - } - - // Template template parameters can be restricted by their - // template parameters, recursively. - const auto *TTP = cast(P); - - // Handle the non-pack case first. - if (!TTP->isExpandedParameterPack()) { - LV.merge(getLVForTemplateParameterList(TTP->getTemplateParameters(), - computation)); - continue; - } - - // Look at all expansions in an expanded pack. - for (unsigned i = 0, n = TTP->getNumExpansionTemplateParameters(); - i != n; ++i) { - LV.merge(getLVForTemplateParameterList( - TTP->getExpansionTemplateParameters(i), computation)); - } - } - - return LV; -} - static const Decl *getOutermostFuncOrBlockContext(const Decl *D) { const Decl *Ret = nullptr; const DeclContext *DC = D->getDeclContext(); @@ -324,10 +268,14 @@ LinkageComputer::getLVForTemplateArgumentList(ArrayRef Args, for (const TemplateArgument &Arg : Args) { switch (Arg.getKind()) { case TemplateArgument::Null: + continue; + case TemplateArgument::Integral: + LV.merge(getLVForType(*Arg.getIntegralType(), computation)); + continue; case TemplateArgument::Expression: + LV.merge(getLVForType(*Arg.getAsExpr()->getType(), computation)); continue; - case TemplateArgument::Type: LV.merge(getLVForType(*Arg.getAsType(), computation)); continue; @@ -368,10 +316,9 @@ LinkageComputer::getLVForTemplateArgumentList(const TemplateArgumentList &TArgs, static bool shouldConsiderTemplateVisibility(const FunctionDecl *fn, const FunctionTemplateSpecializationInfo *specInfo) { - // Include visibility from the template parameters and arguments - // only if this is not an explicit instantiation or specialization - // with direct explicit visibility. (Implicit instantiations won't - // have a direct attribute.) + // Include visibility from the template arguments only if this is not an + // explicit instantiation or specialization with direct explicit visibility. + // (Implicit instantiations won't have a direct attribute.) if (!specInfo->isExplicitInstantiationOrSpecialization()) return true; @@ -399,11 +346,6 @@ void LinkageComputer::mergeTemplateLV( // template declaration. LV.setLinkage(tempLV.getLinkage()); - // Merge information from the template parameters. - LinkageInfo paramsLV = - getLVForTemplateParameterList(temp->getTemplateParameters(), computation); - LV.mergeMaybeWithVisibility(paramsLV, considerVisibility); - // Merge information from the template arguments. const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments; LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation); @@ -426,14 +368,13 @@ static bool hasDirectVisibilityAttribute(const NamedDecl *D, static bool shouldConsiderTemplateVisibility( const ClassTemplateSpecializationDecl *spec, LVComputationKind computation) { - // Include visibility from the template parameters and arguments - // only if this is not an explicit instantiation or specialization - // with direct explicit visibility (and note that implicit - // instantiations won't have a direct attribute). + // Include visibility from the template arguments only if this is not an + // explicit instantiation or specialization with direct explicit visibility + // (and note that implicit instantiations won't have a direct attribute). // - // Furthermore, we want to ignore template parameters and arguments - // for an explicit specialization when computing the visibility of a - // member thereof with explicit visibility. + // Furthermore, we want to ignore template arguments for an explicit + // specialization when computing the visibility of a member thereof with + // explicit visibility. // // This is a bit complex; let's unpack it. // @@ -464,8 +405,6 @@ void LinkageComputer::mergeTemplateLV( LVComputationKind computation) { bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation); - // Merge information from the template parameters, but ignore - // visibility if we're only considering template arguments. ClassTemplateDecl *temp = spec->getSpecializedTemplate(); // Merge information from the template declaration. LinkageInfo tempLV = getLVForDecl(temp, computation); @@ -473,11 +412,6 @@ void LinkageComputer::mergeTemplateLV( // template declaration. LV.setLinkage(tempLV.getLinkage()); - LinkageInfo paramsLV = - getLVForTemplateParameterList(temp->getTemplateParameters(), computation); - LV.mergeMaybeWithVisibility(paramsLV, - considerVisibility && !hasExplicitVisibilityAlready(computation)); - // Merge information from the template arguments. We ignore // template-argument visibility if we've got an explicit // instantiation with a visibility attribute. @@ -521,14 +455,6 @@ void LinkageComputer::mergeTemplateLV(LinkageInfo &LV, LVComputationKind computation) { bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation); - // Merge information from the template parameters, but ignore - // visibility if we're only considering template arguments. - VarTemplateDecl *temp = spec->getSpecializedTemplate(); - LinkageInfo tempLV = - getLVForTemplateParameterList(temp->getTemplateParameters(), computation); - LV.mergeMaybeWithVisibility(tempLV, - considerVisibility && !hasExplicitVisibilityAlready(computation)); - // Merge information from the template arguments. We ignore // template-argument visibility if we've got an explicit // instantiation with a visibility attribute. @@ -858,10 +784,6 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D, // - a template } else if (const auto *temp = dyn_cast(D)) { - bool considerVisibility = !hasExplicitVisibilityAlready(computation); - LinkageInfo tempLV = - getLVForTemplateParameterList(temp->getTemplateParameters(), computation); - LV.mergeMaybeWithVisibility(tempLV, considerVisibility); // An unnamed namespace or a namespace declared directly or indirectly // within an unnamed namespace has internal linkage. All other namespaces @@ -1029,14 +951,6 @@ LinkageComputer::getLVForClassMember(const NamedDecl *D, // Template members. } else if (const auto *temp = dyn_cast(D)) { - bool considerVisibility = - (!LV.isVisibilityExplicit() && - !classLV.isVisibilityExplicit() && - !hasExplicitVisibilityAlready(computation)); - LinkageInfo tempLV = - getLVForTemplateParameterList(temp->getTemplateParameters(), computation); - LV.mergeMaybeWithVisibility(tempLV, considerVisibility); - if (const auto *redeclTemp = dyn_cast(temp)) { if (isExplicitMemberSpecialization(redeclTemp)) { explicitSpecSuppressor = temp->getTemplatedDecl(); diff --git a/clang/lib/AST/Linkage.h b/clang/lib/AST/Linkage.h index 31f384eb75d0b..0907bad8e656d 100644 --- a/clang/lib/AST/Linkage.h +++ b/clang/lib/AST/Linkage.h @@ -137,9 +137,6 @@ class LinkageComputer { LinkageInfo getLVForType(const Type &T, LVComputationKind computation); - LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params, - LVComputationKind computation); - LinkageInfo getLVForValue(const APValue &V, LVComputationKind computation); public: diff --git a/clang/test/CodeGenCXX/visibility.cpp b/clang/test/CodeGenCXX/visibility.cpp index b017bc8b52d5a..2e7ddd1806674 100644 --- a/clang/test/CodeGenCXX/visibility.cpp +++ b/clang/test/CodeGenCXX/visibility.cpp @@ -83,9 +83,6 @@ namespace test41 { } 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; @@ -97,7 +94,7 @@ namespace test48 { }; bar::zed<&x> y; - // CHECK: _ZN6test481yE = hidden global + // CHECK: _ZN6test481yE = global // CHECK-HIDDEN: _ZN6test481yE = hidden global } @@ -137,22 +134,22 @@ namespace test73 { template int HIDDEN var<&hc>; int use() { return var<&dd> + var<&hd>; } - // CHECK: @_ZN6test733varIXadL_ZNS_2daEEEEE = weak_odr hidden global i32 0 + // CHECK: @_ZN6test733varIXadL_ZNS_2daEEEEE = weak_odr global i32 0 // CHECK-NEXT: @_ZN6test733varIXadL_ZNS_2dbEEEEE = weak_odr global i32 0 // CHECK-NEXT: @_ZN6test733varIXadL_ZNS_2dcEEEEE = weak_odr hidden global i32 0 // CHECK-NEXT: @_ZN6test733varIXadL_ZNS_2haEEEEE = weak_odr hidden global i32 0 // CHECK-NEXT: @_ZN6test733varIXadL_ZNS_2hbEEEEE = weak_odr global i32 0 // CHECK-NEXT: @_ZN6test733varIXadL_ZNS_2hcEEEEE = weak_odr hidden global i32 0 - // CHECK: @_ZN6test733varIXadL_ZNS_2ddEEEEE = linkonce_odr hidden global i32 0 + // CHECK: @_ZN6test733varIXadL_ZNS_2ddEEEEE = linkonce_odr global i32 0 // CHECK-NEXT: @_ZN6test733varIXadL_ZNS_2hdEEEEE = linkonce_odr hidden global i32 0 - // CHECK-HIDDEN: @_ZN6test733varIXadL_ZNS_2daEEEEE = weak_odr hidden global i32 0 + // CHECK-HIDDEN: @_ZN6test733varIXadL_ZNS_2daEEEEE = weak_odr global i32 0 // CHECK-HIDDEN-NEXT: @_ZN6test733varIXadL_ZNS_2dbEEEEE = weak_odr global i32 0 // CHECK-HIDDEN-NEXT: @_ZN6test733varIXadL_ZNS_2dcEEEEE = weak_odr hidden global i32 0 // CHECK-HIDDEN-NEXT: @_ZN6test733varIXadL_ZNS_2haEEEEE = weak_odr hidden global i32 0 // CHECK-HIDDEN-NEXT: @_ZN6test733varIXadL_ZNS_2hbEEEEE = weak_odr global i32 0 // CHECK-HIDDEN-NEXT: @_ZN6test733varIXadL_ZNS_2hcEEEEE = weak_odr hidden global i32 0 - // CHECK-HIDDEN: @_ZN6test733varIXadL_ZNS_2ddEEEEE = linkonce_odr hidden global i32 0 + // CHECK-HIDDEN: @_ZN6test733varIXadL_ZNS_2ddEEEEE = linkonce_odr global i32 0 // CHECK-HIDDEN-NEXT: @_ZN6test733varIXadL_ZNS_2hdEEEEE = linkonce_odr hidden global i32 0 } @@ -963,10 +960,9 @@ namespace test47 { } 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. - + // When instantiating the template, we constraint the visibility with the + // non-type template argument &x. The type of &x does not constraint the + // visibility. struct HIDDEN foo { }; @@ -979,15 +975,11 @@ namespace test49 { }; template void bar::zed<&x>(); - // CHECK-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv + // CHECK-LABEL: define weak_odr void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv // CHECK-HIDDEN-LABEL: 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; @@ -997,15 +989,11 @@ namespace test50 { } }; template void bar<&x>::zed(); - // CHECK-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv - // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv + // CHECK-LABEL: define weak_odr void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv + // CHECK-HIDDEN-LABEL: define weak_odr 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 da, db, dc, dd, de, df; HIDDEN foo ha, hb, hc, hd, he, hf; @@ -1013,8 +1001,8 @@ namespace test51 { void DEFAULT zed() { } template void zed<&da>(); - // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2daEEEEEvv( - // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2daEEEEEvv( + // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2daEEEEEvv( + // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2daEEEEEvv( template void DEFAULT zed<&db>(); // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2dbEEEEEvv( @@ -1041,10 +1029,10 @@ namespace test51 { template void zed<&hd>(); template void DEFAULT zed<&he>(); #pragma GCC visibility pop - // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2ddEEEEEvv( + // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2ddEEEEEvv( // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2hdEEEEEvv( // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2heEEEEEvv( - // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2ddEEEEEvv( + // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2ddEEEEEvv( // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2hdEEEEEvv( // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2heEEEEEvv( @@ -1052,17 +1040,13 @@ namespace test51 { zed<&df>(); zed<&hf>(); } - // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test513zedIXadL_ZNS_2dfEEEEEvv( + // CHECK-LABEL: define linkonce_odr void @_ZN6test513zedIXadL_ZNS_2dfEEEEEvv( // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test513zedIXadL_ZNS_2hfEEEEEvv( - // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test513zedIXadL_ZNS_2dfEEEEEvv( + // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6test513zedIXadL_ZNS_2dfEEEEEvv( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test513zedIXadL_ZNS_2hfEEEEEvv( } 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 { };