static void semantic_parameter(declaration_t *declaration)
{
/* TODO: improve error messages */
+ source_position_t const* const pos = &declaration->source_position;
- if (declaration->declared_storage_class == STORAGE_CLASS_TYPEDEF) {
- errorf(HERE, "typedef not allowed in parameter list");
- } else if (declaration->declared_storage_class != STORAGE_CLASS_NONE
- && declaration->declared_storage_class != STORAGE_CLASS_REGISTER) {
- errorf(HERE, "parameter may only have none or register storage class");
+ switch (declaration->declared_storage_class) {
+ case STORAGE_CLASS_TYPEDEF:
+ errorf(pos, "typedef not allowed in parameter list");
+ break;
+
+ /* Allowed storage classes */
+ case STORAGE_CLASS_NONE:
+ case STORAGE_CLASS_REGISTER:
+ break;
+
+ default:
+ errorf(pos, "parameter may only have none or register storage class");
+ break;
}
type_t *const orig_type = declaration->type;
declaration->type = type;
if (is_type_incomplete(skip_typeref(type))) {
- errorf(HERE, "incomplete type '%T' not allowed for parameter '%Y'",
+ errorf(pos, "incomplete type '%T' not allowed for parameter '%Y'",
orig_type, declaration->symbol);
}
}
type, orig_type);
} else if (!is_type_real(type) && is_type_valid(type)) {
/* TODO: improve error message */
- errorf(HERE, "operation needs an arithmetic or pointer type");
+ errorf(&expression->base.source_position,
+ "operation needs an arithmetic or pointer type");
}
expression->base.type = orig_type;
}
if (!is_type_arithmetic(type)) {
if (is_type_valid(type)) {
/* TODO: improve error message */
- errorf(HERE, "operation needs an arithmetic type");
+ errorf(&expression->base.source_position,
+ "operation needs an arithmetic type");
}
return;
}
type_t *const orig_type = expression->value->base.type;
type_t *const type = skip_typeref(orig_type);
if (!is_type_scalar(type) && is_type_valid(type)) {
- errorf(HERE, "operand of ! must be of scalar type");
+ errorf(&expression->base.source_position,
+ "operand of ! must be of scalar type");
}
expression->base.type = type_int;
type_t *const type = skip_typeref(orig_type);
if (!is_type_integer(type)) {
if (is_type_valid(type)) {
- errorf(HERE, "operand of ~ must be of integer type");
+ errorf(&expression->base.source_position,
+ "operand of ~ must be of integer type");
}
return;
}
type_t *const type = skip_typeref(orig_type);
if (!is_type_pointer(type)) {
if (is_type_valid(type)) {
- errorf(HERE, "Unary '*' needs pointer or arrray type, but type '%T' given", orig_type);
+ errorf(&expression->base.source_position,
+ "Unary '*' needs pointer or arrray type, but type '%T' given", orig_type);
}
return;
}
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(HERE, "operation needs arithmetic types");
+ errorf(&expression->base.source_position,
+ "operation needs arithmetic types");
}
return;
}
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(HERE, "operation needs integer types");
+ errorf(&expression->base.source_position,
+ "operands of shift operation must have integer types");
}
return;
}
static void semantic_sub(binary_expression_t *expression)
{
- expression_t *const left = expression->left;
- expression_t *const right = expression->right;
- type_t *const orig_type_left = left->base.type;
- type_t *const orig_type_right = right->base.type;
- type_t *const type_left = skip_typeref(orig_type_left);
- type_t *const type_right = skip_typeref(orig_type_right);
+ expression_t *const left = expression->left;
+ expression_t *const right = expression->right;
+ type_t *const orig_type_left = left->base.type;
+ type_t *const orig_type_right = right->base.type;
+ type_t *const type_left = skip_typeref(orig_type_left);
+ type_t *const type_right = skip_typeref(orig_type_right);
+ source_position_t const *const pos = &expression->base.source_position;
/* ยง 5.6.5 */
if (is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) {
type_t *const unqual_left = get_unqualified_type(skip_typeref(type_left->pointer.points_to));
type_t *const unqual_right = get_unqualified_type(skip_typeref(type_right->pointer.points_to));
if (!types_compatible(unqual_left, unqual_right)) {
- errorf(&expression->base.source_position,
+ errorf(pos,
"subtracting pointers to incompatible types '%T' and '%T'",
orig_type_left, orig_type_right);
} else if (!is_type_object(unqual_left)) {
if (is_type_atomic(unqual_left, ATOMIC_TYPE_VOID)) {
- warningf(&expression->base.source_position,
- "subtracting pointers to void");
+ warningf(pos, "subtracting pointers to void");
} else {
- errorf(&expression->base.source_position,
- "subtracting pointers to non-object types '%T'",
+ errorf(pos, "subtracting pointers to non-object types '%T'",
orig_type_left);
}
}
expression->base.type = type_ptrdiff_t;
} else if (is_type_valid(type_left) && is_type_valid(type_right)) {
- errorf(HERE, "invalid operands of types '%T' and '%T' to binary '-'",
+ errorf(pos, "invalid operands of types '%T' and '%T' to binary '-'",
orig_type_left, 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(HERE, "operation needs arithmetic types");
+ errorf(&expression->base.source_position,
+ "operation needs arithmetic types");
}
return;
}
type_left, orig_type_left);
expression->base.type = type_left;
} else if (is_type_valid(type_left) && is_type_valid(type_right)) {
- errorf(HERE, "incompatible types '%T' and '%T' in assignment", orig_type_left, orig_type_right);
+ errorf(&expression->base.source_position,
+ "incompatible types '%T' and '%T' in assignment",
+ orig_type_left, orig_type_right);
}
}
if (!is_type_scalar(type_left) || !is_type_scalar(type_right)) {
/* TODO: improve error message */
if (is_type_valid(type_left) && is_type_valid(type_right)) {
- errorf(HERE, "operation needs scalar types");
+ errorf(&expression->base.source_position,
+ "operation needs scalar types");
}
return;
}