break;
}
- /* Because of scopes and appending other namespaces to the end of
- * the list, this must hold. */
- assert((old_declaration != NULL ? old_declaration->symbol_next : NULL) == iter->symbol_next);
- *anchor = old_declaration;
+ /* Not all declarations adhere scopes (e.g. jump labels), so this
+ * correction is necessary */
+ if (old_declaration != NULL) {
+ old_declaration->symbol_next = iter->symbol_next;
+ *anchor = old_declaration;
+ } else {
+ *anchor = iter->symbol_next;
+ }
}
ARR_SHRINKLEN(*stack_ptr, (int) new_top);
}
switch(kind) {
- case GNU_AK_CONST:
case GNU_AK_VOLATILE:
case GNU_AK_NAKED:
case GNU_AK_MALLOC:
case GNU_AK_UNUSED: modifiers |= DM_UNUSED; goto no_arg;
case GNU_AK_USED: modifiers |= DM_USED; goto no_arg;
case GNU_AK_PURE: modifiers |= DM_PURE; goto no_arg;
+ case GNU_AK_CONST: modifiers |= DM_CONST; goto no_arg;
case GNU_AK_ALWAYS_INLINE: modifiers |= DM_FORCEINLINE; goto no_arg;
case GNU_AK_DLLIMPORT: modifiers |= DM_DLLIMPORT; goto no_arg;
case GNU_AK_DLLEXPORT: modifiers |= DM_DLLEXPORT; goto no_arg;
&expression->base.source_position);
initializer_t *const result = allocate_initializer_zero(INITIALIZER_VALUE);
+#if 0
+ if (type->kind == TYPE_BITFIELD) {
+ type = type->bitfield.base_type;
+ }
+#endif
result->value.value = create_implicit_cast(expression, type);
return result;
"'.%Y' designator used for non-compound type '%T'",
symbol, orig_type);
}
- goto failed;
- }
- declaration_t *declaration = type->compound.declaration;
- declaration_t *iter = declaration->scope.declarations;
- for( ; iter != NULL; iter = iter->next) {
- if (iter->symbol == symbol) {
- break;
+ top->type = type_error_type;
+ top->v.compound_entry = NULL;
+ orig_type = type_error_type;
+ } else {
+ declaration_t *declaration = type->compound.declaration;
+ declaration_t *iter = declaration->scope.declarations;
+ for( ; iter != NULL; iter = iter->next) {
+ if (iter->symbol == symbol) {
+ break;
+ }
}
- }
- if (iter == NULL) {
- errorf(&designator->source_position,
- "'%T' has no member named '%Y'", orig_type, symbol);
- goto failed;
- }
- if (used_in_offsetof) {
- type_t *real_type = skip_typeref(iter->type);
- if (real_type->kind == TYPE_BITFIELD) {
+ if (iter == NULL) {
errorf(&designator->source_position,
- "offsetof designator '%Y' may not specify bitfield",
- symbol);
+ "'%T' has no member named '%Y'", orig_type, symbol);
goto failed;
}
- }
+ if (used_in_offsetof) {
+ type_t *real_type = skip_typeref(iter->type);
+ if (real_type->kind == TYPE_BITFIELD) {
+ errorf(&designator->source_position,
+ "offsetof designator '%Y' may not specify bitfield",
+ symbol);
+ goto failed;
+ }
+ }
- top->type = orig_type;
- top->v.compound_entry = iter;
- orig_type = iter->type;
+ top->type = orig_type;
+ top->v.compound_entry = iter;
+ orig_type = iter->type;
+ }
} else {
expression_t *array_index = designator->array_index;
assert(designator->array_index != NULL);
}
goto failed;
}
- if (!is_type_valid(array_index->base.type)) {
- goto failed;
- }
long index = fold_constant(array_index);
if (!used_in_offsetof) {
if (index < 0) {
errorf(&designator->source_position,
"array index [%E] must be positive", array_index);
- goto failed;
- }
- if (type->array.size_constant == true) {
+ } else if (type->array.size_constant) {
long array_size = type->array.size;
if (index >= array_size) {
errorf(&designator->source_position,
"designator [%E] (%d) exceeds array size %d",
array_index, index, array_size);
- goto failed;
}
}
}
path->top_type = entry->type;
return;
}
- } else {
+ } else if (is_type_array(type)) {
assert(is_type_array(type));
top->v.index++;
if (!type->array.size_constant || top->v.index < type->array.size) {
return;
}
+ } else {
+ assert(!is_type_valid(type));
+ return;
}
/* we're past the last member of the current sub-aggregate, try if we
/* We are initializing an empty compound. */
} else {
type = skip_typeref(orig_type);
-
- /* we can't do usefull stuff if we didn't even parse the type. Skip the
- * initializers in this case. */
- if (!is_type_valid(type)) {
- skip_initializers();
- return create_empty_initializer();
- }
}
initializer_t **initializers = NEW_ARR_F(initializer_t*, 0);
if (type == NULL) {
/* we are already outside, ... */
- if (is_type_compound(outer_type) &&
- !outer_type->compound.declaration->init.complete) {
+ type_t *const outer_type_skip = skip_typeref(outer_type);
+ if (is_type_compound(outer_type_skip) &&
+ !outer_type_skip->compound.declaration->init.complete) {
goto error_parse_next;
}
goto error_excess;
return make_function_1_type(type_void_ptr, type_size_t);
case T___builtin_huge_val:
return make_function_0_type(type_double);
+ case T___builtin_inf:
+ return make_function_0_type(type_double);
+ case T___builtin_inff:
+ return make_function_0_type(type_float);
+ case T___builtin_infl:
+ return make_function_0_type(type_long_double);
case T___builtin_nan:
return make_function_1_type(type_double, type_char_ptr);
case T___builtin_nanf:
return make_function_1_type(type_float, type_char_ptr);
- case T___builtin_nand:
+ case T___builtin_nanl:
return make_function_1_type(type_long_double, type_char_ptr);
case T___builtin_va_end:
return make_function_1_type(type_void, type_valist);
case T___builtin_va_arg: return parse_va_arg();
case T___builtin_expect:
case T___builtin_alloca:
+ case T___builtin_inf:
+ case T___builtin_inff:
+ case T___builtin_infl:
case T___builtin_nan:
- case T___builtin_nand:
case T___builtin_nanf:
+ case T___builtin_nanl:
case T___builtin_huge_val:
case T___builtin_va_end: return parse_builtin_symbol();
case T___builtin_isgreater:
return true;
default:
- return false;
+ /* Claim it is an lvalue, if the type is invalid. There was a parse
+ * error before, which maybe prevented properly recognizing it as
+ * lvalue. */
+ return !is_type_valid(skip_typeref(expression->base.type));
}
}
value->base.type = revert_automatic_type_conversion(value);
type_t *orig_type = value->base.type;
- if (!is_type_valid(orig_type))
+ if (!is_type_valid(skip_typeref(orig_type)))
return;
set_address_taken(value, false);
/* This check does not prevent the error message in all cases of an
* prior error while parsing the expression. At least it catches the
* common case of a mistyped enum entry. */
- if (is_type_valid(expression->base.type)) {
+ if (is_type_valid(skip_typeref(expression->base.type))) {
errorf(pos, "case label does not reduce to an integer constant");
}
statement->case_label.is_bad = true;
/* This check does not prevent the error message in all cases of an
* prior error while parsing the expression. At least it catches the
* common case of a mistyped enum entry. */
- if (is_type_valid(end_range->base.type)) {
+ if (is_type_valid(skip_typeref(end_range->base.type))) {
errorf(pos, "case range does not reduce to an integer constant");
}
statement->case_label.is_bad = true;
PUSH_PARENT(statement);
+ add_anchor_token('{');
+
expect('(');
add_anchor_token(')');
statement->ifs.condition = parse_expression();
rem_anchor_token(')');
expect(')');
+end_error:
+ rem_anchor_token('{');
+
add_anchor_token(T_else);
statement->ifs.true_statement = parse_statement();
rem_anchor_token(T_else);
POP_PARENT;
return statement;
-end_error:
- POP_PARENT;
- return create_invalid_statement();
}
/**
case T___builtin_islessequal:
case T___builtin_islessgreater:
case T___builtin_isunordered:
+ case T___builtin_inf:
+ case T___builtin_inff:
+ case T___builtin_infl:
case T___builtin_nan:
- case T___builtin_nand:
case T___builtin_nanf:
+ case T___builtin_nanl:
case T___builtin_offsetof:
case T___builtin_prefetch:
case T___builtin_va_arg: