summaryrefslogtreecommitdiff
path: root/absl/debugging/internal
diff options
context:
space:
mode:
Diffstat (limited to 'absl/debugging/internal')
-rw-r--r--absl/debugging/internal/demangle.cc15
-rw-r--r--absl/debugging/internal/demangle_test.cc23
2 files changed, 38 insertions, 0 deletions
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index f9dff5d8..26163416 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -1176,6 +1176,7 @@ static bool ParseConversionOperatorType(State *state) {
// ::= GR <(object) name> [<seq-id>] _
// ::= T <call-offset> <(base) encoding>
// ::= GTt <encoding> # transaction-safe entry point
+// ::= TA <template-arg> # nontype template parameter object
// G++ extensions:
// ::= TC <type> <(offset) number> _ <(base) type>
// ::= TF <type>
@@ -1190,6 +1191,8 @@ static bool ParseConversionOperatorType(State *state) {
// thread_local feature. For these see:
//
// https://maskray.me/blog/2021-02-14-all-about-thread-local-storage
+//
+// For TA see https://github.com/itanium-cxx-abi/cxx-abi/issues/63.
static bool ParseSpecialName(State *state) {
ComplexityGuard guard(state);
if (guard.IsTooComplex()) return false;
@@ -1280,6 +1283,18 @@ static bool ParseSpecialName(State *state) {
return true;
}
state->parse_state = copy;
+
+ if (ParseTwoCharToken(state, "TA")) {
+ bool append = state->parse_state.append;
+ DisableAppend(state);
+ if (ParseTemplateArg(state)) {
+ RestoreAppend(state, append);
+ MaybeAppend(state, "template parameter object");
+ return true;
+ }
+ }
+ state->parse_state = copy;
+
return false;
}
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 68a759c1..55686814 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -943,6 +943,29 @@ TEST(Demangle, TransactionSafeFunctionType) {
EXPECT_STREQ("f()", tmp);
}
+TEST(Demangle, TemplateParameterObject) {
+ char tmp[80];
+
+ // Source:
+ //
+ // struct S { int x, y; };
+ // template <S s, const S* p = &s> void f() {}
+ // template void f<S{1, 2}>();
+ //
+ // LLVM demangling:
+ //
+ // void f<S{1, 2}, &template parameter object for S{1, 2}>()
+ EXPECT_TRUE(Demangle("_Z1fIXtl1SLi1ELi2EEEXadL_ZTAXtlS0_Li1ELi2EEEEEEvv",
+ tmp, sizeof(tmp)));
+ EXPECT_STREQ("f<>()", tmp);
+
+ // The name of the object standing alone.
+ //
+ // LLVM demangling: template parameter object for S{1, 2}
+ EXPECT_TRUE(Demangle("_ZTAXtl1SLi1ELi2EEE", tmp, sizeof(tmp)));
+ EXPECT_STREQ("template parameter object", tmp);
+}
+
TEST(Demangle, EnableIfAttributeOnGlobalFunction) {
char tmp[80];