X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=c1f162b139ba1744e5ec02d6c11aa3da7ec82a5f;hb=c2d5fce07cb63445b4948ff7d66f5a590261483d;hp=7008dea0327299bd280cab6ad504041719fe715a;hpb=dad2cfa20847b2ec1de207f807c41c4ed3471b81;p=cparser diff --git a/parser.c b/parser.c index 7008dea..c1f162b 100644 --- a/parser.c +++ b/parser.c @@ -33,6 +33,12 @@ static context_t *context = NULL; static declaration_t *last_declaration = NULL; static struct obstack temp_obst; +static type_t *type_int = NULL; +static type_t *type_const_char = NULL; +static type_t *type_string = NULL; +static type_t *type_void = NULL; +static type_t *type_size_t = NULL; + static statement_t *parse_compound_statement(void); static statement_t *parse_statement(void); @@ -282,7 +288,7 @@ static void set_context(context_t *new_context) * called when we find a 2nd declarator for an identifier we already have a * declarator for */ -static int is_compatible_declaration (declaration_t *declaration, +static bool is_compatible_declaration (declaration_t *declaration, declaration_t *previous) { /* TODO: not correct yet */ @@ -296,18 +302,9 @@ static int is_compatible_declaration (declaration_t *declaration, static inline declaration_t *environment_push(declaration_t *declaration, const void *context) { - environment_entry_t *entry - = obstack_alloc(&environment_obstack, sizeof(entry[0])); - memset(entry, 0, sizeof(entry[0])); - - int top = ARR_LEN(environment_stack); - ARR_RESIZE(environment_stack, top + 1); - environment_stack[top] = entry; - - assert(declaration->source_position.input_name != NULL); - symbol_t *symbol = declaration->symbol; assert(declaration != symbol->declaration); + assert(declaration->source_position.input_name != NULL); if(symbol->context == context) { declaration_t *previous_declaration = symbol->declaration; @@ -329,6 +326,14 @@ static inline declaration_t *environment_push(declaration_t *declaration, } } + environment_entry_t *entry + = obstack_alloc(&environment_obstack, sizeof(entry[0])); + memset(entry, 0, sizeof(entry[0])); + + int top = ARR_LEN(environment_stack); + ARR_RESIZE(environment_stack, top + 1); + environment_stack[top] = entry; + entry->old_declaration = symbol->declaration; entry->old_context = symbol->context; entry->symbol = symbol; @@ -405,7 +410,7 @@ static compound_type_t *find_compound_type(compound_type_t *types, return NULL; } -static type_t *parse_compound_type_specifier(int is_struct) +static type_t *parse_compound_type_specifier(bool is_struct) { if(is_struct) { eat(T_struct); @@ -805,10 +810,10 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) /* TODO: if type != NULL for the following rules issue an error */ case T_struct: - type = parse_compound_type_specifier(1); + type = parse_compound_type_specifier(true); break; case T_union: - type = parse_compound_type_specifier(0); + type = parse_compound_type_specifier(false); break; case T_enum: type = parse_enum_specifier(); @@ -975,9 +980,9 @@ finish_specifiers: specifiers->type = result; } -static unsigned parse_type_qualifiers(void) +static type_qualifier_t parse_type_qualifiers(void) { - unsigned type_qualifiers = 0; + type_qualifier_t type_qualifiers = 0; while(true) { switch(token.type) { @@ -993,54 +998,6 @@ static unsigned parse_type_qualifiers(void) } } -typedef struct parsed_pointer_t parsed_pointer_t; -struct parsed_pointer_t { - unsigned type_qualifiers; - parsed_pointer_t *next; -}; - -static parsed_pointer_t *parse_pointers(void) -{ - parsed_pointer_t *result = NULL; - parsed_pointer_t *last_pointer = NULL; - - while(token.type == '*') { - next_token(); - parsed_pointer_t *pointer - = obstack_alloc(&temp_obst, sizeof(pointer[0])); - pointer->type_qualifiers = parse_type_qualifiers(); - - if(last_pointer != NULL) { - last_pointer->next = pointer; - } else { - result = pointer; - } - last_pointer = pointer; - } - - return result; -} - -static type_t *make_pointers(type_t *type, parsed_pointer_t *pointer) -{ - for( ; pointer != NULL; pointer = pointer->next) { - pointer_type_t *pointer_type - = allocate_type_zero(sizeof(pointer_type[0])); - pointer_type->type.type = TYPE_POINTER; - pointer_type->points_to = type; - pointer_type->type.qualifiers = pointer->type_qualifiers; - - type_t *result = typehash_insert((type_t*) pointer_type); - if(result != (type_t*) pointer_type) { - obstack_free(type_obst, pointer_type); - } - - type = result; - } - - return type; -} - static void parse_identifier_list(void) { while(true) { @@ -1133,25 +1090,134 @@ static declaration_t *parse_parameters(method_type_t *type) } } -typedef struct declarator_part declarator_part; -struct declarator_part { - parsed_pointer_t *pointers; +typedef enum { + CONSTRUCT_POINTER, + CONSTRUCT_METHOD, + CONSTRUCT_ARRAY +} construct_type_type_t; + +typedef struct construct_type_t construct_type_t; +struct construct_type_t { + construct_type_type_t type; + construct_type_t *next; +}; + +typedef struct parsed_pointer_t parsed_pointer_t; +struct parsed_pointer_t { + construct_type_t construct_type; + type_qualifier_t type_qualifiers; +}; + +typedef struct construct_method_type_t construct_method_type_t; +struct construct_method_type_t { + construct_type_t construct_type; method_type_t *method_type; - declarator_part *inner; }; +typedef struct parsed_array_t parsed_array_t; +struct parsed_array_t { + construct_type_t construct_type; + type_qualifier_t type_qualifiers; + bool is_static; + bool is_variable; + expression_t *size; +}; + +typedef struct construct_base_type_t construct_base_type_t; +struct construct_base_type_t { + construct_type_t construct_type; + type_t *type; +}; + +static construct_type_t *parse_pointer_declarator(void) +{ + eat('*'); + + parsed_pointer_t *pointer = obstack_alloc(&temp_obst, sizeof(pointer[0])); + memset(pointer, 0, sizeof(pointer[0])); + pointer->type_qualifiers = parse_type_qualifiers(); + + return (construct_type_t*) pointer; +} + +static construct_type_t *parse_array_declarator(void) +{ + eat('['); + + parsed_array_t *array = obstack_alloc(&temp_obst, sizeof(array[0])); + memset(array, 0, sizeof(array[0])); + + if(token.type == T_static) { + array->is_static = true; + next_token(); + } + + type_qualifier_t type_qualifiers = parse_type_qualifiers(); + if(type_qualifiers != 0) { + if(token.type == T_static) { + array->is_static = true; + next_token(); + } + } + array->type_qualifiers = type_qualifiers; + + if(token.type == '*' && look_ahead(1)->type == ']') { + array->is_variable = true; + next_token(); + } else if(token.type != ']') { + array->size = parse_assignment_expression(); + } + + expect(']'); + + return (construct_type_t*) array; +} -static declarator_part *parse_inner_declarator(declaration_t *declaration, - int may_be_abstract) +static construct_type_t *parse_method_declarator(declaration_t *declaration) { - declarator_part *part = obstack_alloc(&temp_obst, sizeof(part[0])); - memset(part, 0, sizeof(part[0])); + eat('('); + + method_type_t *method_type + = allocate_type_zero(sizeof(method_type[0])); + method_type->type.type = TYPE_METHOD; - part->pointers = parse_pointers(); + declaration_t *parameters = parse_parameters(method_type); + if(declaration != NULL) { + declaration->context.declarations = parameters; + } + + construct_method_type_t *construct_method_type = + obstack_alloc(&temp_obst, sizeof(construct_method_type[0])); + memset(construct_method_type, 0, sizeof(construct_method_type[0])); + construct_method_type->construct_type.type = CONSTRUCT_METHOD; + construct_method_type->method_type = method_type; + + expect(')'); + + return (construct_type_t*) construct_method_type; +} + +static construct_type_t *parse_inner_declarator(declaration_t *declaration, + int may_be_abstract) +{ + construct_type_t *result = NULL; + construct_type_t *last = NULL; + + while(token.type == '*') { + construct_type_t *type = parse_pointer_declarator(); + if(last != NULL) { + last->next = type; + } else { + result = type; + } + last = type; + } /* TODO: find out if this is correct */ parse_attributes(); + construct_type_t *inner_types = NULL; + switch(token.type) { case T_IDENTIFIER: if(declaration == NULL) { @@ -1164,7 +1230,7 @@ static declarator_part *parse_inner_declarator(declaration_t *declaration, break; case '(': next_token(); - part->inner = parse_inner_declarator(declaration, may_be_abstract); + inner_types = parse_inner_declarator(declaration, may_be_abstract); expect(')'); break; default: @@ -1175,76 +1241,114 @@ static declarator_part *parse_inner_declarator(declaration_t *declaration, } while(true) { + construct_type_t *type; switch(token.type) { case '(': - next_token(); - - method_type_t *method_type - = allocate_type_zero(sizeof(method_type[0])); - method_type->type.type = TYPE_METHOD; - - declaration_t *parameters = parse_parameters(method_type); - if(declaration != NULL) { - declaration->context.declarations = parameters; - } - - part->method_type = method_type; - - expect(')'); + type = parse_method_declarator(declaration); break; case '[': - next_token(); - - if(token.type == T_static) { - next_token(); - } - - unsigned type_qualifiers = parse_type_qualifiers(); - if(type_qualifiers != 0) { - if(token.type == T_static) { - next_token(); - } - } - - /* TODO */ - - if(token.type == '*' && look_ahead(1)->type == ']') { - next_token(); - } else if(token.type != ']') { - parse_assignment_expression(); - } - - expect(']'); + type = parse_array_declarator(); break; default: goto declarator_finished; } + + if(last != NULL) { + last->next = type; + } else { + result = type; + } + last = type; } declarator_finished: parse_attributes(); - return part; + if(inner_types != NULL) { + if(last != NULL) { + last->next = inner_types; + } else { + result = inner_types; + } + last = inner_types; + } + + return result; +} + +#if 0 +static type_t *make_pointers(type_t *type, parsed_pointer_t *pointer) +{ + for( ; pointer != NULL; pointer = pointer->next) { + pointer_type_t *pointer_type + = allocate_type_zero(sizeof(pointer_type[0])); + pointer_type->type.type = TYPE_POINTER; + pointer_type->points_to = type; + pointer_type->type.qualifiers = pointer->type_qualifiers; + + type_t *result = typehash_insert((type_t*) pointer_type); + if(result != (type_t*) pointer_type) { + obstack_free(type_obst, pointer_type); + } + + type = result; + } + + return type; } +#endif -static type_t *construct_declarator_type(declarator_part *part, type_t *type) +static type_t *construct_declarator_type(construct_type_t *construct_list, + type_t *type) { - do { - type = make_pointers(type, part->pointers); + construct_type_t *iter = construct_list; + for( ; iter != NULL; iter = iter->next) { + parsed_pointer_t *parsed_pointer; + parsed_array_t *parsed_array; + construct_method_type_t *construct_method_type; + method_type_t *method_type; + pointer_type_t *pointer_type; + array_type_t *array_type; + + switch(iter->type) { + case CONSTRUCT_METHOD: + construct_method_type = (construct_method_type_t*) iter; + method_type = construct_method_type->method_type; - method_type_t *method_type = part->method_type; - if(method_type != NULL) { method_type->result_type = type; + type = (type_t*) method_type; + break; - type_t *result = typehash_insert((type_t*) method_type); - if(result != (type_t*) method_type) { - obstack_free(type_obst, method_type); - } - type = result; + case CONSTRUCT_POINTER: + parsed_pointer = (parsed_pointer_t*) iter; + pointer_type = allocate_type_zero(sizeof(pointer_type[0])); + + pointer_type->type.type = TYPE_POINTER; + pointer_type->points_to = type; + pointer_type->type.qualifiers = parsed_pointer->type_qualifiers; + type = (type_t*) pointer_type; + break; + + case CONSTRUCT_ARRAY: + parsed_array = (parsed_array_t*) iter; + array_type = allocate_type_zero(sizeof(array_type[0])); + + array_type->type.type = TYPE_ARRAY; + array_type->element_type = type; + array_type->type.qualifiers = parsed_array->type_qualifiers; + array_type->is_static = parsed_array->is_static; + array_type->is_variable = parsed_array->is_variable; + array_type->size = parsed_array->size; + type = (type_t*) array_type; + break; } - part = part->inner; - } while(part != NULL); + type_t *hashed_type = typehash_insert((type_t*) type); + if(hashed_type != type) { + obstack_free(type_obst, type); + type = hashed_type; + } + } return type; } @@ -1253,25 +1357,26 @@ static void parse_declarator(declaration_t *declaration, storage_class_t storage_class, type_t *type, int may_be_abstract) { - declarator_part *part + construct_type_t *construct_type = parse_inner_declarator(declaration, may_be_abstract); - if(part != NULL) { - declaration->type = construct_declarator_type(part, type); - declaration->storage_class = storage_class; - obstack_free(&temp_obst, part); + declaration->type = construct_declarator_type(construct_type, type); + declaration->storage_class = storage_class; + if(construct_type != NULL) { + obstack_free(&temp_obst, construct_type); } } static type_t *parse_abstract_declarator(type_t *base_type) { - declarator_part *part = parse_inner_declarator(NULL, 1); + construct_type_t *construct_type + = parse_inner_declarator(NULL, 1); - if(part == NULL) + if(construct_type == NULL) return NULL; - type_t *result = construct_declarator_type(part, base_type); - obstack_free(&temp_obst, part); + type_t *result = construct_declarator_type(construct_type, base_type); + obstack_free(&temp_obst, construct_type); return result; } @@ -1490,8 +1595,9 @@ static expression_t *parse_string_const(void) { string_literal_t *cnst = allocate_ast_zero(sizeof(cnst[0])); - cnst->expression.type = EXPR_STRING_LITERAL; - cnst->value = parse_string_literals(); + cnst->expression.type = EXPR_STRING_LITERAL; + cnst->expression.datatype = type_string; + cnst->value = parse_string_literals(); return (expression_t*) cnst; } @@ -1500,8 +1606,9 @@ static expression_t *parse_int_const(void) { const_t *cnst = allocate_ast_zero(sizeof(cnst[0])); - cnst->expression.type = EXPR_CONST; - cnst->value = token.v.intvalue; + cnst->expression.type = EXPR_CONST; + cnst->expression.datatype = type_int; + cnst->value = token.v.intvalue; next_token(); @@ -1519,13 +1626,21 @@ static expression_t *parse_reference(void) parser_print_error_prefix(); fprintf(stderr, "unknown symbol '%s' found.\n", ref->symbol->string); } - ref->declaration = ref->symbol->declaration; + ref->declaration = ref->symbol->declaration; + ref->expression.datatype = ref->declaration->type; next_token(); return (expression_t*) ref; } +static void check_cast_allowed(expression_t *expression, type_t *dest_type) +{ + (void) expression; + (void) dest_type; + /* TODO check if cast is allowed and issue warnings/errors */ +} + static expression_t *parse_cast(void) { unary_expression_t *cast = allocate_ast_zero(sizeof(cast[0])); @@ -1539,6 +1654,8 @@ static expression_t *parse_cast(void) expect(')'); expression_t *value = parse_sub_expression(20); + check_cast_allowed(value, type); + cast->expression.datatype = type; cast->value = value; @@ -1552,6 +1669,22 @@ static expression_t *parse_statement_expression(void) expression->expression.type = EXPR_STATEMENT; expression->statement = parse_compound_statement(); + /* find last statement and use it's type */ + const statement_t *last_statement = NULL; + const statement_t *statement = expression->statement; + for( ; statement != NULL; statement = statement->next) { + last_statement = statement; + } + + if(last_statement->type == STATEMENT_EXPRESSION) { + const expression_statement_t *expression_statement = + (const expression_statement_t*) last_statement; + expression->expression.datatype + = expression_statement->expression->datatype; + } else { + expression->expression.datatype = type_void; + } + expect(')'); return (expression_t*) expression; @@ -1590,8 +1723,9 @@ static expression_t *parse_function_keyword(void) /* TODO */ string_literal_t *expression = allocate_ast_zero(sizeof(expression[0])); - expression->expression.type = EXPR_FUNCTION; - expression->value = "TODO: FUNCTION"; + expression->expression.type = EXPR_FUNCTION; + expression->expression.datatype = type_string; + expression->value = "TODO: FUNCTION"; return (expression_t*) expression; } @@ -1602,8 +1736,9 @@ static expression_t *parse_pretty_function_keyword(void) /* TODO */ string_literal_t *expression = allocate_ast_zero(sizeof(expression[0])); - expression->expression.type = EXPR_PRETTY_FUNCTION; - expression->value = "TODO: PRETTY FUNCTION"; + expression->expression.type = EXPR_PRETTY_FUNCTION; + expression->expression.datatype = type_string; + expression->value = "TODO: PRETTY FUNCTION"; return (expression_t*) expression; } @@ -1667,7 +1802,8 @@ static expression_t *parse_offsetof(void) offsetof_expression_t *expression = allocate_ast_zero(sizeof(expression[0])); - expression->expression.type = EXPR_OFFSETOF; + expression->expression.type = EXPR_OFFSETOF; + expression->expression.datatype = type_size_t; expect('('); expression->type = parse_typename(); @@ -1684,6 +1820,8 @@ static expression_t *parse_builtin_symbol(void) = allocate_ast_zero(sizeof(expression[0])); expression->expression.type = EXPR_BUILTIN_SYMBOL; + /* TODO: set datatype */ + expression->symbol = token.v.symbol; next_token(); @@ -1725,7 +1863,7 @@ static expression_t *parse_primary_expression(void) } static expression_t *parse_array_expression(unsigned precedence, - expression_t *array_ref) + expression_t *array_ref) { (void) precedence; @@ -1734,9 +1872,22 @@ static expression_t *parse_array_expression(unsigned precedence, array_access_expression_t *array_access = allocate_ast_zero(sizeof(array_access[0])); - array_access->expression.type = EXPR_ARRAY_ACCESS; - array_access->array_ref = array_ref; - array_access->index = parse_expression(); + array_access->expression.type = EXPR_ARRAY_ACCESS; + array_access->array_ref = array_ref; + array_access->index = parse_expression(); + + type_t *array_type = array_ref->datatype; + if(array_type != NULL) { + if(array_type->type == TYPE_POINTER) { + pointer_type_t *pointer = (pointer_type_t*) array_type; + array_access->expression.datatype = pointer->points_to; + } else { + parser_print_error_prefix(); + fprintf(stderr, "array access on object with non-pointer type "); + print_type(array_type); + fprintf(stderr, "\n"); + } + } if(token.type != ']') { parse_error_expected("Problem while parsing array access", ']', 0); @@ -1747,15 +1898,8 @@ static expression_t *parse_array_expression(unsigned precedence, return (expression_t*) array_access; } -static type_t *get_expression_type(const expression_t *expression) -{ - (void) expression; - /* TODO */ - return NULL; -} - -static int is_declaration_specifier(const token_t *token, - int only_type_specifiers) +static bool is_declaration_specifier(const token_t *token, + bool only_type_specifiers) { declaration_t *declaration; @@ -1786,15 +1930,16 @@ static expression_t *parse_sizeof(unsigned precedence) sizeof_expression_t *sizeof_expression = allocate_ast_zero(sizeof(sizeof_expression[0])); - sizeof_expression->expression.type = EXPR_SIZEOF; + sizeof_expression->expression.type = EXPR_SIZEOF; + sizeof_expression->expression.datatype = type_size_t; - if(token.type == '(' && is_declaration_specifier(look_ahead(1), 1)) { + if(token.type == '(' && is_declaration_specifier(look_ahead(1), true)) { next_token(); sizeof_expression->type = parse_typename(); expect(')'); } else { expression_t *expression = parse_sub_expression(precedence); - sizeof_expression->type = get_expression_type(expression); + sizeof_expression->type = expression->datatype; sizeof_expression->size_expression = expression; } @@ -1814,9 +1959,10 @@ static expression_t *parse_select_expression(unsigned precedence, select->expression.type = EXPR_SELECT; select->compound = compound; + /* TODO: datatype */ + if(token.type != T_IDENTIFIER) { - parse_error_expected("Problem while parsing compound select", - T_IDENTIFIER, 0); + parse_error_expected("Problem while parsing select", T_IDENTIFIER, 0); return NULL; } select->symbol = token.v.symbol; @@ -1831,8 +1977,8 @@ static expression_t *parse_call_expression(unsigned precedence, (void) precedence; call_expression_t *call = allocate_ast_zero(sizeof(call[0])); - call->expression.type = EXPR_CALL; - call->method = expression; + call->expression.type = EXPR_CALL; + call->method = expression; /* parse arguments */ eat('('); @@ -1858,9 +2004,57 @@ static expression_t *parse_call_expression(unsigned precedence, } expect(')'); + type_t *type = expression->datatype; + if(type != NULL) { + /* we can call pointer to function */ + if(type->type == TYPE_POINTER) { + pointer_type_t *pointer = (pointer_type_t*) type; + type = pointer->points_to; + } + + if(type == NULL || type->type != TYPE_METHOD) { + parser_print_error_prefix(); + fprintf(stderr, "expected a method type for call but found type "); + print_type(expression->datatype); + fprintf(stderr, "\n"); + } else { + method_type_t *method_type = (method_type_t*) type; + call->expression.datatype = method_type->result_type; + } + } + return (expression_t*) call; } +static void type_error(const char *msg, const source_position_t source_position, + const type_t *type) +{ + parser_print_error_prefix_pos(source_position); + fprintf(stderr, "%s, but found type ", msg); + print_type(type); + fputc('\n', stderr); +} + +static void type_error_incompatible(const char *msg, + const source_position_t source_position, const type_t *type1, + const type_t *type2) +{ + parser_print_error_prefix_pos(source_position); + fprintf(stderr, "%s, incompatible types: ", msg); + print_type(type1); + fprintf(stderr, " - "); + print_type(type2); + fprintf(stderr, ")\n"); +} + +static type_t *get_type_after_conversion(const type_t *type1, + const type_t *type2) +{ + /* TODO... */ + (void) type2; + return (type_t*) type1; +} + static expression_t *parse_conditional_expression(unsigned precedence, expression_t *expression) { @@ -1868,12 +2062,52 @@ static expression_t *parse_conditional_expression(unsigned precedence, conditional_expression_t *conditional = allocate_ast_zero(sizeof(conditional[0])); + conditional->expression.type = EXPR_CONDITIONAL; conditional->condition = expression; + /* 6.5.15.2 */ + type_t *condition_type = conditional->condition->datatype; + if(condition_type != NULL) { + if(!is_type_scalar(condition_type)) { + type_error("expected a scalar type", expression->source_position, + condition_type); + } + } + conditional->true_expression = parse_expression(); expect(':'); conditional->false_expression = parse_sub_expression(precedence); + type_t *true_type = conditional->true_expression->datatype; + if(true_type == NULL) + return (expression_t*) conditional; + type_t *false_type = conditional->false_expression->datatype; + if(false_type == NULL) + return (expression_t*) conditional; + + /* 6.4.15.3 */ + if(true_type == false_type) { + conditional->expression.datatype = true_type; + } else if(is_type_arithmetic(true_type) && is_type_arithmetic(false_type)) { + type_t *result = get_type_after_conversion(true_type, false_type); + /* TODO: create implicit convs if necessary */ + conditional->expression.datatype = result; + } else if(true_type->type == TYPE_POINTER && + false_type->type == TYPE_POINTER && + true /* TODO compatible points_to types */) { + /* TODO */ + } else if(/* (is_null_ptr_const(true_type) && false_type->type == TYPE_POINTER) + || (is_null_ptr_const(false_type) && + true_type->type == TYPE_POINTER) TODO*/ false) { + /* TODO */ + } else if(/* 1 is pointer to object type, other is void* */ false) { + /* TODO */ + } else { + type_error_incompatible("problem while parsing conditional", + expression->source_position, true_type, + false_type); + } + return (expression_t*) conditional; } @@ -1996,8 +2230,9 @@ static expression_t *parse_sub_expression(unsigned precedence) } else { left = parse_primary_expression(); } - if(left != NULL) - left->source_position = source_position; + assert(left != NULL); + assert(left->type != EXPR_INVALID); + left->source_position = source_position; while(true) { if(token.type < 0) { @@ -2011,8 +2246,10 @@ static expression_t *parse_sub_expression(unsigned precedence) break; left = parser->infix_parser(parser->infix_precedence, left); - if(left != NULL) - left->source_position = source_position; + + assert(left != NULL); + assert(left->type != EXPR_INVALID); + left->source_position = source_position; } return left; @@ -2250,7 +2487,7 @@ static statement_t *parse_for(void) set_context(&statement->context); if(token.type != ';') { - if(is_declaration_specifier(&token, 0)) { + if(is_declaration_specifier(&token, false)) { parse_declaration(); } else { statement->initialisation = parse_expression(); @@ -2549,6 +2786,12 @@ void init_parser(void) { init_expression_parsers(); obstack_init(&temp_obst); + + type_int = make_atomic_type(ATOMIC_TYPE_INT, 0); + type_size_t = make_atomic_type(ATOMIC_TYPE_UINT, 0); + type_const_char = make_atomic_type(ATOMIC_TYPE_CHAR, TYPE_QUALIFIER_CONST); + type_void = make_atomic_type(ATOMIC_TYPE_VOID, 0); + type_string = make_pointer_type(type_const_char, 0); } void exit_parser(void)