#endif
}
+static inline bool next_if(int const type)
+{
+ if (token.type == type) {
+ next_token();
+ return true;
+ } else {
+ return false;
+ }
+}
+
/**
* Return the next token with a given lookahead.
*/
static void eat_block(void)
{
eat_until_matching_token('{');
- if (token.type == '}')
- next_token();
+ next_if('}');
}
#define eat(token_type) (assert(token.type == (token_type)), next_token())
parse_error_expected(NULL, (expected), NULL); \
add_anchor_token(expected); \
eat_until_anchor(); \
- if (token.type == expected) \
- next_token(); \
+ next_if((expected)); \
rem_anchor_token(expected); \
goto error_label; \
} \
*/
static attribute_argument_t *parse_attribute_arguments(void)
{
- if (token.type == ')')
- return NULL;
-
attribute_argument_t *first = NULL;
attribute_argument_t *last = NULL;
- while (true) {
+ if (token.type != ')') do {
attribute_argument_t *argument = allocate_ast_zero(sizeof(*argument));
/* is it an identifier */
last->next = argument;
}
last = argument;
-
- if (token.type == ',') {
- next_token();
- continue;
- }
- expect(')', end_error);
- break;
- }
+ } while (next_if(','));
+ expect(')', end_error);
return first;
attribute_t *attribute = allocate_attribute_zero(kind);
/* parse arguments */
- if (token.type == '(') {
- next_token();
+ if (next_if('('))
attribute->a.arguments = parse_attribute_arguments();
- }
return attribute;
expect('(', end_error);
expect('(', end_error);
- if (token.type == ')') {
- next_token();
- expect(')', end_error);
- return first;
- }
-
- while (true) {
+ if (token.type != ')') do {
attribute_t *attribute = parse_attribute_gnu_single();
if (attribute == NULL)
goto end_error;
last->next = attribute;
}
last = attribute;
-
- if (token.type == ')') {
- next_token();
- break;
- }
- expect(',', end_error);
- }
+ } while (next_if(','));
+ expect(')', end_error);
expect(')', end_error);
end_error:
{
/* there might be extra {} hierarchies */
int braces = 0;
- if (token.type == '{') {
+ if (next_if('{')) {
if (warning.other)
warningf(HERE, "extra curly braces around scalar initializer");
do {
++braces;
- next_token();
- } while (token.type == '{');
+ } while (next_if('{'));
}
expression_t *expression = parse_assignment_expression();
bool additional_warning_displayed = false;
while (braces > 0) {
- if (token.type == ',') {
- next_token();
- }
+ next_if(',');
if (token.type != '}') {
if (!additional_warning_displayed && warning.other) {
warningf(HERE, "additional elements in scalar initializer");
*/
static void skip_initializers(void)
{
- if (token.type == '{')
- next_token();
+ next_if('{');
while (token.type != '}') {
if (token.type == T_EOF)
&& outer_type != NULL) {
sub = initializer_from_expression(outer_type, expression);
if (sub != NULL) {
- if (token.type == ',') {
- next_token();
- }
+ next_if(',');
if (token.type != '}' && warning.other) {
warningf(HERE, "excessive elements in initializer for type '%T'",
orig_type);
entity->base.source_position = token.source_position;
next_token();
- if (token.type == '=') {
- next_token();
+ if (next_if('=')) {
expression_t *value = parse_constant_expression();
value = create_implicit_cast(value, enum_type);
}
record_entity(entity, false);
-
- if (token.type != ',')
- break;
- next_token();
- } while (token.type != '}');
+ } while (next_if(',') && token.type != '}');
rem_anchor_token('}');
expect('}', end_error);
bool old_gcc_extension = in_gcc_extension;
in_type_prop = true;
- while (token.type == T___extension__) {
+ while (next_if(T___extension__)) {
/* This can be a prefix to a typename or an expression. */
- next_token();
in_gcc_extension = true;
}
switch (token.type) {
attribute_property_argument_t *property
= allocate_ast_zero(sizeof(*property));
- while (true) {
+ do {
if (token.type != T_IDENTIFIER) {
parse_error_expected("while parsing property declspec",
T_IDENTIFIER, NULL);
property->get_symbol = token.v.symbol;
}
next_token();
- if (token.type == ')')
- break;
- expect(',', end_error);
- }
+ } while (next_if(','));
attribute->a.property = property;
static attribute_t *parse_microsoft_extended_decl_modifier_single(void)
{
attribute_kind_t kind = ATTRIBUTE_UNKNOWN;
- if (token.type == T_restrict) {
+ if (next_if(T_restrict)) {
kind = ATTRIBUTE_MS_RESTRICT;
- next_token();
} else if (token.type == T_IDENTIFIER) {
const char *name = token.v.symbol->string;
next_token();
}
/* parse arguments */
- if (token.type == '(') {
- next_token();
+ if (next_if('('))
attribute->a.arguments = parse_attribute_arguments();
- }
return attribute;
}
expect('(', end_error);
- if (token.type == ')') {
- next_token();
+ if (next_if(')'))
return NULL;
- }
add_anchor_token(')');
attribute_t *last = first;
- while (true) {
+ do {
if (last != NULL) {
while (last->next != NULL)
last = last->next;
last->next = attribute;
}
last = attribute;
-
- if (token.type == ')') {
- break;
- }
- expect(',', end_error);
- }
+ } while (next_if(','));
rem_anchor_token(')');
expect(')', end_error);
if (scope != NULL)
append_entity(scope, entity);
-
- if (token.type != ',') {
- break;
- }
- next_token();
- } while (token.type == T_IDENTIFIER);
+ } while (next_if(',') && token.type == T_IDENTIFIER);
}
static entity_t *parse_parameter(void)
if (has_parameters()) {
function_parameter_t **anchor = &type->parameters;
- for (;;) {
+ do {
switch (token.type) {
case T_DOTDOTDOT:
next_token();
default:
goto parameters_finished;
}
- if (token.type != ',') {
- goto parameters_finished;
- }
- next_token();
- }
+ } while (next_if(','));
}
memset(array, 0, sizeof(*array));
cons->kind = CONSTRUCT_ARRAY;
- if (token.type == T_static) {
+ if (next_if(T_static))
array->is_static = true;
- next_token();
- }
type_qualifiers_t type_qualifiers = parse_type_qualifiers();
- if (type_qualifiers != 0) {
- if (token.type == T_static) {
+ if (type_qualifiers != 0 && next_if(T_static))
array->is_static = true;
- next_token();
- }
- }
array->type_qualifiers = type_qualifiers;
if (token.type == '*' && look_ahead(1)->type == ']') {
check_variable_type_complete(entity);
- if (token.type != ',')
+ if (!next_if(','))
break;
- eat(',');
add_anchor_token('=');
ndeclaration = parse_declarator(specifiers, flags);
static void parse_compound_declarators(compound_t *compound,
const declaration_specifiers_t *specifiers)
{
- while (true) {
+ do {
entity_t *entity;
if (token.type == ':') {
append_entity(&compound->members, entity);
}
}
-
- if (token.type != ',')
- break;
- next_token();
- }
+ } while (next_if(','));
expect(';', end_error);
end_error:
source_position_t pos;
const scope_t *lookup_scope = NULL;
- if (token.type == T_COLONCOLON) {
- next_token();
+ if (next_if(T_COLONCOLON))
lookup_scope = &unit->scope;
- }
entity_t *entity;
while (true) {
/* lookup entity */
entity = lookup_entity(lookup_scope, symbol, NAMESPACE_NORMAL);
- if (token.type != T_COLONCOLON)
+ if (!next_if(T_COLONCOLON))
break;
- next_token();
switch (entity->kind) {
case ENTITY_NAMESPACE:
end_error:
/* skip further qualifications */
- while (token.type == T_IDENTIFIER) {
- next_token();
- if (token.type != T_COLONCOLON)
- break;
- next_token();
- }
+ while (next_if(T_IDENTIFIER) && next_if(T_COLONCOLON)) {}
return create_error_entity(sym_anonymous, ENTITY_VARIABLE);
}
designator_t *last_designator = result;
while (true) {
- if (token.type == '.') {
- next_token();
+ if (next_if('.')) {
if (token.type != T_IDENTIFIER) {
parse_error_expected("while parsing member designator",
T_IDENTIFIER, NULL);
last_designator = designator;
continue;
}
- if (token.type == '[') {
- next_token();
+ if (next_if('[')) {
add_anchor_token(']');
designator_t *designator = allocate_ast_zero(sizeof(result[0]));
designator->source_position = *HERE;
add_anchor_token(')');
add_anchor_token(',');
- if (token.type != ')') {
- while (true) {
- (void)parse_assignment_expression();
- if (token.type != ',')
- break;
- next_token();
- }
- }
+ if (token.type != ')') do {
+ (void)parse_assignment_expression();
+ } while (next_if(','));
}
rem_anchor_token(',');
rem_anchor_token(')');
if (token.type != ')') {
call_argument_t **anchor = &call->arguments;
- for (;;) {
+ do {
call_argument_t *argument = allocate_ast_zero(sizeof(*argument));
argument->expression = parse_assignment_expression();
*anchor = argument;
anchor = &argument->next;
-
- if (token.type != ',')
- break;
- next_token();
- }
+ } while (next_if(','));
}
rem_anchor_token(',');
rem_anchor_token(')');
eat(T_delete);
- if (token.type == '[') {
- next_token();
+ if (next_if('[')) {
result->kind = EXPR_UNARY_DELETE_ARRAY;
expect(']', end_error);
end_error:;
asm_argument_t *argument = allocate_ast_zero(sizeof(argument[0]));
memset(argument, 0, sizeof(argument[0]));
- if (token.type == '[') {
- eat('[');
+ if (next_if('[')) {
if (token.type != T_IDENTIFIER) {
parse_error_expected("while parsing asm argument",
T_IDENTIFIER, NULL);
*anchor = argument;
anchor = &argument->next;
- if (token.type != ',')
+ if (!next_if(','))
break;
- eat(',');
}
return result;
}
last = clobber;
- if (token.type != ',')
+ if (!next_if(','))
break;
- eat(',');
}
return result;
eat(T_asm);
- if (token.type == T_volatile) {
- next_token();
+ if (next_if(T_volatile))
asm_statement->is_volatile = true;
- }
expect('(', end_error);
add_anchor_token(')');
add_anchor_token(':');
asm_statement->asm_text = parse_string_literals();
- if (token.type != ':') {
+ if (!next_if(':')) {
rem_anchor_token(':');
goto end_of_asm;
}
- eat(':');
asm_statement->outputs = parse_asm_arguments(true);
- if (token.type != ':') {
+ if (!next_if(':')) {
rem_anchor_token(':');
goto end_of_asm;
}
- eat(':');
asm_statement->inputs = parse_asm_arguments(false);
- if (token.type != ':') {
+ if (!next_if(':')) {
rem_anchor_token(':');
goto end_of_asm;
}
rem_anchor_token(':');
- eat(':');
asm_statement->clobbers = parse_asm_clobbers();
}
if (GNU_MODE) {
- if (token.type == T_DOTDOTDOT) {
- next_token();
+ if (next_if(T_DOTDOTDOT)) {
expression_t *const end_range = parse_expression();
statement->case_label.end_range = end_range;
if (!is_constant_expression(end_range)) {
statement->ifs.true_statement = true_stmt;
rem_anchor_token(T_else);
- if (token.type == T_else) {
- next_token();
+ if (next_if(T_else)) {
statement->ifs.false_statement = parse_statement();
} else if (warning.parentheses &&
true_stmt->kind == STATEMENT_IF &&
scope_t *old_scope = scope_push(&statement->fors.scope);
bool old_gcc_extension = in_gcc_extension;
- while (token.type == T___extension__) {
- next_token();
+ while (next_if(T___extension__)) {
in_gcc_extension = true;
}
- if (token.type == ';') {
- next_token();
+ if (next_if(';')) {
} else if (is_declaration_specifier(&token, false)) {
parse_declaration(record_entity, DECL_FLAGS_NONE);
} else {
statement_t *statement = allocate_statement_zero(STATEMENT_GOTO);
eat(T_goto);
- if (GNU_MODE && token.type == '*') {
- next_token();
+ if (GNU_MODE && next_if('*')) {
expression_t *expression = parse_expression();
mark_vars_read(expression, NULL);
POP_PARENT;
- if (token.type == T___except) {
- eat(T___except);
+ if (next_if(T___except)) {
expect('(', end_error);
add_anchor_token(')');
expression_t *const expr = parse_expression();
rem_anchor_token(')');
expect(')', end_error);
statement->ms_try.final_statement = parse_compound_statement(false);
- } else if (token.type == T__finally) {
- eat(T___finally);
+ } else if (next_if(T__finally)) {
statement->ms_try.final_statement = parse_compound_statement(false);
} else {
parse_error_expected("while parsing __try statement", T___except, T___finally, NULL);
entity_t *begin = NULL, *end = NULL;
- while (true) {
+ do {
if (token.type != T_IDENTIFIER) {
parse_error_expected("while parsing local label declaration",
T_IDENTIFIER, NULL);
environment_push(entity);
}
next_token();
-
- if (token.type != ',')
- break;
- next_token();
- }
+ } while (next_if(','));
eat(';');
end_error:
statement->declaration.declarations_begin = begin;
case T___extension__:
/* This can be a prefix to a declaration or an expression statement.
* We simply eat it now and parse the rest with tail recursion. */
- do {
- next_token();
- } while (token.type == T___extension__);
+ while (next_if(T___extension__)) {}
bool old_gcc_extension = in_gcc_extension;
in_gcc_extension = true;
statement = intern_parse_statement();
}
current_linkage = new_linkage;
- if (token.type == '{') {
- next_token();
+ if (next_if('{')) {
parse_externals();
expect('}', end_error);
} else {