From 2a40eb6086cf10d1c3f148db6c5906b0aaa2ff90 Mon Sep 17 00:00:00 2001 From: Chris Mihelich Date: Thu, 6 Jun 2024 13:57:54 -0700 Subject: Demangle C++20 constrained friend names, F ( | ). PiperOrigin-RevId: 641011959 Change-Id: I844d4eb99a9f9da160bb53e491dee753a70750df --- absl/debugging/internal/demangle.cc | 14 ++++++++++++++ absl/debugging/internal/demangle_test.cc | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'absl') diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 7901a410..42c10bbe 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -823,8 +823,13 @@ static bool ParsePrefix(State *state) { // ::= [] // ::= [] // ::= DC + E # C++17 structured binding +// ::= F # C++20 constrained friend +// ::= F # C++20 constrained friend // // is a GCC extension; see below. +// +// For the F notation for constrained friends, see +// https://github.com/itanium-cxx-abi/cxx-abi/issues/24#issuecomment-1491130332. static bool ParseUnqualifiedName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; @@ -841,6 +846,15 @@ static bool ParseUnqualifiedName(State *state) { return true; } state->parse_state = copy; + + // F + // F + if (ParseOneCharToken(state, 'F') && MaybeAppend(state, "friend ") && + (ParseSourceName(state) || ParseOperatorName(state, nullptr))) { + return true; + } + state->parse_state = copy; + return false; } diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 1d108c8b..68ab8a3c 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -160,6 +160,34 @@ TEST(Demangle, ConstrainedAutoInFunctionTemplate) { EXPECT_STREQ(tmp, "f<>()"); } +TEST(Demangle, ConstrainedFriendFunctionTemplate) { + char tmp[100]; + + // Source: + // + // namespace ns { + // template struct Y { + // friend void y(Y) requires true {} + // }; + // } // namespace ns + // + // y(ns::Y{}); + // + // LLVM demangling: + // + // ns::Y::friend y(ns::Y) requires true + ASSERT_TRUE(Demangle("_ZN2ns1YIiEF1yES1_QLb1E", tmp, sizeof(tmp))); + EXPECT_STREQ(tmp, "ns::Y<>::friend y()"); +} + +TEST(Demangle, ConstrainedFriendOperatorTemplate) { + char tmp[100]; + + // ns::Y::friend operator*(ns::Y) requires true + ASSERT_TRUE(Demangle("_ZN2ns1YIiEFdeES1_QLb1E", tmp, sizeof(tmp))); + EXPECT_STREQ(tmp, "ns::Y<>::friend operator*()"); +} + TEST(Demangle, NonTemplateBuiltinType) { char tmp[100]; -- cgit v1.2.3