aboutsummaryrefslogtreecommitdiff
path: root/absl/debugging
diff options
context:
space:
mode:
authorChris Mihelich <cmihelic@google.com>2024-06-04 14:28:23 -0700
committerCopybara-Service <copybara-worker@google.com>2024-06-04 14:29:31 -0700
commitd8e17c009185a3bb305d774aa9e41f3c5de605f6 (patch)
tree350c3ea56cd8d0534b396907897470bb6b5fba98 /absl/debugging
parent36d1644be1fe815cef318e52a3ef4c8f5c50ea01 (diff)
downloadabseil-d8e17c009185a3bb305d774aa9e41f3c5de605f6.tar.gz
abseil-d8e17c009185a3bb305d774aa9e41f3c5de605f6.tar.bz2
abseil-d8e17c009185a3bb305d774aa9e41f3c5de605f6.zip
Demangle types nested under vendor extended types.
PiperOrigin-RevId: 640284003 Change-Id: I3ad2d971383513c7eeb5e3179e50c036cf7aa020
Diffstat (limited to 'absl/debugging')
-rw-r--r--absl/debugging/internal/demangle.cc19
-rw-r--r--absl/debugging/internal/demangle_test.cc21
2 files changed, 39 insertions, 1 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index 99461f3f..e9edd4f8 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -599,6 +599,7 @@ static bool ParseDecltype(State *state);
static bool ParseType(State *state);
static bool ParseCVQualifiers(State *state);
static bool ParseBuiltinType(State *state);
+static bool ParseVendorExtendedType(State *state);
static bool ParseFunctionType(State *state);
static bool ParseBareFunctionType(State *state);
static bool ParseOverloadAttribute(State *state);
@@ -785,6 +786,7 @@ static bool ParseNestedName(State *state) {
// <template-prefix> ::= <prefix> <(template) unqualified-name>
// ::= <template-param>
// ::= <substitution>
+// ::= <vendor-extended-type>
static bool ParsePrefix(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
@@ -793,6 +795,11 @@ static bool ParsePrefix(State *state) {
MaybeAppendSeparator(state);
if (ParseTemplateParam(state) || ParseDecltype(state) ||
ParseSubstitution(state, /*accept_std=*/true) ||
+ // Although the official grammar does not mention it, nested-names
+ // shaped like Nu14__some_builtinIiE6memberE occur in practice, and it
+ // is not clear what else a compiler is supposed to do when a
+ // vendor-extended type has named members.
+ ParseVendorExtendedType(state) ||
ParseUnscopedName(state) ||
(ParseOneCharToken(state, 'M') && ParseUnnamedTypeName(state))) {
has_something = true;
@@ -1373,7 +1380,7 @@ static bool ParseCVQualifiers(State *state) {
}
// <builtin-type> ::= v, etc. # single-character builtin types
-// ::= u <source-name> [I <type> E]
+// ::= <vendor-extended-type>
// ::= Dd, etc. # two-character builtin types
//
// Not supported:
@@ -1397,6 +1404,16 @@ static bool ParseBuiltinType(State *state) {
}
}
+ return ParseVendorExtendedType(state);
+}
+
+// <vendor-extended-type> ::= u <source-name> [I <type> E]
+//
+// NOTE: [I <type> E] is a vendor extension (http://shortn/_FrINpH1XC5).
+static bool ParseVendorExtendedType(State *state) {
+ ComplexityGuard guard(state);
+ if (guard.IsTooComplex()) return false;
+
ParseState copy = state->parse_state;
if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
copy = state->parse_state;
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 6010bd87..cb8b36d0 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -192,6 +192,27 @@ TEST(Demangle, FailsOnTwoArgTemplateBuiltinType) {
Demangle("_Z3fooIicEu17__my_builtin_typeIT_T0_Ev", tmp, sizeof(tmp)));
}
+TEST(Demangle, TypeNestedUnderTemplatedBuiltinType) {
+ char tmp[100];
+
+ // Source:
+ //
+ // template <typename T>
+ // typename std::remove_reference_t<T>::type f(T t);
+ //
+ // struct C { using type = C; };
+ //
+ // f<const C&>(C{});
+ //
+ // These days std::remove_reference_t is implemented in terms of a vendor
+ // builtin __remove_reference_t. A full demangling might look like:
+ //
+ // __remove_reference_t<C const&>::type f<C const&>(C const&)
+ ASSERT_TRUE(Demangle("_Z1fIRK1CENu20__remove_reference_tIT_E4typeES3_",
+ tmp, sizeof(tmp)));
+ EXPECT_STREQ("f<>()", tmp);
+}
+
TEST(Demangle, TemplateTemplateParamSubstitution) {
char tmp[100];