Commit 4580d86d by Dino Radakovic Committed by Copybara-Service

`demangle`: Parse template template and C++20 lambda template param substitutions

These were described in https://github.com/itanium-cxx-abi/cxx-abi/pull/85 and implemented by LLVM.

PiperOrigin-RevId: 607555558
Change-Id: I9991ac88c1fcf63b25b93d93977a83ca343cdb5d
parent d4578efe
...@@ -1434,19 +1434,35 @@ static bool ParsePointerToMemberType(State *state) { ...@@ -1434,19 +1434,35 @@ static bool ParsePointerToMemberType(State *state) {
// <template-param> ::= T_ // <template-param> ::= T_
// ::= T <parameter-2 non-negative number> _ // ::= T <parameter-2 non-negative number> _
// ::= TL <level-1> __
// ::= TL <level-1> _ <parameter-2 non-negative number> _
static bool ParseTemplateParam(State *state) { static bool ParseTemplateParam(State *state) {
ComplexityGuard guard(state); ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false; if (guard.IsTooComplex()) return false;
if (ParseTwoCharToken(state, "T_")) { if (ParseTwoCharToken(state, "T_")) {
MaybeAppend(state, "?"); // We don't support template substitutions. MaybeAppend(state, "?"); // We don't support template substitutions.
return true; return true; // ::= T_
} }
ParseState copy = state->parse_state; ParseState copy = state->parse_state;
if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) && if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
ParseOneCharToken(state, '_')) { ParseOneCharToken(state, '_')) {
MaybeAppend(state, "?"); // We don't support template substitutions. 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; state->parse_state = copy;
return false; return false;
......
...@@ -182,6 +182,36 @@ TEST(Demangle, FailsOnTwoArgTemplateBuiltinType) { ...@@ -182,6 +182,36 @@ TEST(Demangle, FailsOnTwoArgTemplateBuiltinType) {
Demangle("_Z3fooIicEu17__my_builtin_typeIT_T0_Ev", tmp, sizeof(tmp))); 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 corner cases of boundary conditions.
TEST(Demangle, CornerCases) { TEST(Demangle, CornerCases) {
char tmp[10]; char tmp[10];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment