Skip to content

Commit 918d455

Browse files
[libc++abi] Enable demangling of cp expression production (#114882)
See itanium-cxx-abi/cxx-abi#196
1 parent 9b6bb83 commit 918d455

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

libcxxabi/src/demangle/ItaniumDemangle.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,17 +2077,23 @@ class SizeofParamPackExpr : public Node {
20772077
class CallExpr : public Node {
20782078
const Node *Callee;
20792079
NodeArray Args;
2080+
bool IsParen; // (func)(args ...) ?
20802081

20812082
public:
2082-
CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
2083-
: Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
2083+
CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
2084+
: Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
2085+
IsParen(IsParen_) {}
20842086

20852087
template <typename Fn> void match(Fn F) const {
2086-
F(Callee, Args, getPrecedence());
2088+
F(Callee, Args, IsParen, getPrecedence());
20872089
}
20882090

20892091
void printLeft(OutputBuffer &OB) const override {
2092+
if (IsParen)
2093+
OB.printOpen();
20902094
Callee->print(OB);
2095+
if (IsParen)
2096+
OB.printClose();
20912097
OB.printOpen();
20922098
Args.printWithComma(OB);
20932099
OB.printClose();
@@ -3354,9 +3360,12 @@ const typename AbstractManglingParser<
33543360
"operator co_await"},
33553361
{"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
33563362
{"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3357-
{"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"},
3363+
{"cl", OperatorInfo::Call, /*Paren*/ false, Node::Prec::Postfix,
3364+
"operator()"},
33583365
{"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
33593366
{"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3367+
{"cp", OperatorInfo::Call, /*Paren*/ true, Node::Prec::Postfix,
3368+
"operator()"},
33603369
{"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
33613370
{"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
33623371
{"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
@@ -5099,6 +5108,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
50995108
// ::= <binary operator-name> <expression> <expression>
51005109
// ::= <ternary operator-name> <expression> <expression> <expression>
51015110
// ::= cl <expression>+ E # call
5111+
// ::= cp <base-unresolved-name> <expression>* E # (name) (expr-list), call that would use argument-dependent lookup but for the parentheses
51025112
// ::= cv <type> <expression> # conversion with one argument
51035113
// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
51045114
// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
@@ -5234,7 +5244,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
52345244
Names.push_back(E);
52355245
}
52365246
return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
5237-
Op->getPrecedence());
5247+
/*IsParen=*/Op->getFlag(), Op->getPrecedence());
52385248
}
52395249
case OperatorInfo::CCast: {
52405250
// C Cast: (type)expr
@@ -5421,7 +5431,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
54215431
}
54225432
}
54235433
return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
5424-
Node::Prec::Postfix);
5434+
/*IsParen=*/false, Node::Prec::Postfix);
54255435
}
54265436

54275437
// Only unresolved names remain.

libcxxabi/test/test_demangle.pass.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29834,6 +29834,7 @@ const char* cases[][2] =
2983429834
{"_ZN5Casts5auto_IiEEvDTnw_DapicvT__EEE", "void Casts::auto_<int>(decltype(new auto((int)())))"},
2983529835
{"_ZN5Casts7scalar_IiEEvDTcmcvT__Ecvi_EE", "void Casts::scalar_<int>(decltype((int)(), (int)()))"},
2983629836
{"_ZN5test11aIsEEDTcl3foocvT__EEES1_", "decltype(foo((short)())) test1::a<short>(short)"},
29837+
{"_ZN5test11bIsEEDTcp3foocvT__EEES1_", "decltype((foo)((short)())) test1::b<short>(short)"},
2983729838
{"_ZN5test21aIPFfvEEEvT_DTclfL0p_EE", "void test2::a<float (*)()>(float (*)(), decltype(fp()))"},
2983829839
{"_ZN5test21bIPFfvEEEDTclfp_EET_", "decltype(fp()) test2::b<float (*)()>(float (*)())"},
2983929840
{"_ZN5test21cIPFfvEEEvT_PFvDTclfL1p_EEE", "void test2::c<float (*)()>(float (*)(), void (*)(decltype(fp())))"},
@@ -30397,24 +30398,24 @@ void test_invalid_cases()
3039730398
assert(!passed && "demangle did not fail");
3039830399
}
3039930400

30400-
const char *xfail_cases[] = {
30401-
// FIXME: Why does clang generate the "cp" expr?
30402-
"_ZN5test11bIsEEDTcp3foocvT__EEES1_",
30401+
const char *const xfail_cases[] = {
30402+
// Sentinel value
30403+
nullptr
3040330404
};
3040430405

30405-
const size_t num_xfails = sizeof(xfail_cases) / sizeof(xfail_cases[0]);
30406-
3040730406
void test_xfail_cases()
3040830407
{
3040930408
std::size_t len = 0;
3041030409
char* buf = nullptr;
30411-
for (std::size_t i = 0; i < num_xfails; ++i)
30410+
for (const char *c_str : xfail_cases)
3041230411
{
30412+
if (!c_str)
30413+
break;
3041330414
int status;
30414-
char* demang = __cxxabiv1::__cxa_demangle(xfail_cases[i], buf, &len, &status);
30415+
char* demang = __cxxabiv1::__cxa_demangle(c_str, buf, &len, &status);
3041530416
if (status != -2)
3041630417
{
30417-
std::printf("%s was documented as xfail but passed\n", xfail_cases[i]);
30418+
std::printf("%s was documented as xfail but passed\n", c_str);
3041830419
std::printf("Got status = %d\n", status);
3041930420
assert(status == -2);
3042030421
}

llvm/include/llvm/Demangle/ItaniumDemangle.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,17 +2077,23 @@ class SizeofParamPackExpr : public Node {
20772077
class CallExpr : public Node {
20782078
const Node *Callee;
20792079
NodeArray Args;
2080+
bool IsParen; // (func)(args ...) ?
20802081

20812082
public:
2082-
CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
2083-
: Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
2083+
CallExpr(const Node *Callee_, NodeArray Args_, bool IsParen_, Prec Prec_)
2084+
: Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_),
2085+
IsParen(IsParen_) {}
20842086

20852087
template <typename Fn> void match(Fn F) const {
2086-
F(Callee, Args, getPrecedence());
2088+
F(Callee, Args, IsParen, getPrecedence());
20872089
}
20882090

20892091
void printLeft(OutputBuffer &OB) const override {
2092+
if (IsParen)
2093+
OB.printOpen();
20902094
Callee->print(OB);
2095+
if (IsParen)
2096+
OB.printClose();
20912097
OB.printOpen();
20922098
Args.printWithComma(OB);
20932099
OB.printClose();
@@ -3354,9 +3360,12 @@ const typename AbstractManglingParser<
33543360
"operator co_await"},
33553361
{"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
33563362
{"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3357-
{"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"},
3363+
{"cl", OperatorInfo::Call, /*Paren*/ false, Node::Prec::Postfix,
3364+
"operator()"},
33583365
{"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
33593366
{"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3367+
{"cp", OperatorInfo::Call, /*Paren*/ true, Node::Prec::Postfix,
3368+
"operator()"},
33603369
{"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
33613370
{"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
33623371
{"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
@@ -5099,6 +5108,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
50995108
// ::= <binary operator-name> <expression> <expression>
51005109
// ::= <ternary operator-name> <expression> <expression> <expression>
51015110
// ::= cl <expression>+ E # call
5111+
// ::= cp <base-unresolved-name> <expression>* E # (name) (expr-list), call that would use argument-dependent lookup but for the parentheses
51025112
// ::= cv <type> <expression> # conversion with one argument
51035113
// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
51045114
// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
@@ -5234,7 +5244,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
52345244
Names.push_back(E);
52355245
}
52365246
return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
5237-
Op->getPrecedence());
5247+
/*IsParen=*/Op->getFlag(), Op->getPrecedence());
52385248
}
52395249
case OperatorInfo::CCast: {
52405250
// C Cast: (type)expr
@@ -5421,7 +5431,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
54215431
}
54225432
}
54235433
return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
5424-
Node::Prec::Postfix);
5434+
/*IsParen=*/false, Node::Prec::Postfix);
54255435
}
54265436

54275437
// Only unresolved names remain.

0 commit comments

Comments
 (0)