diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 88de234a6e0b..3b041efe3aac 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -2677,7 +2677,7 @@ template struct AbstractManglingParser { bool TryToParseTemplateArgs = true; bool PermitForwardTemplateReferences = false; - bool InConstraintExpr = false; + bool HasIncompleteTemplateParameterTracking = false; size_t ParsingLambdaParamsAtLevel = (size_t)-1; unsigned NumSyntheticTemplateParameters[3] = {}; @@ -4818,7 +4818,8 @@ template Node *AbstractManglingParser::parseConstraintExpr() { // Within this expression, all enclosing template parameter lists are in // scope. - ScopedOverride SaveInConstraintExpr(InConstraintExpr, true); + ScopedOverride SaveIncompleteTemplateParameterTracking( + HasIncompleteTemplateParameterTracking, true); return getDerived().parseExpr(); } @@ -5676,7 +5677,7 @@ Node *AbstractManglingParser::parseTemplateParam() { // substitute them all within a , so print the // parameter numbering instead for now. // TODO: Track all enclosing template parameters and substitute them here. - if (InConstraintExpr) { + if (HasIncompleteTemplateParameterTracking) { return make(std::string_view(Begin, First - 1 - Begin)); } @@ -5737,6 +5738,12 @@ Node *AbstractManglingParser::parseTemplateParamDecl( } if (consumeIf("Tk")) { + // We don't track enclosing template parameter levels well enough to + // reliably demangle template parameter substitutions, so print an arbitrary + // string in place of a parameter for now. + // TODO: Track all enclosing template parameters and demangle substitutions. + ScopedOverride SaveIncompleteTemplateParameterTrackingExpr( + HasIncompleteTemplateParameterTracking, true); Node *Constraint = getDerived().parseName(); if (!Constraint) return nullptr; diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp index ab783cf9d96f..77f79e0d40e8 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -30137,6 +30137,7 @@ const char* cases[][2] = {"_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E0_clIiiEEDaS3_Qaa1CIDtfp_EELb1E", "auto void test7::f()::'lambda0' requires C && C (auto)::operator()(auto) const requires C && true"}, {"_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E1_clIiiEEDaS3_Q1CIDtfp_EE", "auto void test7::f()::'lambda1' requires C && C (auto)::operator()(auto) const requires C"}, {"_ZZN5test71fIiEEvvENKUlTyT0_E_clIiiEEDaS1_", "auto void test7::f()::'lambda'(auto)::operator()(auto) const"}, + {"_ZN3FooIiE6methodITk4TrueIT_EiEEvS3_", "void Foo::method(T)"}, // C++20 requires expressions, see https://github.com/itanium-cxx-abi/cxx-abi/issues/24. {"_Z1fIiEviQrqXcvT__EXfp_Xeqfp_cvS0__EXplcvS0__ELi1ER5SmallXmicvS0__ELi1ENXmlcvS0__ELi2ENR11SmallerThanILi1234EETS0_T1XIS0_ETNS3_4typeETS2_IiEQ11SmallerThanIS0_Li256EEE", "void f(int) requires requires { (T)(); fp; fp == (T)(); {(T)() + 1} -> Small; {(T)() - 1} noexcept; {(T)() * 2} noexcept -> SmallerThan<1234>; typename T; typename X; typename X::type; typename X; requires SmallerThan; }"}, diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h index fb2060fa07f7..0af0224bc83f 100644 --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -2677,7 +2677,7 @@ template struct AbstractManglingParser { bool TryToParseTemplateArgs = true; bool PermitForwardTemplateReferences = false; - bool InConstraintExpr = false; + bool HasIncompleteTemplateParameterTracking = false; size_t ParsingLambdaParamsAtLevel = (size_t)-1; unsigned NumSyntheticTemplateParameters[3] = {}; @@ -4818,7 +4818,8 @@ template Node *AbstractManglingParser::parseConstraintExpr() { // Within this expression, all enclosing template parameter lists are in // scope. - ScopedOverride SaveInConstraintExpr(InConstraintExpr, true); + ScopedOverride SaveIncompleteTemplateParameterTracking( + HasIncompleteTemplateParameterTracking, true); return getDerived().parseExpr(); } @@ -5676,7 +5677,7 @@ Node *AbstractManglingParser::parseTemplateParam() { // substitute them all within a , so print the // parameter numbering instead for now. // TODO: Track all enclosing template parameters and substitute them here. - if (InConstraintExpr) { + if (HasIncompleteTemplateParameterTracking) { return make(std::string_view(Begin, First - 1 - Begin)); } @@ -5737,6 +5738,12 @@ Node *AbstractManglingParser::parseTemplateParamDecl( } if (consumeIf("Tk")) { + // We don't track enclosing template parameter levels well enough to + // reliably demangle template parameter substitutions, so print an arbitrary + // string in place of a parameter for now. + // TODO: Track all enclosing template parameters and demangle substitutions. + ScopedOverride SaveIncompleteTemplateParameterTrackingExpr( + HasIncompleteTemplateParameterTracking, true); Node *Constraint = getDerived().parseName(); if (!Constraint) return nullptr;