Commit c14dfbf9 by Dino Radakovic Committed by Copybara-Service

`demangle`: Parse optional single template argument for built-in types

The optional single template argument for built-in types is not documented in LLVM's comments that list the grammar, but it is [intentionally implemented](https://github.com/llvm/llvm-project/commit/4bc4d51c18d5c087dfbdad1753c84bba8dbf3be0).

PiperOrigin-RevId: 606843797
Change-Id: Ib5ef1983812e9ea68a39fe64b87b6ad6ce81b93c
parent 0a362eb2
...@@ -1297,32 +1297,39 @@ static bool ParseCVQualifiers(State *state) { ...@@ -1297,32 +1297,39 @@ static bool ParseCVQualifiers(State *state) {
} }
// <builtin-type> ::= v, etc. # single-character builtin types // <builtin-type> ::= v, etc. # single-character builtin types
// ::= u <source-name> // ::= u <source-name> [I <type> E]
// ::= Dd, etc. # two-character builtin types // ::= Dd, etc. # two-character builtin types
// //
// Not supported: // Not supported:
// ::= DF <number> _ # _FloatN (N bits) // ::= DF <number> _ # _FloatN (N bits)
// //
// NOTE: [I <type> E] is a vendor extension (http://shortn/_FrINpH1XC5).
static bool ParseBuiltinType(State *state) { static bool ParseBuiltinType(State *state) {
ComplexityGuard guard(state); ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false; if (guard.IsTooComplex()) return false;
const AbbrevPair *p;
for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) { for (const AbbrevPair *p = kBuiltinTypeList; p->abbrev != nullptr; ++p) {
// Guaranteed only 1- or 2-character strings in kBuiltinTypeList. // Guaranteed only 1- or 2-character strings in kBuiltinTypeList.
if (p->abbrev[1] == '\0') { if (p->abbrev[1] == '\0') {
if (ParseOneCharToken(state, p->abbrev[0])) { if (ParseOneCharToken(state, p->abbrev[0])) {
MaybeAppend(state, p->real_name); MaybeAppend(state, p->real_name);
return true; return true; // ::= v, etc. # single-character builtin types
} }
} else if (p->abbrev[2] == '\0' && ParseTwoCharToken(state, p->abbrev)) { } else if (p->abbrev[2] == '\0' && ParseTwoCharToken(state, p->abbrev)) {
MaybeAppend(state, p->real_name); MaybeAppend(state, p->real_name);
return true; return true; // ::= Dd, etc. # two-character builtin types
} }
} }
ParseState copy = state->parse_state; ParseState copy = state->parse_state;
if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) { if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
return true; copy = state->parse_state;
if (ParseOneCharToken(state, 'I') && ParseType(state) &&
ParseOneCharToken(state, 'E')) {
return true; // ::= u <source-name> I <type> E
}
state->parse_state = copy;
return true; // ::= u <source-name>
} }
state->parse_state = copy; state->parse_state = copy;
return false; return false;
......
...@@ -150,6 +150,38 @@ TEST(Demangle, FunctionTemplateTemplateParamWithConstrainedArg) { ...@@ -150,6 +150,38 @@ TEST(Demangle, FunctionTemplateTemplateParamWithConstrainedArg) {
EXPECT_STREQ(tmp, "foo<>()"); EXPECT_STREQ(tmp, "foo<>()");
} }
TEST(Demangle, NonTemplateBuiltinType) {
char tmp[100];
// void foo(__my_builtin_type t);
//
// foo({});
ASSERT_TRUE(Demangle("_Z3foou17__my_builtin_type", tmp, sizeof(tmp)));
EXPECT_STREQ(tmp, "foo()");
}
TEST(Demangle, SingleArgTemplateBuiltinType) {
char tmp[100];
// template <typename T>
// __my_builtin_type<T> foo();
//
// foo<int>();
ASSERT_TRUE(Demangle("_Z3fooIiEu17__my_builtin_typeIT_Ev", tmp, sizeof(tmp)));
EXPECT_STREQ(tmp, "foo<>()");
}
TEST(Demangle, FailsOnTwoArgTemplateBuiltinType) {
char tmp[100];
// template <typename T, typename U>
// __my_builtin_type<T, U> foo();
//
// foo<int, char>();
ASSERT_FALSE(
Demangle("_Z3fooIicEu17__my_builtin_typeIT_T0_Ev", tmp, sizeof(tmp)));
}
// 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