Skip to content

Commit 2235093

Browse files
dinordnetkex
authored andcommitted
demangle: Parse template template and C++20 lambda template param substitutions
These were described in itanium-cxx-abi/cxx-abi#85 and implemented by LLVM. PiperOrigin-RevId: 607555558 Change-Id: I9991ac88c1fcf63b25b93d93977a83ca343cdb5d
1 parent d9e4261 commit 2235093

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

absl/debugging/internal/demangle.cc

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,19 +1434,35 @@ static bool ParsePointerToMemberType(State *state) {
14341434

14351435
// <template-param> ::= T_
14361436
// ::= T <parameter-2 non-negative number> _
1437+
// ::= TL <level-1> __
1438+
// ::= TL <level-1> _ <parameter-2 non-negative number> _
14371439
static bool ParseTemplateParam(State *state) {
14381440
ComplexityGuard guard(state);
14391441
if (guard.IsTooComplex()) return false;
14401442
if (ParseTwoCharToken(state, "T_")) {
14411443
MaybeAppend(state, "?"); // We don't support template substitutions.
1442-
return true;
1444+
return true; // ::= T_
14431445
}
14441446

14451447
ParseState copy = state->parse_state;
14461448
if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
14471449
ParseOneCharToken(state, '_')) {
14481450
MaybeAppend(state, "?"); // We don't support template substitutions.
1449-
return true;
1451+
return true; // ::= T <parameter-2 non-negative number> _
1452+
}
1453+
state->parse_state = copy;
1454+
1455+
if (ParseTwoCharToken(state, "TL") && ParseNumber(state, nullptr)) {
1456+
if (ParseTwoCharToken(state, "__")) {
1457+
MaybeAppend(state, "?"); // We don't support template substitutions.
1458+
return true; // ::= TL <level-1> __
1459+
}
1460+
1461+
if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr) &&
1462+
ParseOneCharToken(state, '_')) {
1463+
MaybeAppend(state, "?"); // We don't support template substitutions.
1464+
return true; // ::= TL <level-1> _ <parameter-2 non-negative number> _
1465+
}
14501466
}
14511467
state->parse_state = copy;
14521468
return false;

absl/debugging/internal/demangle_test.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,36 @@ TEST(Demangle, FailsOnTwoArgTemplateBuiltinType) {
182182
Demangle("_Z3fooIicEu17__my_builtin_typeIT_T0_Ev", tmp, sizeof(tmp)));
183183
}
184184

185+
TEST(Demangle, TemplateTemplateParamSubstitution) {
186+
char tmp[100];
187+
188+
// template <typename T>
189+
// concept True = true;
190+
//
191+
// template<std::integral T, T> struct Foolable {};
192+
// template<template<typename T, T> typename> void foo() {}
193+
//
194+
// template void foo<Foolable>();
195+
ASSERT_TRUE(Demangle("_Z3fooITtTyTnTL0__E8FoolableEvv", tmp, sizeof(tmp)));
196+
EXPECT_STREQ(tmp, "foo<>()");
197+
}
198+
199+
TEST(Demangle, TemplateParamSubstitutionWithGenericLambda) {
200+
char tmp[100];
201+
202+
// template <typename>
203+
// struct Fooer {
204+
// template <typename>
205+
// void foo(decltype([](auto x, auto y) {})) {}
206+
// };
207+
//
208+
// Fooer<int> f;
209+
// f.foo<int>({});
210+
ASSERT_TRUE(
211+
Demangle("_ZN5FooerIiE3fooIiEEvNS0_UlTL0__TL0_0_E_E", tmp, sizeof(tmp)));
212+
EXPECT_STREQ(tmp, "Fooer<>::foo<>()");
213+
}
214+
185215
// Test corner cases of boundary conditions.
186216
TEST(Demangle, CornerCases) {
187217
char tmp[10];

0 commit comments

Comments
 (0)