#include "adt/array.h"
//#define PRINT_TOKENS
-#define MAX_LOOKAHEAD 2
+#define MAX_LOOKAHEAD 1
typedef struct {
entity_t *old_entity;
/** The lookahead ring-buffer. */
static token_t lookahead_buffer[MAX_LOOKAHEAD];
/** Position of the next token in the lookahead buffer. */
-static int lookahead_bufpos;
+static size_t lookahead_bufpos;
static stack_entry_t *environment_stack = NULL;
static stack_entry_t *label_stack = NULL;
static scope_t *file_scope = NULL;
[ENTITY_LOCAL_LABEL] = sizeof(label_t),
[ENTITY_NAMESPACE] = sizeof(namespace_t)
};
- assert(kind < sizeof(sizes) / sizeof(sizes[0]));
+ assert(kind < lengthof(sizes));
assert(sizes[kind] != 0);
return sizes[kind];
}
[STATEMENT_MS_TRY] = sizeof(ms_try_statement_t),
[STATEMENT_LEAVE] = sizeof(leave_statement_t)
};
- assert(kind < sizeof(sizes) / sizeof(sizes[0]));
+ assert(kind < lengthof(sizes));
assert(sizes[kind] != 0);
return sizes[kind];
}
if (kind >= EXPR_BINARY_FIRST && kind <= EXPR_BINARY_LAST) {
return sizes[EXPR_BINARY_FIRST];
}
- assert(kind < sizeof(sizes) / sizeof(sizes[0]));
+ assert(kind < lengthof(sizes));
assert(sizes[kind] != 0);
return sizes[kind];
}
[TYPE_TYPEDEF] = sizeof(typedef_type_t),
[TYPE_TYPEOF] = sizeof(typeof_type_t),
};
- assert(sizeof(sizes) / sizeof(sizes[0]) == (int) TYPE_TYPEOF + 1);
+ assert(lengthof(sizes) == (int)TYPE_TYPEOF + 1);
assert(kind <= TYPE_TYPEOF);
assert(sizes[kind] != 0);
return sizes[kind];
[INITIALIZER_LIST] = sizeof(initializer_list_t),
[INITIALIZER_DESIGNATOR] = sizeof(initializer_designator_t)
};
- assert(kind < sizeof(sizes) / sizeof(*sizes));
+ assert(kind < lengthof(sizes));
assert(sizes[kind] != 0);
return sizes[kind];
}
lookahead_buffer[lookahead_bufpos] = lexer_token;
lexer_next_token();
- lookahead_bufpos = (lookahead_bufpos+1) % MAX_LOOKAHEAD;
+ lookahead_bufpos = (lookahead_bufpos + 1) % MAX_LOOKAHEAD;
#ifdef PRINT_TOKENS
print_token(stderr, &token);
/**
* Return the next token with a given lookahead.
*/
-static inline const token_t *look_ahead(int num)
+static inline const token_t *look_ahead(size_t num)
{
- assert(num > 0 && num <= MAX_LOOKAHEAD);
- int pos = (lookahead_bufpos+num-1) % MAX_LOOKAHEAD;
+ assert(0 < num && num <= MAX_LOOKAHEAD);
+ size_t pos = (lookahead_bufpos + num - 1) % MAX_LOOKAHEAD;
return &lookahead_buffer[pos];
}
type->base.qualifiers = qualifiers;
type->base.modifiers = modifiers;
- type = identify_new_type(type);
+ if (newtype) {
+ type = identify_new_type(type);
+ } else {
+ type = typehash_insert(type);
+ }
type = handle_type_attributes(specifiers->gnu_attributes, type);
specifiers->type = type;
type_t *const orig_type = decl->type;
assert(orig_type != NULL);
type_t *const type = skip_typeref(orig_type);
- type_t * prev_type = skip_typeref(prev_decl->type);
+ type_t *const prev_type = skip_typeref(prev_decl->type);
if (!types_compatible(type, prev_type)) {
errorf(pos,
prev_decl->type, symbol);
}
- unsigned new_storage_class = decl->storage_class;
- if (is_type_incomplete(prev_type)) {
- prev_decl->type = type;
- prev_type = type;
- }
+ storage_class_tag_t new_storage_class = decl->storage_class;
/* pretend no storage class means extern for function
* declarations (except if the previous declaration is neither
* none nor extern) */
if (entity->kind == ENTITY_FUNCTION) {
- if (prev_type->function.unspecified_parameters) {
+ if (prev_type->function.unspecified_parameters)
prev_decl->type = type;
- prev_type = type;
- }
switch (old_storage_class) {
case STORAGE_CLASS_NONE:
default:
break;
}
+ } else if (is_type_incomplete(prev_type)) {
+ prev_decl->type = type;
}
if (old_storage_class == STORAGE_CLASS_EXTERN &&
if (!is_type_incomplete(type))
return;
- /* GCC allows global arrays without size and assigns them a length of one,
- * if no different declaration follows */
- if (is_type_array(type) &&
- c_mode & _GNUC &&
- ent->base.parent_scope == file_scope) {
+ /* §6.9.2:2 and §6.9.2:5: At the end of the translation incomplete arrays
+ * are given length one. */
+ if (is_type_array(type) && ent->base.parent_scope == file_scope) {
ARR_APP1(declaration_t*, incomplete_arrays, decl);
return;
}
if (next == NULL) {
noreturn_candidate = false;
- type_t *const type = current_function->base.type;
+ type_t *const type = skip_typeref(current_function->base.type);
assert(is_type_function(type));
type_t *const ret = skip_typeref(type->function.return_type);
if (warning.return_type &&
/**
* Check the semantic restrictions for a div/mod expression.
*/
-static void semantic_divmod_arithmetic(binary_expression_t *expression) {
+static void semantic_divmod_arithmetic(binary_expression_t *expression)
+{
semantic_binexpr_arithmetic(expression);
warn_div_by_zero(expression);
}
*
* @param statement the switch statement to check
*/
-static void check_enum_cases(const switch_statement_t *statement) {
+static void check_enum_cases(const switch_statement_t *statement)
+{
const type_t *type = skip_typeref(statement->expression->base.type);
if (! is_type_enum(type))
return;
return result;
}
-/* GCC allows global arrays without size and assigns them a length of one,
- * if no different declaration follows */
+/* §6.9.2:2 and §6.9.2:5: At the end of the translation incomplete arrays
+ * are given length one. */
static void complete_incomplete_arrays(void)
{
size_t n = ARR_LEN(incomplete_arrays);