[libcxx-commits] [libcxxabi] [llvm] [libcxxabi][ItaniumDemangle] Demangle explicitly named object parameters (PR #72881)
Michael Buch via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Nov 25 01:15:01 PST 2023
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/72881
>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 1/9] [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]);
>From b728f87399c15c08d1bd1e338a695a3ab3fe3344 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 24 Nov 2023 12:47:01 +0000
Subject: [PATCH 2/9] fixup! print the explicit parameter
---
libcxxabi/src/demangle/ItaniumDemangle.h | 32 +++++++++++++++++++++---
libcxxabi/src/demangle/ItaniumNodes.def | 1 +
libcxxabi/test/test_demangle.pass.cpp | 16 ++++++------
3 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index f9a0c059e86e8bd..57dda9b42106a56 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -890,6 +890,27 @@ class DynamicExceptionSpec : public Node {
}
};
+/// Represents the explicitly named object parameter.
+/// E.g.,
+/// \code{.cpp}
+/// struct Foo {
+/// void bar(this Foo && self);
+/// };
+/// \endcode
+class ExplicitObjectParameter final : public Node {
+ Node *Base;
+
+public:
+ ExplicitObjectParameter(Node *Base_)
+ : Node(KExplicitObjectParameter, Cache::Yes), Base(Base_) {}
+
+ template <typename Fn> void match(Fn F) const { F(Base); }
+
+ void printLeft(OutputBuffer &OB) const override { OB += "this "; }
+
+ void printRight(OutputBuffer &OB) const override { Base->print(OB); }
+};
+
class FunctionEncoding final : public Node {
const Node *Ret;
const Node *Name;
@@ -5433,11 +5454,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
Node *Ty = getDerived().parseType();
if (Ty == nullptr)
return nullptr;
+
+ const bool IsFirstParam = (Names.size() - ParamsBegin) == 0;
+ if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
+ Ty = make<ExplicitObjectParameter>(Ty);
+
+ if (Ty == nullptr)
+ 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/src/demangle/ItaniumNodes.def b/libcxxabi/src/demangle/ItaniumNodes.def
index e27c111de3389c5..18f5d52b47e9113 100644
--- a/libcxxabi/src/demangle/ItaniumNodes.def
+++ b/libcxxabi/src/demangle/ItaniumNodes.def
@@ -99,5 +99,6 @@ NODE(RequiresExpr)
NODE(ExprRequirement)
NODE(TypeRequirement)
NODE(NestedRequirement)
+NODE(ExplicitObjectParameter)
#undef NODE
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index a6b6d45a3783bb1..bf5473ee7eb8a2f 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30176,14 +30176,14 @@ const char* cases[][2] =
{"_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()()"},
+ {"_ZNH3Foo3fooES_i", "Foo::foo(this Foo, int)"},
+ {"_ZNH3Foo3fooERKS_i", "Foo::foo(this Foo const&, int)"},
+ {"_ZNH1X3fooIRS_EEvOT_i", "void X::foo<X&>(this X&, int)"},
+ {"_ZZNH2ns3Foo3fooES0_iENH4Foo24foo2EOKS1_", "ns::Foo::foo(this ns::Foo, int)::Foo2::foo2(this Foo2 const&&)" },
+ {"_ZNH2ns3FooB7Foo_tag3fooB7foo_tagERKS0_i", "ns::Foo[abi:Foo_tag]::foo[abi:foo_tag](this ns::Foo[abi:Foo_tag] const&, int)" },
+ {"_ZZN3Foo3fooEiENH4Foo24foo2EOKS0_", "Foo::foo(int)::Foo2::foo2(this Foo2 const&&)"},
+ {"_ZZNH3Foo3fooES_iENK4Foo24foo2Ev", "Foo::foo(this Foo, int)::Foo2::foo2() const" },
+ {"_ZNH3FooclERKS_", "Foo::operator()(this Foo const&)"},
};
const unsigned N = sizeof(cases) / sizeof(cases[0]);
>From 9b1dde91ff6cbadc8f9645709f493f38ff5f6d1f Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 24 Nov 2023 13:03:59 +0000
Subject: [PATCH 3/9] fixup! assert nullness in ExplicitObjectParamter
constructor
---
libcxxabi/src/demangle/ItaniumDemangle.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 57dda9b42106a56..4874fdfeb67398c 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -902,7 +902,9 @@ class ExplicitObjectParameter final : public Node {
public:
ExplicitObjectParameter(Node *Base_)
- : Node(KExplicitObjectParameter, Cache::Yes), Base(Base_) {}
+ : Node(KExplicitObjectParameter, Cache::Yes), Base(Base_) {
+ assert(Base != nullptr);
+ }
template <typename Fn> void match(Fn F) const { F(Base); }
>From 6122d54236563dbfad68ffe15ad275a323e7732e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 24 Nov 2023 22:32:21 +0000
Subject: [PATCH 4/9] fixup! remove redundant printRight; simplify IsFirstParam
check
---
libcxxabi/src/demangle/ItaniumDemangle.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 4874fdfeb67398c..e7d668291b56bb2 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -902,13 +902,16 @@ class ExplicitObjectParameter final : public Node {
public:
ExplicitObjectParameter(Node *Base_)
- : Node(KExplicitObjectParameter, Cache::Yes), Base(Base_) {
+ : Node(KExplicitObjectParameter), Base(Base_) {
assert(Base != nullptr);
}
template <typename Fn> void match(Fn F) const { F(Base); }
- void printLeft(OutputBuffer &OB) const override { OB += "this "; }
+ void printLeft(OutputBuffer &OB) const override {
+ OB += "this ";
+ Base->print(OB);
+ }
void printRight(OutputBuffer &OB) const override { Base->print(OB); }
};
@@ -5457,7 +5460,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
if (Ty == nullptr)
return nullptr;
- const bool IsFirstParam = (Names.size() - ParamsBegin) == 0;
+ const bool IsFirstParam = ParamsBegin == Names.size();
if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
Ty = make<ExplicitObjectParameter>(Ty);
>From 59b24f45d66d6888e945c4531f886beae0cc7424 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 24 Nov 2023 22:34:40 +0000
Subject: [PATCH 5/9] fixup! sync libcxxabi into llvm
---
llvm/include/llvm/Demangle/ItaniumDemangle.h | 62 +++++++++++++++++---
llvm/include/llvm/Demangle/ItaniumNodes.def | 1 +
2 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index f68c37258ce0992..59aed240b7e24ed 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -19,6 +19,7 @@
#include "DemangleConfig.h"
#include "StringViewExtras.h"
#include "Utility.h"
+#include <__cxxabi_config.h>
#include <algorithm>
#include <cassert>
#include <cctype>
@@ -889,6 +890,32 @@ class DynamicExceptionSpec : public Node {
}
};
+/// Represents the explicitly named object parameter.
+/// E.g.,
+/// \code{.cpp}
+/// struct Foo {
+/// void bar(this Foo && self);
+/// };
+/// \endcode
+class ExplicitObjectParameter final : public Node {
+ Node *Base;
+
+public:
+ ExplicitObjectParameter(Node *Base_)
+ : Node(KExplicitObjectParameter), Base(Base_) {
+ assert(Base != nullptr);
+ }
+
+ template <typename Fn> void match(Fn F) const { F(Base); }
+
+ void printLeft(OutputBuffer &OB) const override {
+ OB += "this ";
+ Base->print(OB);
+ }
+
+ void printRight(OutputBuffer &OB) const override { Base->print(OB); }
+};
+
class FunctionEncoding final : public Node {
const Node *Ret;
const Node *Name;
@@ -2779,6 +2806,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()) {}
@@ -3437,15 +3465,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;
@@ -5421,6 +5459,14 @@ Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
Node *Ty = getDerived().parseType();
if (Ty == nullptr)
return nullptr;
+
+ const bool IsFirstParam = ParamsBegin == Names.size();
+ if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
+ Ty = make<ExplicitObjectParameter>(Ty);
+
+ if (Ty == nullptr)
+ return nullptr;
+
Names.push_back(Ty);
} while (!IsEndOfEncoding() && look() != 'Q');
Params = popTrailingNodeArray(ParamsBegin);
diff --git a/llvm/include/llvm/Demangle/ItaniumNodes.def b/llvm/include/llvm/Demangle/ItaniumNodes.def
index 30a93eccaee37e9..330552663ee658d 100644
--- a/llvm/include/llvm/Demangle/ItaniumNodes.def
+++ b/llvm/include/llvm/Demangle/ItaniumNodes.def
@@ -99,5 +99,6 @@ NODE(RequiresExpr)
NODE(ExprRequirement)
NODE(TypeRequirement)
NODE(NestedRequirement)
+NODE(ExplicitObjectParameter)
#undef NODE
>From cb67b33e8fa422bac47943604ae84465c5aa027a Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 24 Nov 2023 22:37:15 +0000
Subject: [PATCH 6/9] fixup! remove printRight
---
libcxxabi/src/demangle/ItaniumDemangle.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index e7d668291b56bb2..caec1a0253b2d7b 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -912,8 +912,6 @@ class ExplicitObjectParameter final : public Node {
OB += "this ";
Base->print(OB);
}
-
- void printRight(OutputBuffer &OB) const override { Base->print(OB); }
};
class FunctionEncoding final : public Node {
>From c69c9e0bd3cad7b18d25fbd0021a972d0eca7530 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 24 Nov 2023 22:37:41 +0000
Subject: [PATCH 7/9] fixup! re-sync libcxxabi to llvm
---
llvm/include/llvm/Demangle/ItaniumDemangle.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 59aed240b7e24ed..7fc81b27f059d44 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -912,8 +912,6 @@ class ExplicitObjectParameter final : public Node {
OB += "this ";
Base->print(OB);
}
-
- void printRight(OutputBuffer &OB) const override { Base->print(OB); }
};
class FunctionEncoding final : public Node {
>From 4360fb11d04e5ff75fb8c110224de4935348c0f3 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 25 Nov 2023 08:32:19 +0000
Subject: [PATCH 8/9] fixup! assert -> DEMANGLE_ASSERT
---
libcxxabi/src/demangle/ItaniumDemangle.h | 4 +++-
llvm/include/llvm/Demangle/ItaniumDemangle.h | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index caec1a0253b2d7b..9f0894406015090 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -903,7 +903,9 @@ class ExplicitObjectParameter final : public Node {
public:
ExplicitObjectParameter(Node *Base_)
: Node(KExplicitObjectParameter), Base(Base_) {
- assert(Base != nullptr);
+ DEMANGLE_ASSERT(
+ Base != nullptr,
+ "Creating an ExplicitObjectParameter without a valid Base Node.");
}
template <typename Fn> void match(Fn F) const { F(Base); }
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 7fc81b27f059d44..50ec5d48eb5e772 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -903,7 +903,9 @@ class ExplicitObjectParameter final : public Node {
public:
ExplicitObjectParameter(Node *Base_)
: Node(KExplicitObjectParameter), Base(Base_) {
- assert(Base != nullptr);
+ DEMANGLE_ASSERT(
+ Base != nullptr,
+ "Creating an ExplicitObjectParameter without a valid Base Node.");
}
template <typename Fn> void match(Fn F) const { F(Base); }
>From 9197ebd298cc5bc548a79ae4378f3ac09834ce50 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 25 Nov 2023 09:14:19 +0000
Subject: [PATCH 9/9] fixup! remove breaking header
---
llvm/include/llvm/Demangle/ItaniumDemangle.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 50ec5d48eb5e772..4e862561f12c5f9 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -19,7 +19,6 @@
#include "DemangleConfig.h"
#include "StringViewExtras.h"
#include "Utility.h"
-#include <__cxxabi_config.h>
#include <algorithm>
#include <cassert>
#include <cctype>
More information about the libcxx-commits
mailing list