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); ...@@ -578,6 +578,7 @@ static bool ParseTemplateArgs(State *state);
static bool ParseTemplateArg(State *state); static bool ParseTemplateArg(State *state);
static bool ParseBaseUnresolvedName(State *state); static bool ParseBaseUnresolvedName(State *state);
static bool ParseUnresolvedName(State *state); static bool ParseUnresolvedName(State *state);
static bool ParseUnionSelector(State* state);
static bool ParseExpression(State *state); static bool ParseExpression(State *state);
static bool ParseExprPrimary(State *state); static bool ParseExprPrimary(State *state);
static bool ParseExprCastValue(State *state); static bool ParseExprCastValue(State *state);
...@@ -1743,11 +1744,19 @@ static bool ParseUnresolvedName(State *state) { ...@@ -1743,11 +1744,19 @@ static bool ParseUnresolvedName(State *state) {
return false; 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> // <expression> ::= <1-ary operator-name> <expression>
// ::= <2-ary operator-name> <expression> <expression> // ::= <2-ary operator-name> <expression> <expression>
// ::= <3-ary operator-name> <expression> <expression> <expression> // ::= <3-ary operator-name> <expression> <expression> <expression>
// ::= cl <expression>+ E // ::= cl <expression>+ E
// ::= cp <simple-id> <expression>* E # Clang-specific. // ::= cp <simple-id> <expression>* E # Clang-specific.
// ::= so <type> <expression> [<number>] <union-selector>* [p] E
// ::= cv <type> <expression> # type (expression) // ::= cv <type> <expression> # type (expression)
// ::= cv <type> _ <expression>* E # type (expr-list) // ::= cv <type> _ <expression>* E # type (expr-list)
// ::= st <type> // ::= st <type>
...@@ -1787,6 +1796,18 @@ static bool ParseExpression(State *state) { ...@@ -1787,6 +1796,18 @@ static bool ParseExpression(State *state) {
} }
state->parse_state = copy; 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). // Function-param expression (level 0).
if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) && if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) &&
Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) { Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) {
......
...@@ -300,6 +300,35 @@ TEST(Demangle, AbiTags) { ...@@ -300,6 +300,35 @@ TEST(Demangle, AbiTags) {
EXPECT_STREQ("C[abi:bar][abi:foo]()", tmp); 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 // Test one Rust symbol to exercise Demangle's delegation path. Rust demangling
// itself is more thoroughly tested in demangle_rust_test.cc. // itself is more thoroughly tested in demangle_rust_test.cc.
TEST(Demangle, DelegatesToDemangleRustSymbolEncoding) { 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