aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Mihelich <cmihelic@google.com>2024-06-06 13:57:54 -0700
committerCopybara-Service <copybara-worker@google.com>2024-06-06 13:58:39 -0700
commit2a40eb6086cf10d1c3f148db6c5906b0aaa2ff90 (patch)
tree60295a9f29640656dfc6ce864590603b55418da6
parent0cd50e6ee37f1bd8be8dd716694470a7f20b6a59 (diff)
downloadabseil-2a40eb6086cf10d1c3f148db6c5906b0aaa2ff90.tar.gz
abseil-2a40eb6086cf10d1c3f148db6c5906b0aaa2ff90.tar.bz2
abseil-2a40eb6086cf10d1c3f148db6c5906b0aaa2ff90.zip
Demangle C++20 constrained friend names, F (<source-name> | <operator-name>).
PiperOrigin-RevId: 641011959 Change-Id: I844d4eb99a9f9da160bb53e491dee753a70750df
-rw-r--r--absl/debugging/internal/demangle.cc14
-rw-r--r--absl/debugging/internal/demangle_test.cc28
2 files changed, 42 insertions, 0 deletions
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) {
// ::= <local-source-name> [<abi-tags>]
// ::= <unnamed-type-name> [<abi-tags>]
// ::= DC <source-name>+ E # C++17 structured binding
+// ::= F <source-name> # C++20 constrained friend
+// ::= F <operator-name> # C++20 constrained friend
//
// <local-source-name> 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 <source-name>
+ // F <operator-name>
+ 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 <class T> struct Y {
+ // friend void y(Y) requires true {}
+ // };
+ // } // namespace ns
+ //
+ // y(ns::Y<int>{});
+ //
+ // LLVM demangling:
+ //
+ // ns::Y<int>::friend y(ns::Y<int>) 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<int>::friend operator*(ns::Y<int>) requires true
+ ASSERT_TRUE(Demangle("_ZN2ns1YIiEFdeES1_QLb1E", tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "ns::Y<>::friend operator*()");
+}
+
TEST(Demangle, NonTemplateBuiltinType) {
char tmp[100];