Skip to content

Commit

Permalink
demangle: Parse template template and C++20 lambda template param s…
Browse files Browse the repository at this point in the history
…ubstitutions

These were described in itanium-cxx-abi/cxx-abi#85 and implemented by LLVM.

PiperOrigin-RevId: 607555558
Change-Id: I9991ac88c1fcf63b25b93d93977a83ca343cdb5d
  • Loading branch information
dinord authored and netkex committed Apr 3, 2024
1 parent d9e4261 commit 2235093
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
20 changes: 18 additions & 2 deletions absl/debugging/internal/demangle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1434,19 +1434,35 @@ static bool ParsePointerToMemberType(State *state) {

// <template-param> ::= T_
// ::= T <parameter-2 non-negative number> _
// ::= TL <level-1> __
// ::= TL <level-1> _ <parameter-2 non-negative number> _
static bool ParseTemplateParam(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
if (ParseTwoCharToken(state, "T_")) {
MaybeAppend(state, "?"); // We don't support template substitutions.
return true;
return true; // ::= T_
}

ParseState copy = state->parse_state;
if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
ParseOneCharToken(state, '_')) {
MaybeAppend(state, "?"); // We don't support template substitutions.
return true;
return true; // ::= T <parameter-2 non-negative number> _
}
state->parse_state = copy;

if (ParseTwoCharToken(state, "TL") && ParseNumber(state, nullptr)) {
if (ParseTwoCharToken(state, "__")) {
MaybeAppend(state, "?"); // We don't support template substitutions.
return true; // ::= TL <level-1> __
}

if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr) &&
ParseOneCharToken(state, '_')) {
MaybeAppend(state, "?"); // We don't support template substitutions.
return true; // ::= TL <level-1> _ <parameter-2 non-negative number> _
}
}
state->parse_state = copy;
return false;
Expand Down
30 changes: 30 additions & 0 deletions absl/debugging/internal/demangle_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,36 @@ TEST(Demangle, FailsOnTwoArgTemplateBuiltinType) {
Demangle("_Z3fooIicEu17__my_builtin_typeIT_T0_Ev", tmp, sizeof(tmp)));
}

TEST(Demangle, TemplateTemplateParamSubstitution) {
char tmp[100];

// template <typename T>
// concept True = true;
//
// template<std::integral T, T> struct Foolable {};
// template<template<typename T, T> typename> void foo() {}
//
// template void foo<Foolable>();
ASSERT_TRUE(Demangle("_Z3fooITtTyTnTL0__E8FoolableEvv", tmp, sizeof(tmp)));
EXPECT_STREQ(tmp, "foo<>()");
}

TEST(Demangle, TemplateParamSubstitutionWithGenericLambda) {
char tmp[100];

// template <typename>
// struct Fooer {
// template <typename>
// void foo(decltype([](auto x, auto y) {})) {}
// };
//
// Fooer<int> f;
// f.foo<int>({});
ASSERT_TRUE(
Demangle("_ZN5FooerIiE3fooIiEEvNS0_UlTL0__TL0_0_E_E", tmp, sizeof(tmp)));
EXPECT_STREQ(tmp, "Fooer<>::foo<>()");
}

// Test corner cases of boundary conditions.
TEST(Demangle, CornerCases) {
char tmp[10];
Expand Down

0 comments on commit 2235093

Please sign in to comment.