X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=parser.c;h=8977956e83b1cbbbd2bfcb37555677c46a7e5e03;hb=68c5da90234d8956dac083c5f9fd1cae96a7317c;hp=a6eb971ee99538f3eb4e85df32f432db0ef55a61;hpb=712027274baa81ffc562d9334c9b7215b6f53bac;p=cparser diff --git a/parser.c b/parser.c index a6eb971..8977956 100644 --- a/parser.c +++ b/parser.c @@ -132,7 +132,7 @@ static const symbol_t *sym_noalias = NULL; static unsigned char token_anchor_set[T_LAST_TOKEN]; /** The current source position. */ -#define HERE &token.source_position +#define HERE (&token.source_position) static type_t *type_valist; @@ -3321,12 +3321,10 @@ static declaration_t *parse_parameters(function_type_t *type) } if(token.type == ')') { - next_token(); type->unspecified_parameters = 1; goto parameters_finished; } if(token.type == T_void && look_ahead(1)->type == ')') { - next_token(); next_token(); goto parameters_finished; } @@ -3925,6 +3923,9 @@ warn_redundant_declaration: } } } + + if (declaration->is_inline) + previous_declaration->is_inline = true; return previous_declaration; } } else if (is_function_definition) { @@ -3975,18 +3976,18 @@ static void parser_error_multiple_definition(declaration_t *declaration, } static bool is_declaration_specifier(const token_t *token, - bool only_type_specifiers) + bool only_specifiers_qualifiers) { switch(token->type) { TYPE_SPECIFIERS + TYPE_QUALIFIERS return true; case T_IDENTIFIER: return is_typedef_symbol(token->v.symbol); case T___extension__: STORAGE_CLASSES - TYPE_QUALIFIERS - return !only_type_specifiers; + return !only_specifiers_qualifiers; default: return false; @@ -4172,14 +4173,14 @@ static void parse_kr_declaration_list(declaration_t *declaration) set_scope(&declaration->scope); declaration_t *parameter = declaration->scope.declarations; - for( ; parameter != NULL; parameter = parameter->next) { + for ( ; parameter != NULL; parameter = parameter->next) { assert(parameter->parent_scope == NULL); parameter->parent_scope = scope; environment_push(parameter); } /* parse declaration list */ - while(is_declaration_specifier(&token, false)) { + while (is_declaration_specifier(&token, false)) { parse_declaration(finished_kr_declaration); } @@ -4190,7 +4191,6 @@ static void parse_kr_declaration_list(declaration_t *declaration) /* update function type */ type_t *new_type = duplicate_type(type); - new_type->function.kr_style_parameters = false; function_parameter_t *parameters = NULL; function_parameter_t *last_parameter = NULL; @@ -4228,7 +4228,11 @@ static void parse_kr_declaration_list(declaration_t *declaration) } last_parameter = function_parameter; } + + /* § 6.9.1.7: A K&R style parameter list does NOT act as a function + * prototype */ new_type->function.parameters = parameters; + new_type->function.unspecified_parameters = true; type = typehash_insert(new_type); if(type != new_type) { @@ -4368,7 +4372,9 @@ static void parse_external_declaration(void) /* § 6.7.5.3 (14) a function definition with () means no * parameters (and not unspecified parameters) */ - if(type->function.unspecified_parameters) { + if(type->function.unspecified_parameters + && type->function.parameters == NULL + && !type->function.kr_style_parameters) { type_t *duplicate = duplicate_type(type); duplicate->function.unspecified_parameters = false; @@ -4776,18 +4782,11 @@ static declaration_t *create_implicit_function(symbol_t *symbol, declaration->type = type; declaration->symbol = symbol; declaration->source_position = *source_position; - declaration->parent_scope = global_scope; - - scope_t *old_scope = scope; - set_scope(global_scope); - environment_push(declaration); - /* prepends the declaration to the global declarations list */ - declaration->next = scope->declarations; - scope->declarations = declaration; - - assert(scope == global_scope); - set_scope(old_scope); + bool strict_prototypes_old = warning.strict_prototypes; + warning.strict_prototypes = false; + record_declaration(declaration); + warning.strict_prototypes = strict_prototypes_old; return declaration; } @@ -4818,6 +4817,20 @@ static type_t *make_function_1_type(type_t *return_type, type_t *argument_type) return result; } +static type_t *make_function_0_type(type_t *return_type) +{ + type_t *type = allocate_type_zero(TYPE_FUNCTION, &builtin_source_position); + type->function.return_type = return_type; + type->function.parameters = NULL; + + type_t *result = typehash_insert(type); + if(result != type) { + free_type(type); + } + + return result; +} + /** * Creates a function type for some function like builtins. * @@ -4828,6 +4841,8 @@ static type_t *get_builtin_symbol_type(symbol_t *symbol) switch(symbol->ID) { case T___builtin_alloca: 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_nan: return make_function_1_type(type_double, type_char_ptr); case T___builtin_nanf: @@ -5534,6 +5549,7 @@ static expression_t *parse_primary_expression(void) case T___builtin_nan: case T___builtin_nand: case T___builtin_nanf: + case T___builtin_huge_val: case T___builtin_va_end: return parse_builtin_symbol(); case T___builtin_isgreater: case T___builtin_isgreaterequal: @@ -5622,20 +5638,47 @@ static expression_t *parse_array_expression(unsigned precedence, return expression; } -static expression_t *parse_typeprop(expression_kind_t kind, unsigned precedence) +static expression_t *parse_typeprop(expression_kind_t const kind, + source_position_t const pos, + unsigned const precedence) { expression_t *tp_expression = allocate_expression_zero(kind); - tp_expression->base.type = type_size_t; + tp_expression->base.type = type_size_t; + tp_expression->base.source_position = pos; - if(token.type == '(' && is_declaration_specifier(look_ahead(1), true)) { + char const* const what = kind == EXPR_SIZEOF ? "sizeof" : "alignof"; + + if (token.type == '(' && is_declaration_specifier(look_ahead(1), true)) { next_token(); add_anchor_token(')'); - tp_expression->typeprop.type = parse_typename(); + type_t* const type = parse_typename(); + tp_expression->typeprop.type = type; + + char const* const wrong_type = + is_type_incomplete(type) ? "incomplete" : + type->kind == TYPE_FUNCTION ? "function designator" : + type->kind == TYPE_BITFIELD ? "bitfield" : + NULL; + if (wrong_type != NULL) { + errorf(&pos, "operand of %s expression must not be %s type '%T'", what, wrong_type, type); + } + rem_anchor_token(')'); expect(')'); } else { expression_t *expression = parse_sub_expression(precedence); - expression->base.type = revert_automatic_type_conversion(expression); + + type_t* const type = revert_automatic_type_conversion(expression); + expression->base.type = type; + + char const* const wrong_type = + is_type_incomplete(type) ? "incomplete" : + type->kind == TYPE_FUNCTION ? "function designator" : + type->kind == TYPE_BITFIELD ? "bitfield" : + NULL; + if (wrong_type != NULL) { + errorf(&pos, "operand of %s expression must not be expression of %s type '%T'", what, wrong_type, type); + } tp_expression->typeprop.type = expression->base.type; tp_expression->typeprop.tp_expression = expression; @@ -5648,14 +5691,16 @@ end_error: static expression_t *parse_sizeof(unsigned precedence) { + source_position_t pos = *HERE; eat(T_sizeof); - return parse_typeprop(EXPR_SIZEOF, precedence); + return parse_typeprop(EXPR_SIZEOF, pos, precedence); } static expression_t *parse_alignof(unsigned precedence) { + source_position_t pos = *HERE; eat(T___alignof__); - return parse_typeprop(EXPR_SIZEOF, precedence); + return parse_typeprop(EXPR_ALIGNOF, pos, precedence); } static expression_t *parse_select_expression(unsigned precedence, @@ -6346,9 +6391,9 @@ static void semantic_comparison(binary_expression_t *expression) other_expr = left; } - type_t *other_type = skip_typeref(other_expr->base.type); if(const_expr != NULL) { - long val = fold_constant(const_expr); + type_t *other_type = skip_typeref(other_expr->base.type); + long val = fold_constant(const_expr); /* TODO: check if val can be represented by other_type */ (void) other_type; (void) val;