[libcxx-commits] [libcxxabi] [libcxxabi][ItaniumDemangle] Demangle explicitly named object parameters (PR #72881)
Michael Buch via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Nov 20 06:58:22 PST 2023
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/72881
The mangling for an explicitly named object was introduced in https://reviews.llvm.org/D140828
See following discussion for why a new mangling had to be introduced: https://github.com/itanium-cxx-abi/cxx-abi/issues/148
Since clang started emitting names with the new mangling, this patch implements support for demangling such names.
The approach this patch takes is to simply skip the explicit `this` parameter when constructing a `FunctionEncoding`. Thus following two functions demangle to the same:
```
struct Foo {
void func(this Foo self);
void func();
};
```
>From d9243de8658011c20db84dd091d7d76a8751ad06 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 18 Nov 2023 12:54:38 +0000
Subject: [PATCH] [libcxxabi][ItaniumDemangle] Demangle explicitly named object
parameters
---
libcxxabi/src/demangle/ItaniumDemangle.h | 30 +++++++++++++++++-------
libcxxabi/test/test_demangle.pass.cpp | 10 ++++++++
2 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 2336b84da293bcc..f9a0c059e86e8bd 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -2780,6 +2780,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
Qualifiers CVQualifiers = QualNone;
FunctionRefQual ReferenceQualifier = FrefQualNone;
size_t ForwardTemplateRefsBegin;
+ bool HasExplicitObjectParameter = false;
NameState(AbstractManglingParser *Enclosing)
: ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
@@ -3438,15 +3439,25 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
if (!consumeIf('N'))
return nullptr;
- Qualifiers CVTmp = parseCVQualifiers();
- if (State) State->CVQualifiers = CVTmp;
+ // 'H' specifies that the encoding that follows
+ // has an explicit object parameter.
+ if (!consumeIf('H')) {
+ Qualifiers CVTmp = parseCVQualifiers();
+ if (State)
+ State->CVQualifiers = CVTmp;
- if (consumeIf('O')) {
- if (State) State->ReferenceQualifier = FrefQualRValue;
- } else if (consumeIf('R')) {
- if (State) State->ReferenceQualifier = FrefQualLValue;
- } else {
- if (State) State->ReferenceQualifier = FrefQualNone;
+ if (consumeIf('O')) {
+ if (State)
+ State->ReferenceQualifier = FrefQualRValue;
+ } else if (consumeIf('R')) {
+ if (State)
+ State->ReferenceQualifier = FrefQualLValue;
+ } else {
+ if (State)
+ State->ReferenceQualifier = FrefQualNone;
+ }
+ } else if (State) {
+ State->HasExplicitObjectParameter = true;
}
Node *SoFar = nullptr;
@@ -5424,6 +5435,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
return nullptr;
Names.push_back(Ty);
} while (!IsEndOfEncoding() && look() != 'Q');
+ // Ignore the explicit 'this' parameter.
+ if (NameInfo.HasExplicitObjectParameter)
+ ++ParamsBegin;
Params = popTrailingNodeArray(ParamsBegin);
}
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 77741a952850ab9..a6b6d45a3783bb1 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30174,6 +30174,16 @@ const char* cases[][2] =
{"_Z2f5IKiEvu14__remove_constIT_E", "void f5<int const>(__remove_const(int const))"},
{"_Z2f5IPiEvu16__remove_pointerIT_E", "void f5<int*>(__remove_pointer(int*))"},
{"_Z2f5IiEvu14__remove_cvrefIT_E", "void f5<int>(__remove_cvref(int))"},
+
+ // C++23 explicit object parameter
+ {"_ZNH3Foo3fooES_i", "Foo::foo(int)"},
+ {"_ZNH3Foo3fooERKS_i", "Foo::foo(int)"},
+ {"_ZNH1X3fooIRS_EEvOT_i", "void X::foo<X&>(int)"},
+ {"_ZZNH2ns3Foo3fooES0_iENH4Foo24foo2EOKS1_", "ns::Foo::foo(int)::Foo2::foo2()" },
+ {"_ZNH2ns3FooB7Foo_tag3fooB7foo_tagERKS0_i", "ns::Foo[abi:Foo_tag]::foo[abi:foo_tag](int)" },
+ {"_ZZN3Foo3fooEiENH4Foo24foo2EOKS0_", "Foo::foo(int)::Foo2::foo2()"},
+ {"_ZZNH3Foo3fooES_iENK4Foo24foo2Ev", "Foo::foo(int)::Foo2::foo2() const" },
+ {"_ZNH3FooclERKS_", "Foo::operator()()"},
};
const unsigned N = sizeof(cases) / sizeof(cases[0]);
More information about the libcxx-commits
mailing list