From 223c5d18954c4fa90a339785c0492fede208f81d Mon Sep 17 00:00:00 2001 From: Viktoriia Bakalova Date: Fri, 13 Sep 2024 11:19:00 +0000 Subject: [PATCH] [ItaniumDemangle] Add template name to the substituions list during demangling. When demangling a template template parameter (`method(Bar b)`), the current demangler version first enters the template argument (`bool`) into the substitutions list, then the whole template specialization (`Bar`). The template name (`Bar`) never becomes a substitution candidate on its own. This is different when mangling. Mangling `method(Bar b, Bar i)` substitutes the `Bar` in the second parameter with the substitution for `TemplateTemplateParmDecl`. This leads to a discrepancy between mangler and demangler, see https://github.com/llvm/llvm-project/issues/108009. --- libcxxabi/src/demangle/ItaniumDemangle.h | 1 + libcxxabi/test/test_demangle.pass.cpp | 3 +++ llvm/include/llvm/Demangle/ItaniumDemangle.h | 1 + 3 files changed, 5 insertions(+) diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 3b041efe3aac0..d1f8da9d6b57b 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -4336,6 +4336,7 @@ Node *AbstractManglingParser::parseType() { // parse them, take the second production. if (TryToParseTemplateArgs && look() == 'I') { + Subs.push_back(Result); Node *TA = getDerived().parseTemplateArgs(); if (TA == nullptr) return nullptr; diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp index 77f79e0d40e84..44af7e041cbcf 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -30024,6 +30024,9 @@ const char* cases[][2] = // See https://github.com/itanium-cxx-abi/cxx-abi/issues/165. {"_ZN1C1fIiEEvDTtlNS_UlT_TL0__E_EEE", "void C::f(decltype(C::'lambda'(int, auto){}))"}, + // See https://github.com/llvm/llvm-project/issues/108009. + {"_ZN3FooIiE6methodIb3BarEEvT0_IT_ES3_IiE", "void Foo::method(Bar, Bar)"}, + // C++20 class type non-type template parameters: {"_Z1fIXtl1BLPi0ELi1EEEEvv", "void f()"}, {"_Z1fIXtl1BLPi32EEEEvv", "void f()"}, diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h index 0af0224bc83fa..21144bd8c0706 100644 --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -4336,6 +4336,7 @@ Node *AbstractManglingParser::parseType() { // parse them, take the second production. if (TryToParseTemplateArgs && look() == 'I') { + Subs.push_back(Result); Node *TA = getDerived().parseTemplateArgs(); if (TA == nullptr) return nullptr;