Skip to content

Commit

Permalink
[cparse.d] use early returns (dlang#16809)
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilsonator authored Aug 26, 2024
1 parent 0834c75 commit b531a71
Showing 1 changed file with 60 additions and 61 deletions.
121 changes: 60 additions & 61 deletions compiler/src/dmd/cparse.d
Original file line number Diff line number Diff line change
Expand Up @@ -1120,75 +1120,74 @@ final class CParser(AST) : Parser!AST
*/
private AST.Expression cparseCastExp()
{
if (token.value == TOK.leftParenthesis)
if (token.value != TOK.leftParenthesis)
return cparseUnaryExp();

//printf("cparseCastExp()\n");
auto tk = peek(&token);
bool iscast;
bool isexp;
if (tk.value == TOK.identifier)
{
//printf("cparseCastExp()\n");
auto tk = peek(&token);
bool iscast;
bool isexp;
if (tk.value == TOK.identifier)
{
iscast = isTypedef(tk.ident);
isexp = !iscast;
}
if (isexp)
{
// ( identifier ) is an expression
return cparseUnaryExp();
}
iscast = isTypedef(tk.ident);
isexp = !iscast;
}
if (isexp)
{
// ( identifier ) is an expression
return cparseUnaryExp();
}

// If ( type-name )
auto pt = &token;
// If ( type-name )
auto pt = &token;

if (isCastExpression(pt))
{
// Expression may be either a cast or a compound literal, which
// requires checking whether the next token is leftCurly
const loc = token.loc;
nextToken();
auto t = cparseTypeName();
check(TOK.rightParenthesis);
pt = &token;
if (!isCastExpression(pt))
return cparseUnaryExp();

if (token.value == TOK.leftCurly)
{
// C11 6.5.2.5 ( type-name ) { initializer-list }
auto ci = cparseInitializer();
auto ce = new AST.CompoundLiteralExp(loc, t, ci);
return cparsePostfixOperators(ce);
}
// Expression may be either a cast or a compound literal, which
// requires checking whether the next token is leftCurly
const loc = token.loc;
nextToken();
auto t = cparseTypeName();
check(TOK.rightParenthesis);
pt = &token;

if (iscast)
{
// ( type-name ) cast-expression
auto ce = cparseCastExp();
return new AST.CastExp(loc, ce, t);
}
if (token.value == TOK.leftCurly)
{
// C11 6.5.2.5 ( type-name ) { initializer-list }
auto ci = cparseInitializer();
auto ce = new AST.CompoundLiteralExp(loc, t, ci);
return cparsePostfixOperators(ce);
}

if (t.isTypeIdentifier() &&
isexp &&
token.value == TOK.leftParenthesis &&
!isCastExpression(pt))
{
/* (t)(...)... might be a cast expression or a function call,
* with different grammars: a cast would be cparseCastExp(),
* a function call would be cparsePostfixExp(CallExp(cparseArguments())).
* We can't know until t is known. So, parse it as a function call
* and let semantic() rewrite the AST as a CastExp if it turns out
* to be a type.
*/
auto ie = new AST.IdentifierExp(loc, t.isTypeIdentifier().ident);
ie.parens = true; // let semantic know it might be a CastExp
AST.Expression e = new AST.CallExp(loc, ie, cparseArguments());
return cparsePostfixOperators(e);
}
if (iscast)
{
// ( type-name ) cast-expression
auto ce = cparseCastExp();
return new AST.CastExp(loc, ce, t);
}

// ( type-name ) cast-expression
auto ce = cparseCastExp();
return new AST.CastExp(loc, ce, t);
}
if (t.isTypeIdentifier() &&
isexp &&
token.value == TOK.leftParenthesis &&
!isCastExpression(pt))
{
/* (t)(...)... might be a cast expression or a function call,
* with different grammars: a cast would be cparseCastExp(),
* a function call would be cparsePostfixExp(CallExp(cparseArguments())).
* We can't know until t is known. So, parse it as a function call
* and let semantic() rewrite the AST as a CastExp if it turns out
* to be a type.
*/
auto ie = new AST.IdentifierExp(loc, t.isTypeIdentifier().ident);
ie.parens = true; // let semantic know it might be a CastExp
AST.Expression e = new AST.CallExp(loc, ie, cparseArguments());
return cparsePostfixOperators(e);
}
return cparseUnaryExp();

// ( type-name ) cast-expression
auto ce = cparseCastExp();
return new AST.CastExp(loc, ce, t);
}

/**************
Expand Down

0 comments on commit b531a71

Please sign in to comment.