Demangle C++ requires-expressions with parameters (rQ ... E).

PiperOrigin-RevId: 638266358
Change-Id: I8a750a53d5e98bc3ad3b6d36661789d97d6efb0a
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index 606ff4e..2e692d3 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -1922,6 +1922,7 @@
 //              ::= sr <type> <unqualified-name>
 //              ::= u <source-name> <template-arg>* E  # vendor extension
 //              ::= rq <requirement>+ E
+//              ::= rQ <bare-function-type> _ <requirement>+ E
 static bool ParseExpression(State *state) {
   ComplexityGuard guard(state);
   if (guard.IsTooComplex()) return false;
@@ -2093,6 +2094,16 @@
   }
   state->parse_state = copy;
 
+  // <expression> ::= rQ <bare-function-type> _ <requirement>+ E
+  //
+  // https://github.com/itanium-cxx-abi/cxx-abi/issues/24
+  if (ParseTwoCharToken(state, "rQ") && ParseBareFunctionType(state) &&
+      ParseOneCharToken(state, '_') && OneOrMore(ParseRequirement, state) &&
+      ParseOneCharToken(state, 'E')) {
+    return true;
+  }
+  state->parse_state = copy;
+
   return ParseUnresolvedName(state);
 }
 
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 998d34b..5ecb33c 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -303,6 +303,14 @@
   EXPECT_STREQ(tmp, "$_0::operator()<>()");
 }
 
+TEST(Demangle, RequiresExpressionWithItsOwnParameter) {
+  char tmp[100];
+
+  // S<requires (int) { fp + fp; }> f<int>(int)
+  ASSERT_TRUE(Demangle("_Z1fIiE1SIXrQT__XplfL0p_fp_EEES1_", tmp, sizeof(tmp)));
+  EXPECT_STREQ(tmp, "f<>()");
+}
+
 TEST(Demangle, LambdaWithExplicitTypeArgument) {
   char tmp[100];