[libcxx-commits] [libcxxabi] [llvm] [ItaniumDemangle] Fix conversion operators failing to demangle types with substitutions (PR #197420)
Iris Shi via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Aug 27 19:12:38 PDT 2026
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/197420
>From f6dbeb95796f2506f8e8faf3311190a911c4770e Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Wed, 26 Aug 2026 13:41:24 +0800
Subject: [PATCH] [ItaniumDemangle] Fix conversion operators failing to
demangle types with substitutions
---
libcxxabi/src/demangle/ItaniumDemangle.h | 4 ++++
libcxxabi/test/DemangleTestCases.inc | 5 +++++
llvm/include/llvm/Demangle/ItaniumDemangle.h | 4 ++++
llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc | 5 +++++
llvm/unittests/Demangle/DemangleTest.cpp | 9 +++++++++
5 files changed, 27 insertions(+)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 842b9614d9ff7..b9d635880cde6 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -6152,6 +6152,10 @@ AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
if (!consumeIf('I'))
return nullptr;
+ // Subtypes within template args are complete, so they can always parse their
+ // own template args.
+ ScopedOverride<bool> SaveTryToParseTemplateArgs(TryToParseTemplateArgs, true);
+
// <template-params> refer to the innermost <template-args>. Clear out any
// outer args that we may have inserted into TemplateParams.
if (TagTemplates) {
diff --git a/libcxxabi/test/DemangleTestCases.inc b/libcxxabi/test/DemangleTestCases.inc
index 6b7a99d849a94..59fe3bc64fcec 100644
--- a/libcxxabi/test/DemangleTestCases.inc
+++ b/libcxxabi/test/DemangleTestCases.inc
@@ -30234,4 +30234,9 @@
{"__alloc_token_123__ZnwmRKSt9nothrow_t", "operator new(unsigned long, std::nothrow_t const&) (.alloc_token)"},
{"__alloc_token__Znwm.llvm.1234", "operator new(unsigned long) (.llvm.1234) (.alloc_token)"},
{"__alloc_token_123__Z3foov", "foo() (.alloc_token)"},
+
+// Conversion operators with substitutions that have template args
+// (https://github.com/llvm/llvm-project/issues/109130)
+{"_ZN3foocvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEv", "foo::operator std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>()"},
+{"_ZN1XcvSt6vectorIiSaIiEEEv", "X::operator std::vector<int, std::allocator<int>>()"},
// clang-format on
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 83c76c6088339..36a789b7c80e1 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -6152,6 +6152,10 @@ AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
if (!consumeIf('I'))
return nullptr;
+ // Subtypes within template args are complete, so they can always parse their
+ // own template args.
+ ScopedOverride<bool> SaveTryToParseTemplateArgs(TryToParseTemplateArgs, true);
+
// <template-params> refer to the innermost <template-args>. Clear out any
// outer args that we may have inserted into TemplateParams.
if (TagTemplates) {
diff --git a/llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc b/llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc
index 6b7a99d849a94..59fe3bc64fcec 100644
--- a/llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc
+++ b/llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc
@@ -30234,4 +30234,9 @@
{"__alloc_token_123__ZnwmRKSt9nothrow_t", "operator new(unsigned long, std::nothrow_t const&) (.alloc_token)"},
{"__alloc_token__Znwm.llvm.1234", "operator new(unsigned long) (.llvm.1234) (.alloc_token)"},
{"__alloc_token_123__Z3foov", "foo() (.alloc_token)"},
+
+// Conversion operators with substitutions that have template args
+// (https://github.com/llvm/llvm-project/issues/109130)
+{"_ZN3foocvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEv", "foo::operator std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>()"},
+{"_ZN1XcvSt6vectorIiSaIiEEEv", "X::operator std::vector<int, std::allocator<int>>()"},
// clang-format on
diff --git a/llvm/unittests/Demangle/DemangleTest.cpp b/llvm/unittests/Demangle/DemangleTest.cpp
index e60a75ecd76da..d3b3099bbbb1c 100644
--- a/llvm/unittests/Demangle/DemangleTest.cpp
+++ b/llvm/unittests/Demangle/DemangleTest.cpp
@@ -29,4 +29,13 @@ TEST(Demangle, demangleTest) {
// extended type qualifier (https://bugs.llvm.org/show_bug.cgi?id=48009)
EXPECT_EQ(demangle("_Z3fooILi79EEbU7_ExtIntIXT_EEi"),
"bool foo<79>(int _ExtInt<79>)");
+
+ // Conversion operators with substitutions that have template args
+ // (https://github.com/llvm/llvm-project/issues/109130)
+ EXPECT_EQ(demangle("_ZN3foocvNSt7__cxx1112basic_stringIcSt11char_"
+ "traitsIcESaIcEEEEv"),
+ "foo::operator std::__cxx11::basic_string<char, "
+ "std::char_traits<char>, std::allocator<char>>()");
+ EXPECT_EQ(demangle("_ZN1XcvSt6vectorIiSaIiEEEv"),
+ "X::operator std::vector<int, std::allocator<int>>()");
}
More information about the libcxx-commits
mailing list