Demangle array new-expressions, [gs] na ....

PiperOrigin-RevId: 640891321
Change-Id: I2bc0f6b907d8af88446375409fb523158ae0e001
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index 761bde1..efaaf68 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -1996,6 +1996,8 @@
 //              ::= il <braced-expression>* E
 //              ::= [gs] nw <expression>* _ <type> E
 //              ::= [gs] nw <expression>* _ <type> <initializer>
+//              ::= [gs] na <expression>* _ <type> E
+//              ::= [gs] na <expression>* _ <type> <initializer>
 //              ::= dc <type> <expression>
 //              ::= sc <type> <expression>
 //              ::= cc <type> <expression>
@@ -2093,8 +2095,10 @@
 
   // <expression> ::= [gs] nw <expression>* _ <type> E
   //              ::= [gs] nw <expression>* _ <type> <initializer>
+  //              ::= [gs] na <expression>* _ <type> E
+  //              ::= [gs] na <expression>* _ <type> <initializer>
   if (Optional(ParseTwoCharToken(state, "gs")) &&
-      ParseTwoCharToken(state, "nw") &&
+      (ParseTwoCharToken(state, "nw") || ParseTwoCharToken(state, "na")) &&
       ZeroOrMore(ParseExpression, state) && ParseOneCharToken(state, '_') &&
       ParseType(state) &&
       (ParseOneCharToken(state, 'E') || ParseInitializer(state))) {
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 747bc06..033fefc 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -1148,6 +1148,70 @@
   EXPECT_STREQ("f<>()", tmp);
 }
 
+TEST(Demangle, SimpleArrayNewExpression) {
+  char tmp[80];
+
+  // Source:
+  //
+  // template <class T> decltype(T{*new T[1]}) f() { return T{}; }
+  // template decltype(int{*new int[1]}) f<int>();
+  //
+  // Full LLVM demangling of the instantiation of f:
+  //
+  // decltype(int{*(new[] int)}) f<int>()
+  EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_dena_S0_EEEv", tmp, sizeof(tmp)));
+  EXPECT_STREQ("f<>()", tmp);
+}
+
+TEST(Demangle, ArrayNewExpressionWithEmptyParentheses) {
+  char tmp[80];
+
+  // Source:
+  //
+  // template <class T> decltype(T{*new T[1]()}) f() { return T{}; }
+  // template decltype(int{*new int[1]()}) f<int>();
+  //
+  // Full LLVM demangling of the instantiation of f:
+  //
+  // decltype(int{*(new[] int)}) f<int>()
+  EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_dena_S0_piEEEv", tmp, sizeof(tmp)));
+  EXPECT_STREQ("f<>()", tmp);
+}
+
+TEST(Demangle, ArrayPlacementNewExpression) {
+  char tmp[80];
+
+  // Source:
+  //
+  // #include <new>
+  //
+  // template <class T> auto f(T t) -> decltype(T{*new (&t) T[1]}) {
+  //   return T{};
+  // }
+  // template auto f<int>(int t) -> decltype(int{*new (&t) int[1]});
+  //
+  // Full LLVM demangling of the instantiation of f:
+  //
+  // decltype(int{*(new[](&fp) int)}) f<int>(int)
+  EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_denaadfp__S0_EEES0_", tmp, sizeof(tmp)));
+  EXPECT_STREQ("f<>()", tmp);
+}
+
+TEST(Demangle, GlobalScopeArrayNewExpression) {
+  char tmp[80];
+
+  // Source:
+  //
+  // template <class T> decltype(T{*::new T[1]}) f() { return T{}; }
+  // template decltype(int{*::new int[1]}) f<int>();
+  //
+  // Full LLVM demangling of the instantiation of f:
+  //
+  // decltype(int{*(::new[] int)}) f<int>()
+  EXPECT_TRUE(Demangle("_Z1fIiEDTtlT_degsna_S0_EEEv", tmp, sizeof(tmp)));
+  EXPECT_STREQ("f<>()", tmp);
+}
+
 TEST(Demangle, ReferenceQualifiedFunctionTypes) {
   char tmp[80];