static statement_t *parse_compound_statement(bool inside_expression_statement);
static statement_t *parse_statement(void);
-static expression_t *parse_sub_expression(precedence_t);
+static expression_t *parse_subexpression(precedence_t);
static expression_t *parse_expression(void);
static type_t *parse_typename(void);
static void parse_externals(void);
static expression_t *parse_constant_expression(void)
{
- expression_t *result = parse_sub_expression(PREC_CONDITIONAL);
+ expression_t *result = parse_subexpression(PREC_CONDITIONAL);
if (!is_constant_expression(result)) {
errorf(&result->base.source_position,
static expression_t *parse_assignment_expression(void)
{
- return parse_sub_expression(PREC_ASSIGNMENT);
+ return parse_subexpression(PREC_ASSIGNMENT);
}
static void warn_string_concat(const source_position_t *pos)
parsed_array_t array;
};
+static construct_type_t *allocate_declarator_zero(construct_type_kind_t const kind, size_t const size)
+{
+ construct_type_t *const cons = obstack_alloc(&temp_obst, size);
+ memset(cons, 0, size);
+ cons->kind = kind;
+ return cons;
+}
+
/* §6.7.5.1 */
static construct_type_t *parse_pointer_declarator(void)
{
eat('*');
- parsed_pointer_t *pointer = obstack_alloc(&temp_obst, sizeof(pointer[0]));
- memset(pointer, 0, sizeof(pointer[0]));
- pointer->base.kind = CONSTRUCT_POINTER;
- pointer->type_qualifiers = parse_type_qualifiers();
- //pointer->base_variable = base_variable;
+ construct_type_t *const cons = allocate_declarator_zero(CONSTRUCT_POINTER, sizeof(parsed_pointer_t));
+ cons->pointer.type_qualifiers = parse_type_qualifiers();
+ //cons->pointer.base_variable = base_variable;
- return (construct_type_t*) pointer;
+ return cons;
}
/* ISO/IEC 14882:1998(E) §8.3.2 */
{
eat('&');
- construct_type_t *cons = obstack_alloc(&temp_obst, sizeof(cons->reference));
- parsed_reference_t *reference = &cons->reference;
- memset(reference, 0, sizeof(*reference));
- cons->kind = CONSTRUCT_REFERENCE;
+ if (!(c_mode & _CXX))
+ errorf(HERE, "references are only available for C++");
+
+ construct_type_t *const cons = allocate_declarator_zero(CONSTRUCT_REFERENCE, sizeof(parsed_reference_t));
return cons;
}
eat('[');
add_anchor_token(']');
- construct_type_t *cons = obstack_alloc(&temp_obst, sizeof(cons->array));
- parsed_array_t *array = &cons->array;
- memset(array, 0, sizeof(*array));
- cons->kind = CONSTRUCT_ARRAY;
+ construct_type_t *const cons = allocate_declarator_zero(CONSTRUCT_ARRAY, sizeof(parsed_array_t));
+ parsed_array_t *const array = &cons->array;
- if (next_if(T_static))
- array->is_static = true;
+ bool is_static = next_if(T_static);
type_qualifiers_t type_qualifiers = parse_type_qualifiers();
- if (type_qualifiers != 0 && next_if(T_static))
- array->is_static = true;
+
+ if (!is_static)
+ is_static = next_if(T_static);
+
array->type_qualifiers = type_qualifiers;
+ array->is_static = is_static;
+ expression_t *size = NULL;
if (token.type == '*' && look_ahead(1)->type == ']') {
array->is_variable = true;
next_token();
} else if (token.type != ']') {
- expression_t *const size = parse_assignment_expression();
+ size = parse_assignment_expression();
/* §6.7.5.2:1 Array size must have integer type */
type_t *const orig_type = size->base.type;
mark_vars_read(size, NULL);
}
+ if (is_static && size == NULL)
+ errorf(HERE, "static array parameters require a size");
+
rem_anchor_token(']');
expect(']', end_error);
parse_parameters(ftype, scope);
- construct_type_t *cons = obstack_alloc(&temp_obst, sizeof(cons->function));
- construct_function_type_t *function = &cons->function;
- memset(function, 0, sizeof(*function));
- cons->kind = CONSTRUCT_FUNCTION;
- function->function_type = type;
+ construct_type_t *const cons = allocate_declarator_zero(CONSTRUCT_FUNCTION, sizeof(construct_function_type_t));
+ cons->function.function_type = type;
return cons;
}
//variable_t *based = NULL; /* MS __based extension */
switch (token.type) {
case '&':
- if (!(c_mode & _CXX))
- errorf(HERE, "references are only available for C++");
type = parse_reference_declarator();
break;
expression_t *cast = allocate_expression_zero(EXPR_UNARY_CAST);
cast->base.source_position = source_position;
- expression_t *value = parse_sub_expression(PREC_CAST);
+ expression_t *value = parse_subexpression(PREC_CAST);
cast->base.type = type;
cast->unary.value = value;
goto typeprop_expression;
}
} else {
- expression = parse_sub_expression(PREC_UNARY);
+ expression = parse_subexpression(PREC_UNARY);
typeprop_expression:
tp_expression->typeprop.tp_expression = expression;
expect(':', end_error);
end_error:;
expression_t *false_expression =
- parse_sub_expression(c_mode & _CXX ? PREC_ASSIGNMENT : PREC_CONDITIONAL);
+ parse_subexpression(c_mode & _CXX ? PREC_ASSIGNMENT : PREC_CONDITIONAL);
type_t *const orig_true_type = true_expression->base.type;
type_t *const orig_false_type = false_expression->base.type;
bool old_gcc_extension = in_gcc_extension;
in_gcc_extension = true;
- expression_t *expression = parse_sub_expression(PREC_UNARY);
+ expression_t *expression = parse_subexpression(PREC_UNARY);
in_gcc_extension = old_gcc_extension;
return expression;
}
end_error:;
}
- expression_t *const value = parse_sub_expression(PREC_CAST);
+ expression_t *const value = parse_subexpression(PREC_CAST);
result->unary.value = value;
type_t *const type = skip_typeref(value->base.type);
expression_t *unary_expression \
= allocate_expression_zero(unexpression_type); \
eat(token_type); \
- unary_expression->unary.value = parse_sub_expression(PREC_UNARY); \
+ unary_expression->unary.value = parse_subexpression(PREC_UNARY); \
\
sfunc(&unary_expression->unary); \
\
binexpr->binary.left = left; \
eat(token_type); \
\
- expression_t *right = parse_sub_expression(prec_r); \
+ expression_t *right = parse_subexpression(prec_r); \
\
binexpr->binary.right = right; \
sfunc(&binexpr->binary); \
CREATE_BINEXPR_PARSER(',', EXPR_BINARY_COMMA, PREC_ASSIGNMENT, semantic_comma)
-static expression_t *parse_sub_expression(precedence_t precedence)
+static expression_t *parse_subexpression(precedence_t precedence)
{
if (token.type < 0) {
return expected_expression_error();
*/
static expression_t *parse_expression(void)
{
- return parse_sub_expression(PREC_EXPRESSION);
+ return parse_subexpression(PREC_EXPRESSION);
}
/**
expect('(', end_error);
add_anchor_token(')');
- add_anchor_token(':');
+ if (token.type != T_STRING_LITERAL) {
+ parse_error_expected("after asm(", T_STRING_LITERAL, NULL);
+ goto end_of_asm;
+ }
asm_statement->asm_text = parse_string_literals();
+ add_anchor_token(':');
if (!next_if(':')) {
rem_anchor_token(':');
goto end_of_asm;