Support [[gnu::abi_tag("xyz")]] demangling.

PiperOrigin-RevId: 460752575
Change-Id: I9629504b5c63dbfe367cd55e287a782cd8fa546c
pull/1223/head
Abseil Team 3 years ago committed by Copybara-Service
parent d2422b19e9
commit 305a0088ce
  1. 44
      absl/debugging/internal/demangle.cc
  2. 24
      absl/debugging/internal/demangle_test.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
// <https://mentorembedded.github.io/cxx-abi/abi.html#mangling>
// <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling>
// <mangled-name> ::= _Z <encoding>
static bool ParseMangledName(State *state) {
@ -741,17 +742,42 @@ static bool ParsePrefix(State *state) {
return true;
}
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
// ::= <source-name>
// ::= <local-source-name> // GCC extension; see below.
// ::= <unnamed-type-name>
// <unqualified-name> ::= <operator-name> [<abi-tags>]
// ::= <ctor-dtor-name> [<abi-tags>]
// ::= <source-name> [<abi-tags>]
// ::= <local-source-name> [<abi-tags>]
// ::= <unnamed-type-name> [<abi-tags>]
//
// <local-source-name> 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;
}
// <abi-tags> ::= <abi-tag> [<abi-tags>]
// <abi-tag> ::= B <source-name>
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;
}
// <source-name> ::= <positive length number> <identifier>

@ -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.

Loading…
Cancel
Save