type_qualifiers_t qualifiers = TYPE_QUALIFIER_NONE;
type_modifiers_t modifiers = TYPE_MODIFIER_NONE;
unsigned type_specifiers = 0;
- int newtype = 0;
+ bool newtype = false;
specifiers->source_position = token.source_position;
}
} else if ((type_specifiers & SPECIFIER_SIGNED) &&
(type_specifiers & SPECIFIER_UNSIGNED)) {
- errorf(HERE, "signed and unsigned specifiers gives");
+ errorf(HERE, "signed and unsigned specifiers given");
} else if (type_specifiers & (SPECIFIER_SIGNED | SPECIFIER_UNSIGNED)) {
errorf(HERE, "only integer types can be signed or unsigned");
} else {
type = allocate_type_zero(TYPE_ATOMIC, &builtin_source_position);
type->atomic.akind = atomic_type;
}
- newtype = 1;
- } else {
- if (type_specifiers != 0) {
- errorf(HERE, "multiple datatypes in declaration");
- }
+ newtype = true;
+ } else if (type_specifiers != 0) {
+ errorf(HERE, "multiple datatypes in declaration");
}
/* FIXME: check type qualifiers here */
else if (second == NULL) second = "stdcall";
}
if (declaration->modifiers & DM_FASTCALL) {
- if (first == NULL) first = "faslcall";
+ if (first == NULL) first = "fastcall";
else if (second == NULL) second = "fastcall";
}
if (declaration->modifiers & DM_THISCALL) {
next_token();
add_anchor_token(')');
inner_types = parse_inner_declarator(declaration, may_be_abstract);
+ /* All later declarators only modify the return type, not declaration */
+ declaration = NULL;
rem_anchor_token(')');
expect(')');
break;
const declaration_specifiers_t *specifiers, bool may_be_abstract)
{
declaration_t *const declaration = allocate_declaration_zero();
+ declaration->source_position = specifiers->source_position;
declaration->declared_storage_class = specifiers->declared_storage_class;
declaration->modifiers = specifiers->modifiers;
declaration->deprecated_string = specifiers->deprecated_string;
type_t *const ret = skip_typeref(type->function.return_type);
if (warning.return_type &&
!is_type_atomic(ret, ATOMIC_TYPE_VOID) &&
+ is_type_valid(ret) &&
!is_sym_main(current_function->symbol)) {
warningf(&stmt->base.source_position,
"control reaches end of non-void function");
|| parameter->parent_scope == scope);
parameter->parent_scope = scope;
if (parameter->symbol == NULL) {
- errorf(&ndeclaration->source_position, "parameter name omitted");
+ errorf(¶meter->source_position, "parameter name omitted");
continue;
}
environment_push(parameter);
static expression_t *parse_conditional_expression(unsigned precedence,
expression_t *expression)
{
- eat('?');
- add_anchor_token(':');
-
expression_t *result = allocate_expression_zero(EXPR_CONDITIONAL);
conditional_expression_t *conditional = &result->conditional;
- conditional->condition = expression;
+ conditional->base.source_position = *HERE;
+ conditional->condition = expression;
+
+ eat('?');
+ add_anchor_token(':');
/* 6.5.15.2 */
type_t *const condition_type_orig = expression->base.type;
is_type_atomic(false_type, ATOMIC_TYPE_VOID)) {
if (!is_type_atomic(true_type, ATOMIC_TYPE_VOID)
|| !is_type_atomic(false_type, ATOMIC_TYPE_VOID)) {
- warningf(&expression->base.source_position,
+ warningf(&conditional->base.source_position,
"ISO C forbids conditional expression with only one void side");
}
result_type = type_void;
get_unqualified_type(to2))) {
to = to1;
} else {
- warningf(&expression->base.source_position,
+ warningf(&conditional->base.source_position,
"pointer types '%T' and '%T' in conditional expression are incompatible",
true_type, false_type);
to = type_void;
result_type = make_pointer_type(type, TYPE_QUALIFIER_NONE);
} else if (is_type_integer(other_type)) {
- warningf(&expression->base.source_position,
+ warningf(&conditional->base.source_position,
"pointer/integer type mismatch in conditional expression ('%T' and '%T')", true_type, false_type);
result_type = pointer_type;
} else {
if (is_type_valid(true_type) && is_type_valid(false_type)) {
type_error_incompatible("while parsing conditional",
- &expression->base.source_position, true_type,
+ &conditional->base.source_position, true_type,
false_type);
}
result_type = type_error_type;