type_t const *const type = skip_typeref(entity->typedefe.type);
if (!is_type_void(type))
return true;
- if (type->base.qualifiers != TYPE_QUALIFIER_NONE) {
+ if (c_mode & _CXX) {
+ /* ISO/IEC 14882:1998(E) §8.3.5:2 It must be literally (void). A typedef
+ * is not allowed. */
+ errorf(HERE, "empty parameter list defined with a typedef of 'void' not allowed in C++");
+ } else if (type->base.qualifiers != TYPE_QUALIFIER_NONE) {
/* §6.7.5.3:10 Qualification is not allowed here. */
errorf(HERE, "'void' as parameter must not have type qualifiers");
}
source_position_t const *pos = &cast->base.source_position;
/* §6.5.4 A (void) cast is explicitly permitted, more for documentation than for utility. */
- if (dst_type == type_void)
+ if (is_type_void(dst_type))
return true;
/* only integer and pointer can be casted to pointer */
expect(')', end_error);
expect(';', end_error);
+end_error:
if (asm_statement->outputs == NULL) {
/* GCC: An 'asm' instruction without any output operands will be treated
* identically to a volatile 'asm' instruction. */
}
return statement;
-end_error:
- return create_error_statement();
}
static statement_t *parse_label_inner_statement(statement_t const *const label, char const *const label_kind)
return stmt;
}
+/**
+ * Parse an expression in parentheses and mark its variables as read.
+ */
+static expression_t *parse_condition(void)
+{
+ expect('(', end_error0);
+ add_anchor_token(')');
+ expression_t *const expr = parse_expression();
+ mark_vars_read(expr, NULL);
+ rem_anchor_token(')');
+ expect(')', end_error1);
+end_error1:
+ return expr;
+end_error0:
+ return create_error_expression();
+}
+
/**
* Parse an if statement.
*/
add_anchor_token('{');
- expect('(', end_error);
- add_anchor_token(')');
- expression_t *const expr = parse_expression();
+ expression_t *const expr = parse_condition();
statement->ifs.condition = expr;
/* §6.8.4.1:1 The controlling expression of an if statement shall have
* scalar type. */
semantic_condition(expr, "condition of 'if'-statment");
- mark_vars_read(expr, NULL);
- rem_anchor_token(')');
- expect(')', end_error);
-end_error:
rem_anchor_token('{');
add_anchor_token(T_else);
PUSH_PARENT(statement);
- expect('(', end_error);
- add_anchor_token(')');
- expression_t *const expr = parse_expression();
- mark_vars_read(expr, NULL);
+ expression_t *const expr = parse_condition();
type_t * type = skip_typeref(expr->base.type);
if (is_type_integer(type)) {
type = promote_integer(type);
type = type_error_type;
}
statement->switchs.expression = create_implicit_cast(expr, type);
- expect(')', end_error);
- rem_anchor_token(')');
switch_statement_t *rem = current_switch;
current_switch = &statement->switchs;
POP_PARENT();
return statement;
-end_error:
- POP_PARENT();
- return create_error_statement();
}
static statement_t *parse_loop_body(statement_t *const loop)
PUSH_PARENT(statement);
- expect('(', end_error);
- add_anchor_token(')');
- expression_t *const cond = parse_expression();
+ expression_t *const cond = parse_condition();
statement->whiles.condition = cond;
/* §6.8.5:2 The controlling expression of an iteration statement shall
* have scalar type. */
semantic_condition(cond, "condition of 'while'-statement");
- mark_vars_read(cond, NULL);
- rem_anchor_token(')');
- expect(')', end_error);
statement->whiles.body = parse_loop_body(statement);
POP_PARENT();
return statement;
-end_error:
- POP_PARENT();
- return create_error_statement();
}
/**
statement->do_while.body = parse_loop_body(statement);
rem_anchor_token(T_while);
- expect(T_while, end_error);
- expect('(', end_error);
- add_anchor_token(')');
- expression_t *const cond = parse_expression();
+ expect(T_while, end_error0);
+end_error0:;
+ expression_t *const cond = parse_condition();
statement->do_while.condition = cond;
/* §6.8.5:2 The controlling expression of an iteration statement shall
* have scalar type. */
semantic_condition(cond, "condition of 'do-while'-statement");
- mark_vars_read(cond, NULL);
- rem_anchor_token(')');
- expect(')', end_error);
- expect(';', end_error);
+ expect(';', end_error1);
+end_error1:
POP_PARENT();
return statement;
-end_error:
- POP_PARENT();
- return create_error_statement();
}
/**
eat(T_for);
- expect('(', end_error1);
- add_anchor_token(')');
-
PUSH_PARENT(statement);
PUSH_SCOPE(&statement->fors.scope);
+ expect('(', end_error1);
+ add_anchor_token(')');
+
PUSH_EXTENSION();
if (next_if(';')) {
warningf(WARN_UNUSED_VALUE, &init->base.source_position, "initialisation of 'for'-statement has no effect");
}
rem_anchor_token(';');
- expect(';', end_error2);
+ expect(';', end_error3);
+end_error3:;
}
POP_EXTENSION();
rem_anchor_token(';');
}
expect(';', end_error2);
+end_error2:
if (token.kind != ')') {
expression_t *const step = parse_expression();
statement->fors.step = step;
warningf(WARN_UNUSED_VALUE, &step->base.source_position, "step of 'for'-statement has no effect");
}
}
- expect(')', end_error2);
rem_anchor_token(')');
+ expect(')', end_error1);
+end_error1:
statement->fors.body = parse_loop_body(statement);
POP_SCOPE();
POP_PARENT();
return statement;
-
-end_error2:
- POP_PARENT();
- rem_anchor_token(')');
- POP_SCOPE();
- /* fallthrough */
-
-end_error1:
- return create_error_statement();
}
/**
else
parse_error_expected("while parsing goto", T_IDENTIFIER, NULL);
eat_until_anchor();
- return create_error_statement();
+ statement->gotos.label = &allocate_entity_zero(ENTITY_LABEL, NAMESPACE_LABEL, sym_anonymous)->label;
}
}
POP_PARENT();
if (next_if(T___except)) {
- expect('(', end_error);
- add_anchor_token(')');
- expression_t *const expr = parse_expression();
- mark_vars_read(expr, NULL);
+ expression_t *const expr = parse_condition();
type_t * type = skip_typeref(expr->base.type);
if (is_type_integer(type)) {
type = promote_integer(type);
type = type_error_type;
}
statement->ms_try.except_expression = create_implicit_cast(expr, type);
- rem_anchor_token(')');
- expect(')', end_error);
- statement->ms_try.final_statement = parse_compound_statement(false);
- } else if (next_if(T__finally)) {
- statement->ms_try.final_statement = parse_compound_statement(false);
- } else {
+ } else if (!next_if(T__finally)) {
parse_error_expected("while parsing __try statement", T___except, T___finally, NULL);
- return create_error_statement();
}
+ statement->ms_try.final_statement = parse_compound_statement(false);
return statement;
-end_error:
- return create_error_statement();
}
static statement_t *parse_empty_statement(void)
*/
static statement_t *intern_parse_statement(void)
{
- statement_t *statement = NULL;
-
/* declaration or statement */
- add_anchor_token(';');
+ statement_t *statement;
switch (token.kind) {
case T_IDENTIFIER: {
token_kind_t la1_type = (token_kind_t)look_ahead(1)->kind;
default:
errorf(HERE, "unexpected token %K while parsing statement", &token);
statement = create_error_statement();
- if (!at_anchor())
- next_token();
+ eat_until_anchor();
break;
}
- rem_anchor_token(';');
-
- assert(statement != NULL
- && statement->base.source_position.input_name != NULL);
return statement;
}
add_anchor_token('*');
add_anchor_token('+');
add_anchor_token('-');
+ add_anchor_token(';');
add_anchor_token('{');
add_anchor_token('~');
add_anchor_token(T_CHARACTER_CONSTANT);
rem_anchor_token(T_CHARACTER_CONSTANT);
rem_anchor_token('~');
rem_anchor_token('{');
+ rem_anchor_token(';');
rem_anchor_token('-');
rem_anchor_token('+');
rem_anchor_token('*');