add_anchor_token(',');
parse_constant_expression();
rem_anchor_token(',');
- rem_anchor_token('(');
+ rem_anchor_token(')');
expect(',');
add_anchor_token(')');
parse_constant_expression();
- rem_anchor_token('(');
+ rem_anchor_token(')');
expect(')');
return;
end_error:
add_anchor_token(',');
add_anchor_token('=');
- rem_anchor_token(';');
+ add_anchor_token(';');
/* declarator is common to both function-definitions and declarations */
declaration_t *ndeclaration = parse_declarator(&specifiers, /*may_be_abstract=*/false);
*/
static expression_t *parse_cast(void)
{
+ add_anchor_token(')');
+
source_position_t source_position = token.source_position;
type_t *type = parse_typename();
- /* matching add_anchor_token() is at call site */
rem_anchor_token(')');
expect(')');
*/
static expression_t *parse_statement_expression(void)
{
+ add_anchor_token(')');
+
expression_t *expression = allocate_expression_zero(EXPR_STATEMENT);
statement_t *statement = parse_compound_statement(true);
}
expression->base.type = type;
+ rem_anchor_token(')');
expect(')');
end_error:
static expression_t *parse_parenthesized_expression(void)
{
eat('(');
- add_anchor_token(')');
switch(token.type) {
case '{':
}
}
+ add_anchor_token(')');
expression_t *result = parse_expression();
rem_anchor_token(')');
expect(')');
expression_t *const expr = parse_assignment_expression();
if (expr->kind == EXPR_REFERENCE) {
declaration_t *const decl = expr->reference.declaration;
- if (decl == NULL)
- return create_invalid_expression();
- if (decl->parent_scope == ¤t_function->scope &&
- decl->next == NULL) {
- expression->va_starte.parameter = decl;
- expect(')');
- return expression;
+ if (decl->parent_scope != ¤t_function->scope || decl->next != NULL) {
+ errorf(&expr->base.source_position,
+ "second argument of 'va_start' must be last parameter of the current function");
}
+ expression->va_starte.parameter = decl;
+ expect(')');
+ return expression;
}
- errorf(&expr->base.source_position,
- "second argument of 'va_start' must be last parameter of the current function");
+ expect(')');
end_error:
return create_invalid_expression();
}
case ';': statement = parse_empty_statement(); break;
case '{': statement = parse_compound_statement(false); break;
- case T___leave: statement = parse_leave_statement(); break;
+ case T___leave: statement = parse_leave_statement(); break;
case T___try: statement = parse_ms_try_statment(); break;
case T_asm: statement = parse_asm_statement(); break;
case T_break: statement = parse_break(); break;
case T_return: statement = parse_return(); break;
case T_switch: statement = parse_switch(); break;
case T_while: statement = parse_while(); break;
- default: statement = parse_expression_statement(); break;
+
+ case '!':
+ case '&':
+ case '(':
+ case '*':
+ case '+':
+ case '-':
+ case '~':
+ case T_ANDAND:
+ case T_CHARACTER_CONSTANT:
+ case T_FLOATINGPOINT:
+ case T_INTEGER:
+ case T_MINUSMINUS:
+ case T_PLUSPLUS:
+ case T_STRING_LITERAL:
+ case T_WIDE_CHARACTER_CONSTANT:
+ case T_WIDE_STRING_LITERAL:
+ case T___FUNCDNAME__:
+ case T___FUNCSIG__:
+ case T___FUNCTION__:
+ case T___PRETTY_FUNCTION__:
+ case T___builtin_alloca:
+ case T___builtin_classify_type:
+ case T___builtin_constant_p:
+ case T___builtin_expect:
+ case T___builtin_huge_val:
+ case T___builtin_isgreater:
+ case T___builtin_isgreaterequal:
+ case T___builtin_isless:
+ case T___builtin_islessequal:
+ case T___builtin_islessgreater:
+ case T___builtin_isunordered:
+ case T___builtin_nan:
+ case T___builtin_nand:
+ case T___builtin_nanf:
+ case T___builtin_offsetof:
+ case T___builtin_prefetch:
+ case T___builtin_va_arg:
+ case T___builtin_va_end:
+ case T___builtin_va_start:
+ case T___func__:
+ case T___noop:
+ case T__assume:
+ statement = parse_expression_statement();
+ break;
+
+ default:
+ errorf(HERE, "unexpected token %K while parsing statement", &token);
+ statement = create_invalid_statement();
+ if (!at_anchor())
+ next_token();
+ break;
}
rem_anchor_token(';');
}
}
if (anchor_leak)
- exit(1);
+ abort();
#endif
switch (token.type) {