* If not, generate an error, eat the current statement,
* and goto the end_error label.
*/
-#define expect(expected) \
+#define expect(expected, error_label) \
do { \
if (UNLIKELY(token.type != (expected))) { \
parse_error_expected(NULL, (expected), NULL); \
if (token.type == expected) \
next_token(); \
rem_anchor_token(expected); \
- goto end_error; \
+ goto error_label; \
} \
next_token(); \
} while (0)
add_anchor_token(')');
expression = parse_constant_expression();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
attribute->u.argument = fold_constant(expression);
return;
end_error:
}
rem_anchor_token(',');
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
return;
end_error:
attribute->invalid = true;
}
*string = parse_string_literals();
rem_anchor_token('(');
- expect(')');
+ expect(')', end_error);
return;
end_error:
attribute->invalid = true;
add_anchor_token(')');
if (token.type != T_IDENTIFIER) {
- expect(T_IDENTIFIER);
+ expect(T_IDENTIFIER, end_error);
}
/* This isn't really correct, the backend should provide a list of machine
next_token();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
return;
end_error:
attribute->invalid = true;
}
next_token();
- expect(',');
+ expect(',', end_error);
add_anchor_token(')');
add_anchor_token(',');
parse_constant_expression();
rem_anchor_token(',');
rem_anchor_token(')');
- expect(',');
+ expect(',', end_error);
add_anchor_token(')');
parse_constant_expression();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
return;
end_error:
attribute->u.value = true;
gnu_attribute_t *attribute;
eat(T___attribute__);
- expect('(');
- expect('(');
+ expect('(', end_error);
+ expect('(', end_error);
if (token.type != ')') {
/* find the end of the list */
next_token();
}
}
- expect(')');
- expect(')');
+ expect(')', end_error);
+ expect(')', end_error);
end_error:
*attributes = head;
case T_asm:
next_token();
- expect('(');
+ expect('(', end_error);
if (token.type != T_STRING_LITERAL) {
parse_error_expected("while parsing assembler attribute",
T_STRING_LITERAL, NULL);
} else {
parse_string_literals();
}
- expect(')');
+ expect(')', end_error);
continue;
case T_cdecl: modifiers |= DM_CDECL; break;
add_anchor_token(']');
designator->array_index = parse_constant_expression();
rem_anchor_token(']');
- expect(']');
+ expect(']', end_error);
break;
case '.':
designator = allocate_ast_zero(sizeof(designator[0]));
next_token();
break;
default:
- expect('=');
+ expect('=', end_error);
return result;
}
if (type != NULL) {
ascend_from_subtype(path);
- expect('}');
+ expect('}', end_error);
} else {
- expect('}');
+ expect('}', end_error);
goto error_parse_next;
}
}
if (token.type == '}') {
break;
}
- expect(',');
+ expect(',', end_error);
if (token.type == '}') {
break;
}
max_index = path.max_index;
DEL_ARR_F(path.path);
- expect('}');
+ expect('}', end_error);
} else {
/* parse_scalar_initializer() also works in this case: we simply
* have an expression without {} around it */
} while (token.type != '}');
rem_anchor_token('}');
- expect('}');
+ expect('}', end_error);
end_error:
;
type_t *type;
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression_t *expression = NULL;
in_gcc_extension = old_gcc_extension;
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
type_t *typeof_type = allocate_type_zero(TYPE_TYPEOF);
typeof_type->typeoft.expression = expression;
symbol_t *symbol = token.v.symbol;
if (symbol == sym_align) {
next_token();
- expect('(');
+ expect('(', end_error);
if (token.type != T_INTEGER)
goto end_error;
if (check_alignment_value(token.v.intvalue)) {
specifiers->alignment = (unsigned char)token.v.intvalue;
}
next_token();
- expect(')');
+ expect(')', end_error);
} else if (symbol == sym_allocate) {
next_token();
- expect('(');
+ expect('(', end_error);
if (token.type != T_IDENTIFIER)
goto end_error;
(void)token.v.symbol;
- expect(')');
+ expect(')', end_error);
} else if (symbol == sym_dllimport) {
next_token();
DET_MOD(dllimport, DM_DLLIMPORT);
DET_MOD(novtable, DM_NOVTABLE);
} else if (symbol == sym_property) {
next_token();
- expect('(');
+ expect('(', end_error);
for (;;) {
bool is_get = false;
if (token.type != T_IDENTIFIER)
goto end_error;
}
next_token();
- expect('=');
+ expect('=', end_error);
if (token.type != T_IDENTIFIER)
goto end_error;
if (is_get) {
}
break;
}
- expect(')');
+ expect(')', end_error);
} else if (symbol == sym_selectany) {
next_token();
DET_MOD(selectany, DM_SELECTANY);
} else if (symbol == sym_uuid) {
next_token();
- expect('(');
+ expect('(', end_error);
if (token.type != T_STRING_LITERAL)
goto end_error;
next_token();
- expect(')');
+ expect(')', end_error);
} else if (symbol == sym_deprecated) {
next_token();
if (specifiers->deprecated != 0 && warning.other)
} else {
errorf(HERE, "string literal expected");
}
- expect(')');
+ expect(')', end_error);
}
} else if (symbol == sym_noalias) {
next_token();
entity->declaration.type = type_error_type;
entity->declaration.implicit = true;
} else if (kind == ENTITY_TYPEDEF) {
- entity->typedefe.type = type_error_type;
+ entity->typedefe.type = type_error_type;
+ entity->typedefe.builtin = true;
}
record_entity(entity, false);
return entity;
if (offset > size)
need_pad = true;
- if (warning.padded && need_pad) {
- warningf(&compound->base.source_position,
- "'%#T' needs padding", type, compound->base.symbol);
- }
- if (warning.packed && !need_pad) {
- warningf(&compound->base.source_position,
- "superfluous packed attribute on '%#T'",
- type, compound->base.symbol);
+ if (need_pad) {
+ if (warning.padded) {
+ warningf(&compound->base.source_position, "'%T' needs padding", type);
+ }
+ } else {
+ if (compound->modifiers & DM_PACKED && warning.packed) {
+ warningf(&compound->base.source_position,
+ "superfluous packed attribute on '%T'", type);
+ }
}
type->base.size = offset;
case T__declspec:
next_token();
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
parse_microsoft_extended_decl_modifier(specifiers);
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
break;
case T___thread:
parameters_finished:
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
end_error:
restore_anchor_state(',', saved_comma_state);
}
rem_anchor_token(']');
- expect(']');
+ expect(']', end_error);
end_error:
return &array->construct_type;
case T__based:
next_token();
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
parse_microsoft_based(&base_spec);
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
continue;
default:
next_token();
break;
case '(':
- next_token();
- add_anchor_token(')');
- inner_types = parse_inner_declarator(env, may_be_abstract);
- if (inner_types != NULL) {
- /* All later declarators only modify the return type */
- env = NULL;
+ /* §6.7.6:2 footnote 126: Empty parentheses in a type name are
+ * interpreted as ``function with no parameter specification'', rather
+ * than redundant parentheses around the omitted identifier. */
+ if (look_ahead(1)->type != ')') {
+ next_token();
+ add_anchor_token(')');
+ inner_types = parse_inner_declarator(env, may_be_abstract);
+ if (inner_types != NULL) {
+ /* All later declarators only modify the return type */
+ env = NULL;
+ }
+ rem_anchor_token(')');
+ expect(')', end_error);
}
- rem_anchor_token(')');
- expect(')');
break;
default:
if (may_be_abstract)
env.symbol);
}
} else if (flags & DECL_IS_PARAMETER) {
- orig_type = semantic_parameter(&env.source_position, type,
+ orig_type = semantic_parameter(&env.source_position, orig_type,
specifiers, env.symbol);
entity = allocate_entity_zero(ENTITY_PARAMETER);
static void parser_error_multiple_definition(entity_t *entity,
const source_position_t *source_position)
{
- errorf(source_position, "multiple definition of symbol '%Y' (declared %P)",
+ errorf(source_position, "multiple definition of '%Y' (declared %P)",
entity->base.symbol, &entity->base.source_position);
}
ndeclaration = parse_declarator(specifiers, flags);
rem_anchor_token('=');
}
- expect(';');
+ expect(';', end_error);
end_error:
anonymous_entity = NULL;
break;
next_token();
}
- expect(';');
+ expect(';', end_error);
end_error:
anonymous_entity = NULL;
case T___builtin_expect:
return make_function_2_type(type_long, type_long, type_long);
default:
- internal_errorf(HERE, "not implemented builtin symbol found");
+ internal_errorf(HERE, "not implemented builtin identifier found");
}
}
entity = create_implicit_function(symbol, HERE);
} else {
- errorf(HERE, "unknown symbol '%Y' found.", symbol);
+ errorf(HERE, "unknown identifier '%Y' found.", symbol);
entity = create_error_entity(symbol, ENTITY_VARIABLE);
}
}
type_t *type = parse_typename();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
if (token.type == '{') {
return parse_compound_literal(type);
expression->base.type = type;
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
end_error:
return expression;
add_anchor_token(')');
expression_t *result = parse_expression();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
end_error:
return result;
designator->source_position = *HERE;
designator->array_index = parse_expression();
rem_anchor_token(']');
- expect(']');
+ expect(']', end_error);
if (designator->array_index == NULL) {
return NULL;
}
eat(T___builtin_offsetof);
- expect('(');
+ expect('(', end_error);
add_anchor_token(',');
type_t *type = parse_typename();
rem_anchor_token(',');
- expect(',');
+ expect(',', end_error);
add_anchor_token(')');
designator_t *designator = parse_designator();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
expression->offsetofe.type = type;
expression->offsetofe.designator = designator;
eat(T___builtin_va_start);
- expect('(');
+ expect('(', end_error);
add_anchor_token(',');
expression->va_starte.ap = parse_assignment_expression();
rem_anchor_token(',');
- expect(',');
+ expect(',', end_error);
expression_t *const expr = parse_assignment_expression();
if (expr->kind == EXPR_REFERENCE) {
entity_t *const entity = expr->reference.entity;
} else {
expression->va_starte.parameter = &entity->variable;
}
- expect(')');
+ expect(')', end_error);
return expression;
}
- expect(')');
+ expect(')', end_error);
end_error:
return create_invalid_expression();
}
eat(T___builtin_va_arg);
- expect('(');
+ expect('(', end_error);
expression->va_arge.ap = parse_assignment_expression();
- expect(',');
+ expect(',', end_error);
expression->base.type = parse_typename();
- expect(')');
+ expect(')', end_error);
return expression;
end_error:
eat(T___builtin_constant_p);
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression->builtin_constant.value = parse_assignment_expression();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
expression->base.type = type_int;
return expression;
eat(T___builtin_prefetch);
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression->builtin_prefetch.adr = parse_assignment_expression();
if (token.type == ',') {
expression->builtin_prefetch.locality = parse_assignment_expression();
}
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
expression->base.type = type_void;
return expression;
expression->base.source_position = *HERE;
next_token();
- expect('(');
+ expect('(', end_error);
expression->binary.left = parse_assignment_expression();
- expect(',');
+ expect(',', end_error);
expression->binary.right = parse_assignment_expression();
- expect(')');
+ expect(')', end_error);
type_t *const orig_type_left = expression->binary.left->base.type;
type_t *const orig_type_right = expression->binary.right->base.type;
#if 0
/**
- * Parses a __builtin_expect() expression.
+ * Parses a __builtin_expect(, end_error) expression.
*/
-static expression_t *parse_builtin_expect(void)
+static expression_t *parse_builtin_expect(void, end_error)
{
expression_t *expression
= allocate_expression_zero(EXPR_BINARY_BUILTIN_EXPECT);
eat(T___builtin_expect);
- expect('(');
+ expect('(', end_error);
expression->binary.left = parse_assignment_expression();
- expect(',');
+ expect(',', end_error);
expression->binary.right = parse_constant_expression();
- expect(')');
+ expect(')', end_error);
expression->base.type = expression->binary.left->base.type;
eat(T__assume);
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression->unary.value = parse_assignment_expression();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
expression->base.type = type_void;
return expression;
}
rem_anchor_token(',');
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
end_error:
return cnst;
expression->base.type = automatic_type_conversion(return_type);
rem_anchor_token(']');
- expect(']');
+ expect(']', end_error);
end_error:
return expression;
}
add_anchor_token(')');
orig_type = parse_typename();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
if (token.type == '{') {
/* It was not sizeof(type) after all. It is sizeof of an expression
symbol, type_left);
}
create_error_entry:
- return create_invalid_expression();
+ entry = create_error_entity(symbol, ENTITY_COMPOUND_MEMBER);
}
assert(is_declaration(entry));
}
rem_anchor_token(',');
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
if (function_type == NULL)
return result;
true_expression = parse_expression();
}
rem_anchor_token(':');
- expect(':');
+ expect(':', end_error);
expression_t *false_expression =
parse_sub_expression(c_mode & _CXX ? PREC_ASSIGNMENT : PREC_CONDITIONAL);
eat(T___builtin_classify_type);
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression_t *expression = parse_expression();
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
result->classify_type.type_expression = expression;
return result;
if (token.type == '[') {
next_token();
result->kind = EXPR_UNARY_DELETE_ARRAY;
- expect(']');
+ expect(']', end_error);
end_error:;
}
}
argument->symbol = token.v.symbol;
- expect(']');
+ expect(']', end_error);
}
argument->constraints = parse_string_literals();
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression_t *expression = parse_expression();
rem_anchor_token(')');
mark_vars_read(expression, NULL);
}
argument->expression = expression;
- expect(')');
+ expect(')', end_error);
set_address_taken(expression, true);
asm_statement->is_volatile = true;
}
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
add_anchor_token(':');
asm_statement->asm_text = parse_string_literals();
end_of_asm:
rem_anchor_token(')');
- expect(')');
- expect(';');
+ expect(')', end_error);
+ expect(';', end_error);
if (asm_statement->outputs == NULL) {
/* GCC: An 'asm' instruction without any output operands will be treated
PUSH_PARENT(statement);
- expect(':');
+ expect(':', end_error);
end_error:
if (current_switch != NULL) {
PUSH_PARENT(statement);
- expect(':');
+ expect(':', end_error);
if (current_switch != NULL) {
const case_label_statement_t *def_label = current_switch->default_label;
if (def_label != NULL) {
add_anchor_token('{');
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression_t *const expr = parse_expression();
statement->ifs.condition = expr;
semantic_condition(expr, "condition of 'if'-statment");
mark_vars_read(expr, NULL);
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
end_error:
rem_anchor_token('{');
PUSH_PARENT(statement);
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression_t *const expr = parse_expression();
mark_vars_read(expr, NULL);
type = type_error_type;
}
statement->switchs.expression = create_implicit_cast(expr, type);
- expect(')');
+ expect(')', end_error);
rem_anchor_token(')');
switch_statement_t *rem = current_switch;
PUSH_PARENT(statement);
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression_t *const cond = parse_expression();
statement->whiles.condition = cond;
semantic_condition(cond, "condition of 'while'-statement");
mark_vars_read(cond, NULL);
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
statement->whiles.body = parse_loop_body(statement);
statement->do_while.body = parse_loop_body(statement);
rem_anchor_token(T_while);
- expect(T_while);
- expect('(');
+ expect(T_while, end_error);
+ expect('(', end_error);
add_anchor_token(')');
expression_t *const cond = parse_expression();
statement->do_while.condition = cond;
semantic_condition(cond, "condition of 'do-while'-statement");
mark_vars_read(cond, NULL);
rem_anchor_token(')');
- expect(')');
- expect(';');
+ expect(')', end_error);
+ expect(';', end_error);
POP_PARENT;
return statement;
eat(T_for);
+ expect('(', end_error1);
+ add_anchor_token(')');
+
PUSH_PARENT(statement);
size_t const top = environment_top();
scope_t *old_scope = scope_push(&statement->fors.scope);
- expect('(');
- add_anchor_token(')');
-
if (token.type == ';') {
next_token();
} else if (is_declaration_specifier(&token, false)) {
"initialisation of 'for'-statement has no effect");
}
rem_anchor_token(';');
- expect(';');
+ expect(';', end_error2);
}
if (token.type != ';') {
mark_vars_read(cond, NULL);
rem_anchor_token(';');
}
- expect(';');
+ expect(';', end_error2);
if (token.type != ')') {
expression_t *const step = parse_expression();
statement->fors.step = step;
"step of 'for'-statement has no effect");
}
}
- expect(')');
+ expect(')', end_error2);
rem_anchor_token(')');
statement->fors.body = parse_loop_body(statement);
POP_PARENT;
return statement;
-end_error:
+end_error2:
POP_PARENT;
rem_anchor_token(')');
assert(current_scope == &statement->fors.scope);
scope_pop(old_scope);
environment_pop_to(top);
+ /* fallthrough */
+end_error1:
return create_invalid_statement();
}
*goto_anchor = &statement->gotos;
goto_anchor = &statement->gotos.next;
- expect(';');
+ expect(';', end_error);
return statement;
end_error:
statement_t *statement = allocate_statement_zero(STATEMENT_CONTINUE);
eat(T_continue);
- expect(';');
+ expect(';', end_error);
end_error:
return statement;
statement_t *statement = allocate_statement_zero(STATEMENT_BREAK);
eat(T_break);
- expect(';');
+ expect(';', end_error);
end_error:
return statement;
statement_t *statement = allocate_statement_zero(STATEMENT_LEAVE);
eat(T___leave);
- expect(';');
+ expect(';', end_error);
end_error:
return statement;
}
statement->returns.value = return_value;
- expect(';');
+ expect(';', end_error);
end_error:
return statement;
statement->expression.expression = expr;
mark_vars_read(expr, ENT_ANY);
- expect(';');
+ expect(';', end_error);
end_error:
return statement;
if (token.type == T___except) {
eat(T___except);
- expect('(');
+ expect('(', end_error);
add_anchor_token(')');
expression_t *const expr = parse_expression();
mark_vars_read(expr, NULL);
}
statement->ms_try.except_expression = create_implicit_cast(expr, type);
rem_anchor_token(')');
- expect(')');
+ expect(')', end_error);
statement->ms_try.final_statement = parse_compound_statement(false);
} else if (token.type == T__finally) {
eat(T___finally);
size_t const top = environment_top();
scope_t *old_scope = scope_push(&entity->namespacee.members);
- expect('{');
+ expect('{', end_error);
parse_externals();
- expect('}');
+ expect('}', end_error);
end_error:
assert(current_scope == &entity->namespacee.members);
eat('{');
add_anchor_token('}');
+ /* tokens, which can start a statement */
+ /* TODO MS, __builtin_FOO */
+ add_anchor_token('!');
+ add_anchor_token('&');
+ add_anchor_token('(');
+ add_anchor_token('*');
+ add_anchor_token('+');
+ add_anchor_token('-');
+ add_anchor_token('{');
+ add_anchor_token('~');
+ add_anchor_token(T_CHARACTER_CONSTANT);
+ add_anchor_token(T_COLONCOLON);
+ add_anchor_token(T_FLOATINGPOINT);
+ add_anchor_token(T_IDENTIFIER);
+ add_anchor_token(T_INTEGER);
+ add_anchor_token(T_MINUSMINUS);
+ add_anchor_token(T_PLUSPLUS);
+ add_anchor_token(T_STRING_LITERAL);
+ add_anchor_token(T_WIDE_CHARACTER_CONSTANT);
+ add_anchor_token(T_WIDE_STRING_LITERAL);
+ add_anchor_token(T__Bool);
+ add_anchor_token(T__Complex);
+ add_anchor_token(T__Imaginary);
+ add_anchor_token(T___FUNCTION__);
+ add_anchor_token(T___PRETTY_FUNCTION__);
+ add_anchor_token(T___alignof__);
+ add_anchor_token(T___attribute__);
+ add_anchor_token(T___builtin_va_start);
+ add_anchor_token(T___extension__);
+ add_anchor_token(T___func__);
+ add_anchor_token(T___imag__);
+ add_anchor_token(T___label__);
+ add_anchor_token(T___real__);
+ add_anchor_token(T___thread);
+ add_anchor_token(T_asm);
+ add_anchor_token(T_auto);
+ add_anchor_token(T_bool);
+ add_anchor_token(T_break);
+ add_anchor_token(T_case);
+ add_anchor_token(T_char);
+ add_anchor_token(T_class);
+ add_anchor_token(T_const);
+ add_anchor_token(T_const_cast);
+ add_anchor_token(T_continue);
+ add_anchor_token(T_default);
+ add_anchor_token(T_delete);
+ add_anchor_token(T_double);
+ add_anchor_token(T_do);
+ add_anchor_token(T_dynamic_cast);
+ add_anchor_token(T_enum);
+ add_anchor_token(T_extern);
+ add_anchor_token(T_false);
+ add_anchor_token(T_float);
+ add_anchor_token(T_for);
+ add_anchor_token(T_goto);
+ add_anchor_token(T_if);
+ add_anchor_token(T_inline);
+ add_anchor_token(T_int);
+ add_anchor_token(T_long);
+ add_anchor_token(T_new);
+ add_anchor_token(T_operator);
+ add_anchor_token(T_register);
+ add_anchor_token(T_reinterpret_cast);
+ add_anchor_token(T_restrict);
+ add_anchor_token(T_return);
+ add_anchor_token(T_short);
+ add_anchor_token(T_signed);
+ add_anchor_token(T_sizeof);
+ add_anchor_token(T_static);
+ add_anchor_token(T_static_cast);
+ add_anchor_token(T_struct);
+ add_anchor_token(T_switch);
+ add_anchor_token(T_template);
+ add_anchor_token(T_this);
+ add_anchor_token(T_throw);
+ add_anchor_token(T_true);
+ add_anchor_token(T_try);
+ add_anchor_token(T_typedef);
+ add_anchor_token(T_typeid);
+ add_anchor_token(T_typename);
+ add_anchor_token(T_typeof);
+ add_anchor_token(T_union);
+ add_anchor_token(T_unsigned);
+ add_anchor_token(T_using);
+ add_anchor_token(T_void);
+ add_anchor_token(T_volatile);
+ add_anchor_token(T_wchar_t);
+ add_anchor_token(T_while);
size_t const top = environment_top();
scope_t *old_scope = scope_push(&statement->compound.scope);
}
end_error:
+ rem_anchor_token(T_while);
+ rem_anchor_token(T_wchar_t);
+ rem_anchor_token(T_volatile);
+ rem_anchor_token(T_void);
+ rem_anchor_token(T_using);
+ rem_anchor_token(T_unsigned);
+ rem_anchor_token(T_union);
+ rem_anchor_token(T_typeof);
+ rem_anchor_token(T_typename);
+ rem_anchor_token(T_typeid);
+ rem_anchor_token(T_typedef);
+ rem_anchor_token(T_try);
+ rem_anchor_token(T_true);
+ rem_anchor_token(T_throw);
+ rem_anchor_token(T_this);
+ rem_anchor_token(T_template);
+ rem_anchor_token(T_switch);
+ rem_anchor_token(T_struct);
+ rem_anchor_token(T_static_cast);
+ rem_anchor_token(T_static);
+ rem_anchor_token(T_sizeof);
+ rem_anchor_token(T_signed);
+ rem_anchor_token(T_short);
+ rem_anchor_token(T_return);
+ rem_anchor_token(T_restrict);
+ rem_anchor_token(T_reinterpret_cast);
+ rem_anchor_token(T_register);
+ rem_anchor_token(T_operator);
+ rem_anchor_token(T_new);
+ rem_anchor_token(T_long);
+ rem_anchor_token(T_int);
+ rem_anchor_token(T_inline);
+ rem_anchor_token(T_if);
+ rem_anchor_token(T_goto);
+ rem_anchor_token(T_for);
+ rem_anchor_token(T_float);
+ rem_anchor_token(T_false);
+ rem_anchor_token(T_extern);
+ rem_anchor_token(T_enum);
+ rem_anchor_token(T_dynamic_cast);
+ rem_anchor_token(T_do);
+ rem_anchor_token(T_double);
+ rem_anchor_token(T_delete);
+ rem_anchor_token(T_default);
+ rem_anchor_token(T_continue);
+ rem_anchor_token(T_const_cast);
+ rem_anchor_token(T_const);
+ rem_anchor_token(T_class);
+ rem_anchor_token(T_char);
+ rem_anchor_token(T_case);
+ rem_anchor_token(T_break);
+ rem_anchor_token(T_bool);
+ rem_anchor_token(T_auto);
+ rem_anchor_token(T_asm);
+ rem_anchor_token(T___thread);
+ rem_anchor_token(T___real__);
+ rem_anchor_token(T___label__);
+ rem_anchor_token(T___imag__);
+ rem_anchor_token(T___func__);
+ rem_anchor_token(T___extension__);
+ rem_anchor_token(T___builtin_va_start);
+ rem_anchor_token(T___attribute__);
+ rem_anchor_token(T___alignof__);
+ rem_anchor_token(T___PRETTY_FUNCTION__);
+ rem_anchor_token(T___FUNCTION__);
+ rem_anchor_token(T__Imaginary);
+ rem_anchor_token(T__Complex);
+ rem_anchor_token(T__Bool);
+ rem_anchor_token(T_WIDE_STRING_LITERAL);
+ rem_anchor_token(T_WIDE_CHARACTER_CONSTANT);
+ rem_anchor_token(T_STRING_LITERAL);
+ rem_anchor_token(T_PLUSPLUS);
+ rem_anchor_token(T_MINUSMINUS);
+ rem_anchor_token(T_INTEGER);
+ rem_anchor_token(T_IDENTIFIER);
+ rem_anchor_token(T_FLOATINGPOINT);
+ rem_anchor_token(T_COLONCOLON);
+ rem_anchor_token(T_CHARACTER_CONSTANT);
+ rem_anchor_token('~');
+ rem_anchor_token('{');
+ rem_anchor_token('-');
+ rem_anchor_token('+');
+ rem_anchor_token('*');
+ rem_anchor_token('(');
+ rem_anchor_token('&');
+ rem_anchor_token('!');
rem_anchor_token('}');
assert(current_scope == &statement->compound.scope);
scope_pop(old_scope);
statement_t *statement = allocate_statement_zero(STATEMENT_ASM);
eat(T_asm);
- expect('(');
+ expect('(', end_error);
statement->asms.asm_text = parse_string_literals();
statement->base.next = unit->global_asm;
unit->global_asm = statement;
- expect(')');
- expect(';');
+ expect(')', end_error);
+ expect(';', end_error);
end_error:;
}
if (token.type == '{') {
next_token();
parse_externals();
- expect('}');
+ expect('}', end_error);
} else {
parse_external();
}