mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 20:14:23 +08:00
Parse <discriminator> more accurately.
PiperOrigin-RevId: 638778076 Change-Id: I97b9bab2d1b6f87d2f449777145f932949d61a38
This commit is contained in:
committed by
Copybara-Service
parent
c8671e7542
commit
9a2da1a407
@@ -2387,12 +2387,22 @@ static bool ParseLocalName(State *state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// <discriminator> := _ <(non-negative) number>
|
||||
// <discriminator> := _ <digit>
|
||||
// := __ <number (>= 10)> _
|
||||
static bool ParseDiscriminator(State *state) {
|
||||
ComplexityGuard guard(state);
|
||||
if (guard.IsTooComplex()) return false;
|
||||
ParseState copy = state->parse_state;
|
||||
if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
|
||||
|
||||
// Both forms start with _ so parse that first.
|
||||
if (!ParseOneCharToken(state, '_')) return false;
|
||||
|
||||
// <digit>
|
||||
if (ParseDigit(state, nullptr)) return true;
|
||||
|
||||
// _ <number> _
|
||||
if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr) &&
|
||||
ParseOneCharToken(state, '_')) {
|
||||
return true;
|
||||
}
|
||||
state->parse_state = copy;
|
||||
|
||||
@@ -479,6 +479,53 @@ TEST(Demangle, Clones) {
|
||||
EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
|
||||
}
|
||||
|
||||
TEST(Demangle, Discriminators) {
|
||||
char tmp[80];
|
||||
|
||||
// Source:
|
||||
//
|
||||
// using Thunk = void (*)();
|
||||
//
|
||||
// Thunk* f() {
|
||||
// static Thunk thunks[12] = {};
|
||||
//
|
||||
// #define THUNK(i) [backslash here]
|
||||
// do { struct S { static void g() {} }; thunks[i] = &S::g; } while (0)
|
||||
//
|
||||
// THUNK(0);
|
||||
// [... repeat for 1 to 10 ...]
|
||||
// THUNK(11);
|
||||
//
|
||||
// return thunks;
|
||||
// }
|
||||
//
|
||||
// The test inputs are manglings of some of the S::g member functions.
|
||||
|
||||
// The first one omits the discriminator.
|
||||
EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gEv", tmp, sizeof(tmp)));
|
||||
EXPECT_STREQ("f()::S::g()", tmp);
|
||||
|
||||
// The second one encodes 0.
|
||||
EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_0v", tmp, sizeof(tmp)));
|
||||
EXPECT_STREQ("f()::S::g()", tmp);
|
||||
|
||||
// The eleventh one encodes 9.
|
||||
EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_9v", tmp, sizeof(tmp)));
|
||||
EXPECT_STREQ("f()::S::g()", tmp);
|
||||
|
||||
// The twelfth one encodes 10 with extra underscores delimiting it.
|
||||
EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE__10_v", tmp, sizeof(tmp)));
|
||||
EXPECT_STREQ("f()::S::g()", tmp);
|
||||
}
|
||||
|
||||
TEST(Demangle, SingleDigitDiscriminatorFollowedByADigit) {
|
||||
char tmp[80];
|
||||
|
||||
// Don't parse 911 as a number.
|
||||
EXPECT_TRUE(Demangle("_ZZ1fvEN1S1gE_911return_type", tmp, sizeof(tmp)));
|
||||
EXPECT_STREQ("f()::S::g()", tmp);
|
||||
}
|
||||
|
||||
TEST(Demangle, LiteralOfGlobalNamespaceEnumType) {
|
||||
char tmp[80];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user