diff options
author | Chris Mihelich <cmihelic@google.com> | 2024-06-07 18:27:07 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-06-07 18:27:59 -0700 |
commit | 696b32788ca887881547380530926314c521ea7d (patch) | |
tree | 43d71b9eba21fd1980c09fee75cc950154732b73 /absl/debugging/internal/demangle.cc | |
parent | f875817b18cb6536d82b925305fb321e158f59cb (diff) | |
download | abseil-696b32788ca887881547380530926314c521ea7d.tar.gz abseil-696b32788ca887881547380530926314c521ea7d.tar.bz2 abseil-696b32788ca887881547380530926314c521ea7d.zip |
Try not to lose easy type combinators in S::operator const int*() and the like.
PiperOrigin-RevId: 641411131
Change-Id: Icba1307cccb8957e09f087a7b544f7fe8bfd8333
Diffstat (limited to 'absl/debugging/internal/demangle.cc')
-rw-r--r-- | absl/debugging/internal/demangle.cc | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 7ae21dcb..d97dfad4 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -589,6 +589,7 @@ static bool ParseFloatNumber(State *state); static bool ParseSeqId(State *state); static bool ParseIdentifier(State *state, size_t length); static bool ParseOperatorName(State *state, int *arity); +static bool ParseConversionOperatorType(State *state); static bool ParseSpecialName(State *state); static bool ParseCallOffset(State *state); static bool ParseNVOffset(State *state); @@ -1056,7 +1057,7 @@ static bool ParseOperatorName(State *state, int *arity) { // First check with "cv" (cast) case. ParseState copy = state->parse_state; if (ParseTwoCharToken(state, "cv") && MaybeAppend(state, "operator ") && - EnterNestedName(state) && ParseType(state) && + EnterNestedName(state) && ParseConversionOperatorType(state) && LeaveNestedName(state, copy.nest_level)) { if (arity != nullptr) { *arity = 1; @@ -1105,6 +1106,65 @@ static bool ParseOperatorName(State *state, int *arity) { return false; } +// <operator-name> ::= cv <type> # (cast) +// +// The name of a conversion operator is the one place where cv-qualifiers, *, &, +// and other simple type combinators are expected to appear in our stripped-down +// demangling (elsewhere they appear in function signatures or template +// arguments, which we omit from the output). We make reasonable efforts to +// render simple cases accurately. +static bool ParseConversionOperatorType(State *state) { + ComplexityGuard guard(state); + if (guard.IsTooComplex()) return false; + ParseState copy = state->parse_state; + + // Scan pointers, const, and other easy mangling prefixes with postfix + // demanglings. Remember the range of input for later rescanning. + // + // See `ParseType` and the `switch` below for the meaning of each char. + const char* begin_simple_prefixes = RemainingInput(state); + while (ParseCharClass(state, "OPRCGrVK")) {} + const char* end_simple_prefixes = RemainingInput(state); + + // Emit the base type first. + if (!ParseType(state)) { + state->parse_state = copy; + return false; + } + + // Then rescan the easy type combinators in reverse order to emit their + // demanglings in the expected output order. + while (begin_simple_prefixes != end_simple_prefixes) { + switch (*--end_simple_prefixes) { + case 'P': + MaybeAppend(state, "*"); + break; + case 'R': + MaybeAppend(state, "&"); + break; + case 'O': + MaybeAppend(state, "&&"); + break; + case 'C': + MaybeAppend(state, " _Complex"); + break; + case 'G': + MaybeAppend(state, " _Imaginary"); + break; + case 'r': + MaybeAppend(state, " restrict"); + break; + case 'V': + MaybeAppend(state, " volatile"); + break; + case 'K': + MaybeAppend(state, " const"); + break; + } + } + return true; +} + // <special-name> ::= TV <type> // ::= TT <type> // ::= TI <type> @@ -1442,12 +1502,18 @@ static bool ParseExtendedQualifier(State *state) { ComplexityGuard guard(state); if (guard.IsTooComplex()) return false; ParseState copy = state->parse_state; - if (ParseOneCharToken(state, 'U') && ParseSourceName(state) && - Optional(ParseTemplateArgs(state))) { - return true; + + if (!ParseOneCharToken(state, 'U')) return false; + + bool append = state->parse_state.append; + DisableAppend(state); + if (!ParseSourceName(state)) { + state->parse_state = copy; + return false; } - state->parse_state = copy; - return false; + Optional(ParseTemplateArgs(state)); + RestoreAppend(state, append); + return true; } // <builtin-type> ::= v, etc. # single-character builtin types |