Demangle transaction-safety notations GTt and Dx.

PiperOrigin-RevId: 641249074
Change-Id: Id410ce6c3b7a9a2b10aedf9c70ec65d3e37af06d
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index 8b76ce0..9f4a835 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -1112,6 +1112,7 @@
 //                ::= GV <(object) name>
 //                ::= GR <(object) name> [<seq-id>] _
 //                ::= T <call-offset> <(base) encoding>
+//                ::= GTt <encoding>  # transaction-safe entry point
 // G++ extensions:
 //                ::= TC <type> <(offset) number> _ <(base) type>
 //                ::= TF <type>
@@ -1205,6 +1206,12 @@
   }
   state->parse_state = copy;
 
+  if (ParseThreeCharToken(state, "GTt") &&
+      MaybeAppend(state, "transaction clone for ") && ParseEncoding(state)) {
+    return true;
+  }
+  state->parse_state = copy;
+
   if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") &&
       ParseCallOffset(state) && ParseEncoding(state)) {
     return true;
@@ -1509,7 +1516,7 @@
 }
 
 // <function-type> ::=
-//     [exception-spec] F [Y] <bare-function-type> [<ref-qualifier>] E
+//     [exception-spec] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
 //
 // <ref-qualifier> ::= R | O
 static bool ParseFunctionType(State *state) {
@@ -1517,6 +1524,7 @@
   if (guard.IsTooComplex()) return false;
   ParseState copy = state->parse_state;
   Optional(ParseExceptionSpec(state));
+  Optional(ParseTwoCharToken(state, "Dx"));
   if (!ParseOneCharToken(state, 'F')) {
     state->parse_state = copy;
     return false;
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 108642a..974b15f 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -759,6 +759,21 @@
   EXPECT_STREQ("f<>()", tmp);
 }
 
+TEST(Demangle, TransactionSafeEntryPoint) {
+  char tmp[80];
+
+  EXPECT_TRUE(Demangle("_ZGTt1fv", tmp, sizeof(tmp)));
+  EXPECT_STREQ("transaction clone for f()", tmp);
+}
+
+TEST(Demangle, TransactionSafeFunctionType) {
+  char tmp[80];
+
+  // GNU demangling: f(void (*)() transaction_safe)
+  EXPECT_TRUE(Demangle("_Z1fPDxFvvE", tmp, sizeof(tmp)));
+  EXPECT_STREQ("f()", tmp);
+}
+
 TEST(Demangle, EnableIfAttributeOnGlobalFunction) {
   char tmp[80];