#define PUSH_PARENT(stmt) \
statement_t *const prev_parent = current_parent; \
((void)(current_parent = (stmt)))
-#define POP_PARENT ((void)(current_parent = prev_parent))
+#define POP_PARENT() ((void)(current_parent = prev_parent))
/** special symbol used for anonymous entities. */
static symbol_t *sym_anonymous = NULL;
parse_error_expected(NULL, (expected), NULL); \
add_anchor_token(expected); \
eat_until_anchor(); \
- next_if((expected)); \
rem_anchor_token(expected); \
- goto error_label; \
+ if (token.type != (expected)) \
+ goto error_label; \
} \
next_token(); \
} while (0)
entity_t *old_current_entity = current_entity;
current_function = function;
current_entity = entity;
- current_parent = NULL;
+ PUSH_PARENT(NULL);
goto_first = NULL;
goto_anchor = &goto_first;
}
}
- assert(current_parent == NULL);
+ POP_PARENT();
assert(current_function == function);
assert(current_entity == entity);
current_entity = old_current_entity;
eat('{');
add_anchor_token('}');
- while (token.type != '}') {
- if (token.type == T_EOF) {
- errorf(HERE, "EOF while parsing struct");
- break;
+ for (;;) {
+ switch (token.type) {
+ DECLARATION_START
+ case T_IDENTIFIER: {
+ declaration_specifiers_t specifiers;
+ parse_declaration_specifiers(&specifiers);
+ parse_compound_declarators(compound, &specifiers);
+ break;
+ }
+
+ default:
+ rem_anchor_token('}');
+ expect('}', end_error);
+end_error:
+ /* §6.7.2.1:7 */
+ compound->complete = true;
+ return;
}
- declaration_specifiers_t specifiers;
- parse_declaration_specifiers(&specifiers);
- parse_compound_declarators(compound, &specifiers);
}
- rem_anchor_token('}');
- next_token();
-
- /* §6.7.2.1:7 */
- compound->complete = true;
}
static type_t *parse_typename(void)
static expression_t *parse_boolean_literal(bool value)
{
expression_t *literal = allocate_expression_zero(EXPR_LITERAL_BOOLEAN);
- literal->base.source_position = token.source_position;
- literal->base.type = type_bool;
- literal->literal.value.begin = value ? "true" : "false";
- literal->literal.value.size = value ? 4 : 5;
+ literal->base.type = type_bool;
+ literal->literal.value.begin = value ? "true" : "false";
+ literal->literal.value.size = value ? 4 : 5;
next_token();
return literal;
}
expression_t *literal = allocate_expression_zero(kind);
- literal->base.source_position = token.source_position;
- literal->base.type = type;
- literal->literal.value = token.literal;
- literal->literal.suffix = token.symbol;
+ literal->base.type = type;
+ literal->literal.value = token.literal;
+ literal->literal.suffix = token.symbol;
next_token();
/* integer type depends on the size of the number and the size
static expression_t *parse_character_constant(void)
{
expression_t *literal = allocate_expression_zero(EXPR_LITERAL_CHARACTER);
- literal->base.source_position = token.source_position;
- literal->base.type = c_mode & _CXX ? type_char : type_int;
- literal->literal.value = token.literal;
+ literal->base.type = c_mode & _CXX ? type_char : type_int;
+ literal->literal.value = token.literal;
size_t len = literal->literal.value.size;
if (len > 1) {
static expression_t *parse_wide_character_constant(void)
{
expression_t *literal = allocate_expression_zero(EXPR_LITERAL_WIDE_CHARACTER);
- literal->base.source_position = token.source_position;
- literal->base.type = type_int;
- literal->literal.value = token.literal;
+ literal->base.type = type_int;
+ literal->literal.value = token.literal;
size_t len = wstrlen(&literal->literal.value);
if (len > 1) {
return true;
}
-static expression_t *parse_compound_literal(type_t *type)
+static expression_t *parse_compound_literal(source_position_t const *const pos, type_t *type)
{
expression_t *expression = allocate_expression_zero(EXPR_COMPOUND_LITERAL);
+ expression->base.source_position = *pos;
parse_initializer_env_t env;
env.type = type;
*/
static expression_t *parse_cast(void)
{
- source_position_t source_position = token.source_position;
+ source_position_t const pos = *HERE;
eat('(');
add_anchor_token(')');
expect(')', end_error);
if (token.type == '{') {
- return parse_compound_literal(type);
+ return parse_compound_literal(&pos, type);
}
expression_t *cast = allocate_expression_zero(EXPR_UNARY_CAST);
- cast->base.source_position = source_position;
+ cast->base.source_position = pos;
expression_t *value = parse_subexpression(PREC_CAST);
cast->base.type = type;
{
/* the result is a (int)0 */
expression_t *literal = allocate_expression_zero(EXPR_LITERAL_MS_NOOP);
- literal->base.type = type_int;
- literal->base.source_position = token.source_position;
- literal->literal.value.begin = "__noop";
- literal->literal.value.size = 6;
+ literal->base.type = type_int;
+ literal->literal.value.begin = "__noop";
+ literal->literal.value.size = 6;
eat(T___noop);
type_t *orig_type;
expression_t *expression;
if (token.type == '(' && is_declaration_specifier(look_ahead(1))) {
+ source_position_t const pos = *HERE;
next_token();
add_anchor_token(')');
orig_type = parse_typename();
if (token.type == '{') {
/* It was not sizeof(type) after all. It is sizeof of an expression
* starting with a compound literal */
- expression = parse_compound_literal(orig_type);
+ expression = parse_compound_literal(&pos, orig_type);
goto typeprop_expression;
}
} else {
statement->case_label.statement = parse_label_inner_statement(statement, "case label");
- POP_PARENT;
+ POP_PARENT();
return statement;
}
statement->case_label.statement = parse_label_inner_statement(statement, "default label");
- POP_PARENT;
+ POP_PARENT();
return statement;
}
*label_anchor = &statement->label;
label_anchor = &statement->label.next;
- POP_PARENT;
+ POP_PARENT();
return statement;
}
warningf(WARN_PARENTHESES, pos, "suggest explicit braces to avoid ambiguous 'else'");
}
- POP_PARENT;
+ POP_PARENT();
return statement;
}
}
check_enum_cases(&statement->switchs);
- POP_PARENT;
+ POP_PARENT();
return statement;
end_error:
- POP_PARENT;
+ POP_PARENT();
return create_invalid_statement();
}
statement->whiles.body = parse_loop_body(statement);
- POP_PARENT;
+ POP_PARENT();
return statement;
end_error:
- POP_PARENT;
+ POP_PARENT();
return create_invalid_statement();
}
expect(')', end_error);
expect(';', end_error);
- POP_PARENT;
+ POP_PARENT();
return statement;
end_error:
- POP_PARENT;
+ POP_PARENT();
return create_invalid_statement();
}
scope_pop(old_scope);
environment_pop_to(top);
- POP_PARENT;
+ POP_PARENT();
return statement;
end_error2:
- POP_PARENT;
+ POP_PARENT();
rem_anchor_token(')');
assert(current_scope == &statement->fors.scope);
scope_pop(old_scope);
statement->ms_try.try_statement = parse_compound_statement(false);
current_try = rem;
- POP_PARENT;
+ POP_PARENT();
if (next_if(T___except)) {
expect('(', end_error);
scope_pop(old_scope);
environment_pop_to(top);
- POP_PARENT;
+ POP_PARENT();
return statement;
}