Commit cf071bb3 by Chris Mihelich Committed by Copybara-Service

Demangle C++17 fold-expressions.

PiperOrigin-RevId: 638068943
Change-Id: I7ffe7df900ec4854d8712885d212854b31e79fea
parent 44e077d6
......@@ -1885,6 +1885,10 @@ static bool ParseBracedExpression(State *state) {
// ::= dt <expression> <unresolved-name> # expr.name
// ::= pt <expression> <unresolved-name> # expr->name
// ::= sp <expression> # argument pack expansion
// ::= fl <binary operator-name> <expression>
// ::= fr <binary operator-name> <expression>
// ::= fL <binary operator-name> <expression> <expression>
// ::= fR <binary operator-name> <expression> <expression>
// ::= sr <type> <unqualified-name> <template-args>
// ::= sr <type> <unqualified-name>
// ::= u <source-name> <template-arg>* E # vendor extension
......@@ -1990,6 +1994,27 @@ static bool ParseExpression(State *state) {
}
state->parse_state = copy;
// Unary folds (... op pack) and (pack op ...).
//
// <expression> ::= fl <binary operator-name> <expression>
// ::= fr <binary operator-name> <expression>
if ((ParseTwoCharToken(state, "fl") || ParseTwoCharToken(state, "fr")) &&
ParseOperatorName(state, nullptr) && ParseExpression(state)) {
return true;
}
state->parse_state = copy;
// Binary folds (init op ... op pack) and (pack op ... op init).
//
// <expression> ::= fL <binary operator-name> <expression> <expression>
// ::= fR <binary operator-name> <expression> <expression>
if ((ParseTwoCharToken(state, "fL") || ParseTwoCharToken(state, "fR")) &&
ParseOperatorName(state, nullptr) && ParseExpression(state) &&
ParseExpression(state)) {
return true;
}
state->parse_state = copy;
// Object and pointer member access expressions.
//
// <expression> ::= (dt | pt) <expression> <unresolved-name>
......
......@@ -506,6 +506,65 @@ TEST(Demangle, SubobjectAddresses) {
EXPECT_STREQ("f<>()", tmp);
}
TEST(Demangle, UnaryFoldExpressions) {
char tmp[80];
// Source:
//
// template <bool b> struct S {};
//
// template <class... T> auto f(T... t) -> S<((sizeof(T) == 4) || ...)> {
// return {};
// }
//
// void g() { f(1, 2L); }
//
// Full LLVM demangling of the instantiation of f:
//
// S<((sizeof (int) == 4, sizeof (long) == 4) || ...)> f<int, long>(int, long)
EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfrooeqstT_Li4EEEDpS1_",
tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
// The like with a left fold.
//
// S<(... || (sizeof (int) == 4, sizeof (long) == 4))> f<int, long>(int, long)
EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXflooeqstT_Li4EEEDpS1_",
tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
}
TEST(Demangle, BinaryFoldExpressions) {
char tmp[80];
// Source:
//
// template <bool b> struct S {};
//
// template <class... T> auto f(T... t)
// -> S<((sizeof(T) == 4) || ... || false)> {
// return {};
// }
//
// void g() { f(1, 2L); }
//
// Full LLVM demangling of the instantiation of f:
//
// S<((sizeof (int) == 4, sizeof (long) == 4) || ... || false)>
// f<int, long>(int, long)
EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfRooeqstT_Li4ELb0EEEDpS1_",
tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
// The like with a left fold.
//
// S<(false || ... || (sizeof (int) == 4, sizeof (long) == 4))>
// f<int, long>(int, long)
EXPECT_TRUE(Demangle("_Z1fIJilEE1SIXfLooLb0EeqstT_Li4EEEDpS1_",
tmp, sizeof(tmp)));
EXPECT_STREQ("f<>()", tmp);
}
TEST(Demangle, SizeofPacks) {
char tmp[80];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment