From ed34153e0d9cd15f9b9eb45e86b457e0a495aeea Mon Sep 17 00:00:00 2001 From: Chris Mihelich Date: Thu, 6 Jun 2024 09:42:39 -0700 Subject: Demangle delete-expressions with the global-scope operator, gs (dl | da) .... PiperOrigin-RevId: 640928445 Change-Id: I547f194ebb0a4482ecec627a7a03bab60e8e1c0b --- absl/debugging/internal/demangle.cc | 15 ++++++-- absl/debugging/internal/demangle_test.cc | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc index 72cc887b..58749478 100644 --- a/absl/debugging/internal/demangle.cc +++ b/absl/debugging/internal/demangle.cc @@ -46,11 +46,11 @@ typedef struct { // List of operators from Itanium C++ ABI. static const AbbrevPair kOperatorList[] = { - // New has special syntax (not currently supported). + // New has special syntax. {"nw", "new", 0}, {"na", "new[]", 0}, - // Works except that the 'gs' prefix is not supported. + // Special-cased elsewhere to support the optional gs prefix. {"dl", "delete", 1}, {"da", "delete[]", 1}, @@ -1998,6 +1998,8 @@ static bool ParseBracedExpression(State *state) { // ::= [gs] nw * _ // ::= [gs] na * _ E // ::= [gs] na * _ +// ::= [gs] dl +// ::= [gs] da // ::= dc // ::= sc // ::= cc @@ -2106,6 +2108,15 @@ static bool ParseExpression(State *state) { } state->parse_state = copy; + // ::= [gs] dl + // ::= [gs] da + if (Optional(ParseTwoCharToken(state, "gs")) && + (ParseTwoCharToken(state, "dl") || ParseTwoCharToken(state, "da")) && + ParseExpression(state)) { + return true; + } + state->parse_state = copy; + // dynamic_cast, static_cast, const_cast, reinterpret_cast. // // ::= (dc | sc | cc | rc) diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc index 317e8494..c1308de9 100644 --- a/absl/debugging/internal/demangle_test.cc +++ b/absl/debugging/internal/demangle_test.cc @@ -1258,6 +1258,66 @@ TEST(Demangle, ArrayNewExpressionWithTwoElementsInBraces) { EXPECT_STREQ("f<>()", tmp); } +TEST(Demangle, SimpleDeleteExpression) { + char tmp[80]; + + // Source: + // + // template auto f(T* p) -> decltype(delete p) {} + // template auto f(int* p) -> decltype(delete p); + // + // LLVM demangling: + // + // decltype(delete fp) f(int*) + EXPECT_TRUE(Demangle("_Z1fIiEDTdlfp_EPT_", tmp, sizeof(tmp))); + EXPECT_STREQ("f<>()", tmp); +} + +TEST(Demangle, GlobalScopeDeleteExpression) { + char tmp[80]; + + // Source: + // + // template auto f(T* p) -> decltype(::delete p) {} + // template auto f(int* p) -> decltype(::delete p); + // + // LLVM demangling: + // + // decltype(::delete fp) f(int*) + EXPECT_TRUE(Demangle("_Z1fIiEDTgsdlfp_EPT_", tmp, sizeof(tmp))); + EXPECT_STREQ("f<>()", tmp); +} + +TEST(Demangle, SimpleArrayDeleteExpression) { + char tmp[80]; + + // Source: + // + // template auto f(T* a) -> decltype(delete[] a) {} + // template auto f(int* a) -> decltype(delete[] a); + // + // LLVM demangling: + // + // decltype(delete[] fp) f(int*) + EXPECT_TRUE(Demangle("_Z1fIiEDTdafp_EPT_", tmp, sizeof(tmp))); + EXPECT_STREQ("f<>()", tmp); +} + +TEST(Demangle, GlobalScopeArrayDeleteExpression) { + char tmp[80]; + + // Source: + // + // template auto f(T* a) -> decltype(::delete[] a) {} + // template auto f(int* a) -> decltype(::delete[] a); + // + // LLVM demangling: + // + // decltype(::delete[] fp) f(int*) + EXPECT_TRUE(Demangle("_Z1fIiEDTgsdafp_EPT_", tmp, sizeof(tmp))); + EXPECT_STREQ("f<>()", tmp); +} + TEST(Demangle, ReferenceQualifiedFunctionTypes) { char tmp[80]; -- cgit v1.2.3