return true;
}
-static expression_t *parse_compound_literal(source_position_t const *const pos, 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;
+ bool global_scope = current_scope == file_scope;
parse_initializer_env_t env;
env.type = type;
env.entity = NULL;
- env.must_be_constant = false;
+ env.must_be_constant = global_scope;
initializer_t *initializer = parse_initializer(&env);
type = env.type;
- expression->compound_literal.initializer = initializer;
- expression->compound_literal.type = type;
- expression->base.type = automatic_type_conversion(type);
+ expression->base.type = automatic_type_conversion(type);
+ expression->compound_literal.initializer = initializer;
+ expression->compound_literal.type = type;
+ expression->compound_literal.global_scope = global_scope;
return expression;
}
static expression_t *parse_function_keyword(funcname_kind_t const kind)
{
if (current_function == NULL) {
- errorf(HERE, "'%K' used outside of a function", &token);
+ errorf(HERE, "%K used outside of a function", &token);
}
expression_t *expression = allocate_expression_zero(EXPR_FUNCNAME);
type_t *const type = skip_typeref(orig_type);
if (!is_type_arithmetic(type)) {
if (is_type_valid(type)) {
- /* TODO: improve error message */
- errorf(&expression->base.source_position,
- "operation needs an arithmetic type");
+ source_position_t const *const pos = &expression->base.source_position;
+ errorf(pos, "operand of unary expression must have arithmetic type, but is '%T'", orig_type);
}
return;
} else if (is_type_integer(type)) {
type_t *const type_right = skip_typeref(orig_type_right);
if (!is_type_arithmetic(type_left) || !is_type_arithmetic(type_right)) {
- /* TODO: improve error message */
if (is_type_valid(type_left) && is_type_valid(type_right)) {
- errorf(&expression->base.source_position,
- "operation needs arithmetic types");
+ source_position_t const *const pos = &expression->base.source_position;
+ errorf(pos, "operands of binary expression must have arithmetic types, but are '%T' and '%T'", orig_type_left, orig_type_right);
}
return;
}
type_t *const type_right = skip_typeref(orig_type_right);
if (!is_type_integer(type_left) || !is_type_integer(type_right)) {
- /* TODO: improve error message */
if (is_type_valid(type_left) && is_type_valid(type_right)) {
- errorf(&expression->base.source_position,
- "operation needs integer types");
+ source_position_t const *const pos = &expression->base.source_position;
+ errorf(pos, "operands of binary expression must have integer types, but are '%T' and '%T'", orig_type_left, orig_type_right);
}
return;
}
type_t * type_right = skip_typeref(orig_type_right);
if (!is_type_integer(type_left) || !is_type_integer(type_right)) {
- /* TODO: improve error message */
if (is_type_valid(type_left) && is_type_valid(type_right)) {
- errorf(&expression->base.source_position,
- "operands of shift operation must have integer types");
+ source_position_t const *const pos = &expression->base.source_position;
+ errorf(pos, "operands of shift expression must have integer types, but are '%T' and '%T'", orig_type_left, orig_type_right);
}
return false;
}