MaskRay updated this revision to Diff 550961. MaskRay added a comment. rebase. this does not address rjmccall's comment, but just to show the difference to other tests
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154774/new/ https://reviews.llvm.org/D154774 Files: clang/lib/AST/Decl.cpp clang/test/CodeGenCXX/visibility.cpp Index: clang/test/CodeGenCXX/visibility.cpp =================================================================== --- clang/test/CodeGenCXX/visibility.cpp +++ clang/test/CodeGenCXX/visibility.cpp @@ -1017,8 +1017,8 @@ 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( @@ -1029,8 +1029,8 @@ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2dcEEEEEvv( template void zed<&ha>(); - // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( - // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( + // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( + // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( template void DEFAULT zed<&hb>(); // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2hbEEEEEvv( @@ -1429,6 +1429,7 @@ template <class T> template <class U> U foo<T>::bar() { return {}; } + /// foo<int>::{zed,bar} get the instantiated-from member's HIDDEN, overriding DEFAULT. extern template struct DEFAULT foo<int>; int use() { @@ -1436,13 +1437,12 @@ foo<long> p; return o.zed() + o.bar<int>() + p.zed() + p.bar<int>(); } - /// FIXME: foo<int>::bar is hidden in GCC w/ or w/o -fvisibility=hidden. // CHECK-LABEL: declare hidden noundef i32 @_ZN6test713fooIiE3zedEv( - // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIiE3barIiEET_v( + // CHECK-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIiE3barIiEET_v( // CHECK-LABEL: define linkonce_odr hidden noundef i64 @_ZN6test713fooIlE3zedEv( - // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIlE3barIiEET_v( + // CHECK-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIlE3barIiEET_v( // CHECK-HIDDEN-LABEL: declare hidden noundef i32 @_ZN6test713fooIiE3zedEv( - // CHECK-HIDDEN-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIiE3barIiEET_v( + // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIiE3barIiEET_v( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i64 @_ZN6test713fooIlE3zedEv( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIlE3barIiEET_v( } Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -375,7 +375,9 @@ if (!specInfo->isExplicitInstantiationOrSpecialization()) return true; - return !fn->hasAttr<VisibilityAttr>(); + return !fn->hasAttr<VisibilityAttr>() && !specInfo->getTemplate() + ->getTemplatedDecl() + ->hasAttr<VisibilityAttr>(); } /// Merge in template-related linkage and visibility for the given @@ -1274,12 +1276,20 @@ } // Also handle function template specializations. if (const auto *fn = dyn_cast<FunctionDecl>(ND)) { - // If the function is a specialization of a template with an - // explicit visibility attribute, use that. - if (FunctionTemplateSpecializationInfo *templateInfo - = fn->getTemplateSpecializationInfo()) - return getVisibilityOf(templateInfo->getTemplate()->getTemplatedDecl(), - kind); + // If the function is a specialization of a template, + if (FunctionTemplateSpecializationInfo *templateInfo = + fn->getTemplateSpecializationInfo()) { + // ... If the template has an explicit visibility attribute, use that. + if (auto Vis = getVisibilityOf( + templateInfo->getTemplate()->getTemplatedDecl(), kind)) + return Vis; + // ... If the template instantiates from a member template with an + // explicit visibility attribute, use that. + if (auto *InstantiatedFrom = + templateInfo->getTemplate()->getInstantiatedFromMemberTemplate()) + return getVisibilityOf(InstantiatedFrom->getTemplatedDecl(), kind); + return std::nullopt; + } // If the function is a member of a specialization of a class template // and the corresponding decl has explicit visibility, use that.
Index: clang/test/CodeGenCXX/visibility.cpp =================================================================== --- clang/test/CodeGenCXX/visibility.cpp +++ clang/test/CodeGenCXX/visibility.cpp @@ -1017,8 +1017,8 @@ 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( @@ -1029,8 +1029,8 @@ // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2dcEEEEEvv( template void zed<&ha>(); - // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( - // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( + // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( + // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2haEEEEEvv( template void DEFAULT zed<&hb>(); // CHECK-LABEL: define weak_odr void @_ZN6test513zedIXadL_ZNS_2hbEEEEEvv( @@ -1429,6 +1429,7 @@ template <class T> template <class U> U foo<T>::bar() { return {}; } + /// foo<int>::{zed,bar} get the instantiated-from member's HIDDEN, overriding DEFAULT. extern template struct DEFAULT foo<int>; int use() { @@ -1436,13 +1437,12 @@ foo<long> p; return o.zed() + o.bar<int>() + p.zed() + p.bar<int>(); } - /// FIXME: foo<int>::bar is hidden in GCC w/ or w/o -fvisibility=hidden. // CHECK-LABEL: declare hidden noundef i32 @_ZN6test713fooIiE3zedEv( - // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIiE3barIiEET_v( + // CHECK-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIiE3barIiEET_v( // CHECK-LABEL: define linkonce_odr hidden noundef i64 @_ZN6test713fooIlE3zedEv( - // CHECK-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIlE3barIiEET_v( + // CHECK-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIlE3barIiEET_v( // CHECK-HIDDEN-LABEL: declare hidden noundef i32 @_ZN6test713fooIiE3zedEv( - // CHECK-HIDDEN-LABEL: define linkonce_odr noundef i32 @_ZN6test713fooIiE3barIiEET_v( + // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIiE3barIiEET_v( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i64 @_ZN6test713fooIlE3zedEv( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden noundef i32 @_ZN6test713fooIlE3barIiEET_v( } Index: clang/lib/AST/Decl.cpp =================================================================== --- clang/lib/AST/Decl.cpp +++ clang/lib/AST/Decl.cpp @@ -375,7 +375,9 @@ if (!specInfo->isExplicitInstantiationOrSpecialization()) return true; - return !fn->hasAttr<VisibilityAttr>(); + return !fn->hasAttr<VisibilityAttr>() && !specInfo->getTemplate() + ->getTemplatedDecl() + ->hasAttr<VisibilityAttr>(); } /// Merge in template-related linkage and visibility for the given @@ -1274,12 +1276,20 @@ } // Also handle function template specializations. if (const auto *fn = dyn_cast<FunctionDecl>(ND)) { - // If the function is a specialization of a template with an - // explicit visibility attribute, use that. - if (FunctionTemplateSpecializationInfo *templateInfo - = fn->getTemplateSpecializationInfo()) - return getVisibilityOf(templateInfo->getTemplate()->getTemplatedDecl(), - kind); + // If the function is a specialization of a template, + if (FunctionTemplateSpecializationInfo *templateInfo = + fn->getTemplateSpecializationInfo()) { + // ... If the template has an explicit visibility attribute, use that. + if (auto Vis = getVisibilityOf( + templateInfo->getTemplate()->getTemplatedDecl(), kind)) + return Vis; + // ... If the template instantiates from a member template with an + // explicit visibility attribute, use that. + if (auto *InstantiatedFrom = + templateInfo->getTemplate()->getInstantiatedFromMemberTemplate()) + return getVisibilityOf(InstantiatedFrom->getTemplatedDecl(), kind); + return std::nullopt; + } // If the function is a member of a specialization of a class template // and the corresponding decl has explicit visibility, use that.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits