From 305a0088cebf6bcae3cd98aaf0bb5fc5f64d0912 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 13 Jul 2022 10:42:00 -0700 Subject: Support [[gnu::abi_tag("xyz")]] demangling. PiperOrigin-RevId: 460752575 Change-Id: I9629504b5c63dbfe367cd55e287a782cd8fa546c --- absl/debugging/internal/demangle.cc | 44 +++++++++++++++++++++++++------- absl/debugging/internal/demangle_test.cc | 24 +++++++++++++++++ 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 93ae3279..9ac644ef 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -548,6 +548,7 @@ static bool ParseSpecialName(State *state); static bool ParseCallOffset(State *state); static bool ParseNVOffset(State *state); static bool ParseVOffset(State *state); +static bool ParseAbiTags(State *state); static bool ParseCtorDtorName(State *state); static bool ParseDecltype(State *state); static bool ParseType(State *state); @@ -601,7 +602,7 @@ static bool ParseSubstitution(State *state, bool accept_std); // // Reference: // - Itanium C++ ABI -// +// // ::= _Z static bool ParseMangledName(State *state) { @@ -741,17 +742,42 @@ static bool ParsePrefix(State *state) { return true; } -// ::= -// ::= -// ::= -// ::= // GCC extension; see below. -// ::= +// ::= [] +// ::= [] +// ::= [] +// ::= [] +// ::= [] +// +// is a GCC extension; see below. static bool ParseUnqualifiedName(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; - return (ParseOperatorName(state, nullptr) || ParseCtorDtorName(state) || - ParseSourceName(state) || ParseLocalSourceName(state) || - ParseUnnamedTypeName(state)); + if (ParseOperatorName(state, nullptr) || ParseCtorDtorName(state) || + ParseSourceName(state) || ParseLocalSourceName(state) || + ParseUnnamedTypeName(state)) { + return ParseAbiTags(state); + } + return false; +} + +// ::= [] +// ::= B +static bool ParseAbiTags(State *state) { + ComplexityGuard guard(state); + if (guard.IsTooComplex()) return false; + + while (ParseOneCharToken(state, 'B')) { + ParseState copy = state->parse_state; + MaybeAppend(state, "[abi:"); + + if (!ParseSourceName(state)) { + state->parse_state = copy; + return false; + } + MaybeAppend(state, "]"); + } + + return true; } // ::= diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 6b142902..8463a2b7 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -102,6 +102,30 @@ TEST(Demangle, Clones) { EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp))); } +// Test the GNU abi_tag extension. +TEST(Demangle, AbiTags) { + char tmp[80]; + + // Mangled name generated via: + // struct [[gnu::abi_tag("abc")]] A{}; + // A a; + EXPECT_TRUE(Demangle("_Z1aB3abc", tmp, sizeof(tmp))); + EXPECT_STREQ("a[abi:abc]", tmp); + + // Mangled name generated via: + // struct B { + // B [[gnu::abi_tag("xyz")]] (){}; + // }; + // B b; + EXPECT_TRUE(Demangle("_ZN1BC2B3xyzEv", tmp, sizeof(tmp))); + EXPECT_STREQ("B::B[abi:xyz]()", tmp); + + // Mangled name generated via: + // [[gnu::abi_tag("foo", "bar")]] void C() {} + EXPECT_TRUE(Demangle("_Z1CB3barB3foov", tmp, sizeof(tmp))); + EXPECT_STREQ("C[abi:bar][abi:foo]()", tmp); +} + // Tests that verify that Demangle footprint is within some limit. // They are not to be run under sanitizers as the sanitizers increase // stack consumption by about 4x. -- cgit v1.2.3