diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -1926,16 +1926,16 @@ void printLeft(OutputBuffer &OB) const override { if (IsGlobal) - OB += "::operator "; + OB += "::"; OB += "new"; if (IsArray) OB += "[]"; - OB += ' '; if (!ExprList.empty()) { OB += "("; ExprList.printWithComma(OB); OB += ")"; } + OB += ' '; Type->print(OB); if (!InitList.empty()) { OB += "("; @@ -1961,7 +1961,8 @@ OB += "::"; OB += "delete"; if (IsArray) - OB += "[] "; + OB += "[]"; + OB += ' '; Op->print(OB); } }; @@ -2495,7 +2496,6 @@ Node *parseExprPrimary(); template Node *parseFloatingLiteral(); Node *parseFunctionParam(); - Node *parseNewExpr(); Node *parseConversionExpr(); Node *parseBracedExpr(); Node *parseFoldExpr(); @@ -4178,43 +4178,6 @@ return nullptr; } -// [gs] nw * _ E # new (expr-list) type -// [gs] nw * _ # new (expr-list) type (init) -// [gs] na * _ E # new[] (expr-list) type -// [gs] na * _ # new[] (expr-list) type (init) -// ::= pi * E # parenthesized initialization -template -Node *AbstractManglingParser::parseNewExpr() { - bool Global = consumeIf("gs"); - bool IsArray = look(1) == 'a'; - if (!consumeIf("nw") && !consumeIf("na")) - return nullptr; - size_t Exprs = Names.size(); - while (!consumeIf('_')) { - Node *Ex = getDerived().parseExpr(); - if (Ex == nullptr) - return nullptr; - Names.push_back(Ex); - } - NodeArray ExprList = popTrailingNodeArray(Exprs); - Node *Ty = getDerived().parseType(); - if (Ty == nullptr) - return Ty; - if (consumeIf("pi")) { - size_t InitsBegin = Names.size(); - while (!consumeIf('E')) { - Node *Init = getDerived().parseExpr(); - if (Init == nullptr) - return Init; - Names.push_back(Init); - } - NodeArray Inits = popTrailingNodeArray(InitsBegin); - return make(ExprList, Ty, Inits, Global, IsArray); - } else if (!consumeIf('E')) - return nullptr; - return make(ExprList, Ty, NodeArray(), Global, IsArray); -} - // cv # conversion with one argument // cv _ * E # conversion with a different number of arguments template @@ -4817,8 +4780,35 @@ case 'n': switch (First[1]) { case 'a': - case 'w': - return getDerived().parseNewExpr(); + case 'w': { + // [gs] nw * _ [pi *] E # new (expr-list) type [(init)] + // [gs] na * _ [pi *] E # new[] (expr-list) type [(init)] + bool IsArray = First[1] == 'a'; + First += 2; + size_t Exprs = Names.size(); + while (!consumeIf('_')) { + Node *Ex = getDerived().parseExpr(); + if (Ex == nullptr) + return nullptr; + Names.push_back(Ex); + } + NodeArray ExprList = popTrailingNodeArray(Exprs); + Node *Ty = getDerived().parseType(); + if (Ty == nullptr) + return nullptr; + bool HaveInits = consumeIf("pi"); + size_t InitsBegin = Names.size(); + while (!consumeIf('E')) { + if (!HaveInits) + return nullptr; + Node *Init = getDerived().parseExpr(); + if (Init == nullptr) + return Init; + Names.push_back(Init); + } + NodeArray Inits = popTrailingNodeArray(InitsBegin); + return make(ExprList, Ty, Inits, Global, IsArray); + } case 'e': First += 2; return getDerived().parseBinaryExpr("!="); diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -29858,6 +29858,11 @@ {"_ZN2FnIXgs4BaseEX4BaseEEEvv","void Fn<::Base, Base>()"}, + {"_ZN2FnIXgsnw_iEEXna_ipiLi4EEEEEvv", "void Fn<::new int, new[] int(4)>()"}, + {"_ZN2FnIXnwLj4E_iEEXgsnaLj4E_ipiLi4EEEEEvv", "void Fn()"}, + {"_ZN2FnIXgsdlLi4EEXdaLi4EEEEvv", "void Fn<::delete 4, delete[] 4>()"}, + {"_ZN2FnIXdlLj4EEXgsdaLj4EEEEvv", "void Fn()"}, + {"_Z3TPLIiET_S0_", "int TPL(int)"}, }; diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -1926,16 +1926,16 @@ void printLeft(OutputBuffer &OB) const override { if (IsGlobal) - OB += "::operator "; + OB += "::"; OB += "new"; if (IsArray) OB += "[]"; - OB += ' '; if (!ExprList.empty()) { OB += "("; ExprList.printWithComma(OB); OB += ")"; } + OB += ' '; Type->print(OB); if (!InitList.empty()) { OB += "("; @@ -1961,7 +1961,8 @@ OB += "::"; OB += "delete"; if (IsArray) - OB += "[] "; + OB += "[]"; + OB += ' '; Op->print(OB); } }; @@ -2495,7 +2496,6 @@ Node *parseExprPrimary(); template Node *parseFloatingLiteral(); Node *parseFunctionParam(); - Node *parseNewExpr(); Node *parseConversionExpr(); Node *parseBracedExpr(); Node *parseFoldExpr(); @@ -4178,43 +4178,6 @@ return nullptr; } -// [gs] nw * _ E # new (expr-list) type -// [gs] nw * _ # new (expr-list) type (init) -// [gs] na * _ E # new[] (expr-list) type -// [gs] na * _ # new[] (expr-list) type (init) -// ::= pi * E # parenthesized initialization -template -Node *AbstractManglingParser::parseNewExpr() { - bool Global = consumeIf("gs"); - bool IsArray = look(1) == 'a'; - if (!consumeIf("nw") && !consumeIf("na")) - return nullptr; - size_t Exprs = Names.size(); - while (!consumeIf('_')) { - Node *Ex = getDerived().parseExpr(); - if (Ex == nullptr) - return nullptr; - Names.push_back(Ex); - } - NodeArray ExprList = popTrailingNodeArray(Exprs); - Node *Ty = getDerived().parseType(); - if (Ty == nullptr) - return Ty; - if (consumeIf("pi")) { - size_t InitsBegin = Names.size(); - while (!consumeIf('E')) { - Node *Init = getDerived().parseExpr(); - if (Init == nullptr) - return Init; - Names.push_back(Init); - } - NodeArray Inits = popTrailingNodeArray(InitsBegin); - return make(ExprList, Ty, Inits, Global, IsArray); - } else if (!consumeIf('E')) - return nullptr; - return make(ExprList, Ty, NodeArray(), Global, IsArray); -} - // cv # conversion with one argument // cv _ * E # conversion with a different number of arguments template @@ -4817,8 +4780,35 @@ case 'n': switch (First[1]) { case 'a': - case 'w': - return getDerived().parseNewExpr(); + case 'w': { + // [gs] nw * _ [pi *] E # new (expr-list) type [(init)] + // [gs] na * _ [pi *] E # new[] (expr-list) type [(init)] + bool IsArray = First[1] == 'a'; + First += 2; + size_t Exprs = Names.size(); + while (!consumeIf('_')) { + Node *Ex = getDerived().parseExpr(); + if (Ex == nullptr) + return nullptr; + Names.push_back(Ex); + } + NodeArray ExprList = popTrailingNodeArray(Exprs); + Node *Ty = getDerived().parseType(); + if (Ty == nullptr) + return nullptr; + bool HaveInits = consumeIf("pi"); + size_t InitsBegin = Names.size(); + while (!consumeIf('E')) { + if (!HaveInits) + return nullptr; + Node *Init = getDerived().parseExpr(); + if (Init == nullptr) + return Init; + Names.push_back(Init); + } + NodeArray Inits = popTrailingNodeArray(InitsBegin); + return make(ExprList, Ty, Inits, Global, IsArray); + } case 'e': First += 2; return getDerived().parseBinaryExpr("!=");