diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 85694d9e93a1f2..afef50b26ca5aa 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -98,7 +98,7 @@ X(BoolExpr) \ X(StringLiteral) \ X(LambdaExpr) \ - X(IntegerCastExpr) \ + X(EnumLiteral) \ X(IntegerLiteral) \ X(FloatLiteral) \ X(DoubleLiteral) \ @@ -2036,22 +2036,26 @@ class LambdaExpr : public Node { } }; -class IntegerCastExpr : public Node { +class EnumLiteral : public Node { // ty(integer) const Node *Ty; StringView Integer; public: - IntegerCastExpr(const Node *Ty_, StringView Integer_) - : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {} + EnumLiteral(const Node *Ty_, StringView Integer_) + : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {} template void match(Fn F) const { F(Ty, Integer); } void printLeft(OutputStream &S) const override { - S += "("; + S << "("; Ty->print(S); - S += ")"; - S += Integer; + S << ")"; + + if (Integer[0] == 'n') + S << "-" << Integer.dropFront(1); + else + S << Integer; } }; @@ -4270,12 +4274,12 @@ Node *AbstractManglingParser::parseExprPrimary() { Node *T = getDerived().parseType(); if (T == nullptr) return nullptr; - StringView N = parseNumber(); + StringView N = parseNumber(/*AllowNegative=*/true); if (N.empty()) return nullptr; if (!consumeIf('E')) return nullptr; - return make(T, N); + return make(T, N); } } } diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp index edab9ad827e6ce..2df8ea17511e3f 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -29792,6 +29792,8 @@ const char* cases[][2] = // "auto inline_func()::'lambda'(int, int) const" {"_ZZ11inline_funcvENKUlTyTyT_T0_E_clIiiEEDaS_S0_", "auto inline_func()::'lambda'($T, $T0)::operator()($T, $T0) const"}, {"_ZZ11inline_funcvENKUlTyTyT_T1_T0_E_clIiiiEEDaS_S0_S1_", "auto inline_func()::'lambda'($T, auto, $T0)::operator()($T, auto, $T0) const"}, + + {"_Z1fIL4Enumn1EEvv", "void f<(Enum)-1>()"}, }; const unsigned N = sizeof(cases) / sizeof(cases[0]); diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h index 85694d9e93a1f2..afef50b26ca5aa 100644 --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -98,7 +98,7 @@ X(BoolExpr) \ X(StringLiteral) \ X(LambdaExpr) \ - X(IntegerCastExpr) \ + X(EnumLiteral) \ X(IntegerLiteral) \ X(FloatLiteral) \ X(DoubleLiteral) \ @@ -2036,22 +2036,26 @@ class LambdaExpr : public Node { } }; -class IntegerCastExpr : public Node { +class EnumLiteral : public Node { // ty(integer) const Node *Ty; StringView Integer; public: - IntegerCastExpr(const Node *Ty_, StringView Integer_) - : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {} + EnumLiteral(const Node *Ty_, StringView Integer_) + : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {} template void match(Fn F) const { F(Ty, Integer); } void printLeft(OutputStream &S) const override { - S += "("; + S << "("; Ty->print(S); - S += ")"; - S += Integer; + S << ")"; + + if (Integer[0] == 'n') + S << "-" << Integer.dropFront(1); + else + S << Integer; } }; @@ -4270,12 +4274,12 @@ Node *AbstractManglingParser::parseExprPrimary() { Node *T = getDerived().parseType(); if (T == nullptr) return nullptr; - StringView N = parseNumber(); + StringView N = parseNumber(/*AllowNegative=*/true); if (N.empty()) return nullptr; if (!consumeIf('E')) return nullptr; - return make(T, N); + return make(T, N); } } }