Author: Matheus Izvekov Date: 2025-04-09T23:23:52-03:00 New Revision: 98feb05825a179c56f965d936b948a95d2a6b888
URL: https://github.com/llvm/llvm-project/commit/98feb05825a179c56f965d936b948a95d2a6b888 DIFF: https://github.com/llvm/llvm-project/commit/98feb05825a179c56f965d936b948a95d2a6b888.diff LOG: [clang] fix unresolved dependent template specialization mangling (#135111) This fixes a regression introduced in https://github.com/llvm/llvm-project/pull/133610 which was reported here https://github.com/llvm/llvm-project/pull/133610#issuecomment-2787332042 When mangling a dependent template specialization appearing within an unresolved prefix, translate the dtst back to a dependent template name including the prefix, and mangle following the nested unresolved-type production. There are no release notes, since this regression was never released. Added: Modified: clang/lib/AST/ItaniumMangle.cpp clang/test/CodeGenCXX/mangle-template.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index eb25b19bbdc74..8790a5282a96b 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1404,9 +1404,19 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, // - a template type parameter // - a template template parameter with arguments // In all of these cases, we should have no prefix. - if (qualifier->getPrefix()) { - mangleUnresolvedPrefix(qualifier->getPrefix(), - /*recursive*/ true); + if (NestedNameSpecifier *Prefix = qualifier->getPrefix()) { + if (const auto *DTST = + dyn_cast<DependentTemplateSpecializationType>(type)) { + Out << "srN"; + TemplateName Template = getASTContext().getDependentTemplateName( + {Prefix, DTST->getDependentTemplateName().getName(), + /*HasTemplateKeyword=*/true}); + mangleTemplatePrefix(Template); + mangleTemplateArgs(Template, DTST->template_arguments()); + break; + } + mangleUnresolvedPrefix(Prefix, + /*recursive=*/true); } else { // Otherwise, all the cases want this. Out << "sr"; diff --git a/clang/test/CodeGenCXX/mangle-template.cpp b/clang/test/CodeGenCXX/mangle-template.cpp index a4cb22739ac2a..365aba5989baa 100644 --- a/clang/test/CodeGenCXX/mangle-template.cpp +++ b/clang/test/CodeGenCXX/mangle-template.cpp @@ -70,7 +70,7 @@ namespace test7 { static const unsigned value = sizeof(T); }; - template<unsigned> struct int_c { + template<unsigned> struct int_c { typedef float type; }; @@ -92,7 +92,7 @@ namespace test8 { }; }; - template<unsigned> struct int_c { + template<unsigned> struct int_c { typedef float type; }; @@ -399,3 +399,20 @@ namespace type_qualifier { // CHECK: @_ZN14type_qualifier1gIPiEEvDTcmcvv_ELi1EE template void g<int*>(int); } + +namespace unresolved_template_specialization_type { + template <int> struct enable_if {}; + struct Foo { + static const int value = true; + }; + struct HashStateBase { + template <typename> using is_hashable = Foo; + }; + template <class> struct raw_hash_set { + template <typename H> + static enable_if<H::template is_hashable<int>::value> + AbslHashValue() {} + }; + template enable_if<true> raw_hash_set<int>::AbslHashValue<HashStateBase>(); + // CHECH: @_ZN39unresolved_template_specialization_type12raw_hash_setIiE13AbslHashValueINS_13HashStateBaseEEENS_9enable_ifIXsrNT_11is_hashableIiEE5valueEEEv +} // namespace unresolved_template_specialization_type _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits