Commit 88c1f181 by Chris Mihelich Committed by Copybara-Service

Demangle C++ so ... E encodings (typically array-to-pointer decay).

PiperOrigin-RevId: 636566755
Change-Id: I2c8c1f19a67a7a487dd2bbb46c17f9fb4e2b037c
parent 41492937
......@@ -578,6 +578,7 @@ static bool ParseTemplateArgs(State *state);
static bool ParseTemplateArg(State *state);
static bool ParseBaseUnresolvedName(State *state);
static bool ParseUnresolvedName(State *state);
static bool ParseUnionSelector(State* state);
static bool ParseExpression(State *state);
static bool ParseExprPrimary(State *state);
static bool ParseExprCastValue(State *state);
......@@ -1743,11 +1744,19 @@ static bool ParseUnresolvedName(State *state) {
return false;
}
// <union-selector> ::= _ [<number>]
//
// https://github.com/itanium-cxx-abi/cxx-abi/issues/47
static bool ParseUnionSelector(State *state) {
return ParseOneCharToken(state, '_') && Optional(ParseNumber(state, nullptr));
}
// <expression> ::= <1-ary operator-name> <expression>
// ::= <2-ary operator-name> <expression> <expression>
// ::= <3-ary operator-name> <expression> <expression> <expression>
// ::= cl <expression>+ E
// ::= cp <simple-id> <expression>* E # Clang-specific.
// ::= so <type> <expression> [<number>] <union-selector>* [p] E
// ::= cv <type> <expression> # type (expression)
// ::= cv <type> _ <expression>* E # type (expr-list)
// ::= st <type>
......@@ -1787,6 +1796,18 @@ static bool ParseExpression(State *state) {
}
state->parse_state = copy;
// <expression> ::= so <type> <expression> [<number>] <union-selector>* [p] E
//
// https://github.com/itanium-cxx-abi/cxx-abi/issues/47
if (ParseTwoCharToken(state, "so") && ParseType(state) &&
ParseExpression(state) && Optional(ParseNumber(state, nullptr)) &&
ZeroOrMore(ParseUnionSelector, state) &&
Optional(ParseOneCharToken(state, 'p')) &&
ParseOneCharToken(state, 'E')) {
return true;
}
state->parse_state = copy;
// Function-param expression (level 0).
if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) &&
Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) {
......
......@@ -300,6 +300,35 @@ TEST(Demangle, AbiTags) {
EXPECT_STREQ("C[abi:bar][abi:foo]()", tmp);
}
// Test subobject-address template parameters.
TEST(Demangle, SubobjectAddresses) {
char tmp[80];
// void f<a.<char const at offset 123>>()
EXPECT_TRUE(Demangle("_Z1fIXsoKcL_Z1aE123EEEvv", tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
// void f<&a.<char const at offset 0>>()
EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aEEEEvv", tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
// void f<&a.<char const at offset 123>>()
EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123EEEvv", tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
// void f<&a.<char const at offset 123>>(), past the end this time
EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123pEEEvv", tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
// void f<&a.<char const at offset 0>>() with union-selectors
EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE__1_234EEEvv", tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
// void f<&a.<char const at offset 123>>(), past the end, with union-selector
EXPECT_TRUE(Demangle("_Z1fIXadsoKcL_Z1aE123_456pEEEvv", tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
}
// Test one Rust symbol to exercise Demangle's delegation path. Rust demangling
// itself is more thoroughly tested in demangle_rust_test.cc.
TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) {
......
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