X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=parser.c;h=db9482623d232ae1cf900bd65577b78bf1d7ecff;hb=9de06381987e3b71a9efea26cb9b596fd433191c;hp=e1db29c5a8793a4a8aac761d6544e3af2daf68ce;hpb=59b11d82a27344b8c4b0df847453686945850943;p=cparser diff --git a/parser.c b/parser.c index e1db29c..db94826 100644 --- a/parser.c +++ b/parser.c @@ -115,6 +115,7 @@ static void *allocate_ast_zero(size_t size) static size_t get_expression_struct_size(expression_type_t type) { static const size_t sizes[] = { + [EXPR_INVALID] = sizeof(expression_base_t), [EXPR_REFERENCE] = sizeof(reference_expression_t), [EXPR_CONST] = sizeof(const_expression_t), [EXPR_STRING_LITERAL] = sizeof(string_literal_expression_t), @@ -136,10 +137,18 @@ static size_t get_expression_struct_size(expression_type_t type) assert(sizeof(sizes) / sizeof(sizes[0]) == EXPR_STATEMENT + 1); assert(type <= EXPR_STATEMENT); assert(sizes[type] != 0); - (void) get_expression_struct_size; return sizes[type]; } +static expression_t *allocate_expression_zero(expression_type_t type) +{ + size_t size = get_expression_struct_size(type); + expression_t *res = allocate_ast_zero(size); + + res->base.type = type; + return res; +} + static size_t get_type_struct_size(type_type_t type) { static const size_t sizes[] = { @@ -443,6 +452,17 @@ static void set_context(context_t *new_context) static bool is_compatible_declaration (declaration_t *declaration, declaration_t *previous) { + if (declaration->type->type == TYPE_FUNCTION && + previous->type->type == TYPE_FUNCTION && + previous->type->function.unspecified_parameters) { + function_type_t* const prev_func = &previous->type->function; + function_type_t* const decl_func = &declaration->type->function; + if (prev_func->unspecified_parameters && + prev_func->result_type == decl_func->result_type) { + declaration->type = previous->type; + return true; + } + } /* TODO: not correct yet */ return declaration->type == previous->type; } @@ -689,14 +709,13 @@ static type_t *promote_integer(type_t *type) static expression_t *create_cast_expression(expression_t *expression, type_t *dest_type) { - unary_expression_t *cast = allocate_ast_zero(sizeof(cast[0])); + expression_t *cast = allocate_expression_zero(EXPR_UNARY); - cast->expression.type = EXPR_UNARY; - cast->type = UNEXPR_CAST; - cast->value = expression; - cast->expression.datatype = dest_type; + cast->unary.type = UNEXPR_CAST; + cast->unary.value = expression; + cast->base.datatype = dest_type; - return (expression_t*) cast; + return cast; } static bool is_null_expression(const expression_t *const expression) @@ -1017,8 +1036,7 @@ static initializer_t *initializer_from_expression(type_t *type, || atype == ATOMIC_TYPE_SCHAR || atype == ATOMIC_TYPE_UCHAR) { - string_literal_expression_t *literal - = &expression->string_literal; + string_literal_expression_t *literal = &expression->string; return initializer_from_string(array_type, literal->value); } } @@ -1538,6 +1556,27 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) MATCH_STORAGE_CLASS(T_auto, STORAGE_CLASS_AUTO) MATCH_STORAGE_CLASS(T_register, STORAGE_CLASS_REGISTER) + case T___thread: + switch (specifiers->storage_class) { + case STORAGE_CLASS_NONE: + specifiers->storage_class = STORAGE_CLASS_THREAD; + break; + + case STORAGE_CLASS_EXTERN: + specifiers->storage_class = STORAGE_CLASS_THREAD_EXTERN; + break; + + case STORAGE_CLASS_STATIC: + specifiers->storage_class = STORAGE_CLASS_THREAD_STATIC; + break; + + default: + parse_error("multiple storage classes in declaration specifiers"); + break; + } + next_token(); + break; + /* type qualifiers */ #define MATCH_TYPE_QUALIFIER(token, qualifier) \ case token: \ @@ -1798,7 +1837,11 @@ static void parse_identifier_list(void) T_IDENTIFIER, 0); return; } + declaration_t *declaration = allocate_ast_zero(sizeof(declaration[0])); + declaration->symbol = token.v.symbol; + next_token(); + if(token.type != ',') break; next_token(); @@ -2253,22 +2296,20 @@ static void parse_init_declarators(const declaration_specifiers_t *specifiers) array_type_t *array_type = &type->array; if(array_type->size == NULL) { - const_expression_t - *cnst = allocate_ast_zero(sizeof(cnst[0])); + expression_t *cnst = allocate_expression_zero(EXPR_CONST); - cnst->expression.type = EXPR_CONST; - cnst->expression.datatype = type_size_t; + cnst->base.datatype = type_size_t; if(initializer->type == INITIALIZER_LIST) { initializer_list_t *list = &initializer->list; - cnst->v.int_value = list->len; + cnst->conste.v.int_value = list->len; } else { assert(initializer->type == INITIALIZER_STRING); initializer_string_t *string = &initializer->string; - cnst->v.int_value = strlen(string->string) + 1; + cnst->conste.v.int_value = strlen(string->string) + 1; } - array_type->size = (expression_t*) cnst; + array_type->size = cnst; } } @@ -2283,6 +2324,19 @@ static void parse_init_declarators(const declaration_specifiers_t *specifiers) eat_block(); continue; } + function_type_t *function_type = &type->function; + /* § 6.7.5.3 (14) a function definition with () means no + * parameters */ + if(function_type->unspecified_parameters) { + type_t *duplicate = duplicate_type(type); + duplicate->function.unspecified_parameters = false; + + type = typehash_insert(duplicate); + if(type != duplicate) { + //obstack_free(type_obst, duplicate); + } + function_type = &type->function; + } if(declaration->init.statement != NULL) { parser_error_multiple_definition(declaration, ndeclaration); @@ -2454,8 +2508,7 @@ expression_parser_function_t expression_parsers[T_LAST_TOKEN]; static expression_t *make_invalid_expression(void) { - expression_t *expression = allocate_ast_zero(sizeof(expression[0])); - expression->type = EXPR_INVALID; + expression_t *expression = allocate_expression_zero(EXPR_INVALID); expression->base.source_position = token.source_position; return expression; } @@ -2474,39 +2527,33 @@ static expression_t *expected_expression_error(void) static expression_t *parse_string_const(void) { - string_literal_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0])); - - cnst->expression.type = EXPR_STRING_LITERAL; - cnst->expression.datatype = type_string; - cnst->value = parse_string_literals(); + expression_t *cnst = allocate_expression_zero(EXPR_STRING_LITERAL); + cnst->base.datatype = type_string; + cnst->string.value = parse_string_literals(); - return (expression_t*) cnst; + return cnst; } static expression_t *parse_int_const(void) { - const_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0])); - - cnst->expression.type = EXPR_CONST; - cnst->expression.datatype = token.datatype; - cnst->v.int_value = token.v.intvalue; + expression_t *cnst = allocate_expression_zero(EXPR_CONST); + cnst->base.datatype = token.datatype; + cnst->conste.v.int_value = token.v.intvalue; next_token(); - return (expression_t*) cnst; + return cnst; } static expression_t *parse_float_const(void) { - const_expression_t *cnst = allocate_ast_zero(sizeof(cnst[0])); - - cnst->expression.type = EXPR_CONST; - cnst->expression.datatype = token.datatype; - cnst->v.float_value = token.v.floatvalue; + expression_t *cnst = allocate_expression_zero(EXPR_CONST); + cnst->base.datatype = token.datatype; + cnst->conste.v.float_value = token.v.floatvalue; next_token(); - return (expression_t*) cnst; + return cnst; } static declaration_t *create_implicit_function(symbol_t *symbol, @@ -2608,18 +2655,15 @@ type_t *revert_automatic_type_conversion(const expression_t *expression) switch(expression->type) { case EXPR_REFERENCE: { - const reference_expression_t *ref - = (const reference_expression_t*) expression; + const reference_expression_t *ref = &expression->reference; return ref->declaration->type; } case EXPR_SELECT: { - const select_expression_t *select - = (const select_expression_t*) expression; + const select_expression_t *select = &expression->select; return select->compound_entry->type; } case EXPR_UNARY: { - const unary_expression_t *unary - = (const unary_expression_t*) expression; + const unary_expression_t *unary = &expression->unary; if(unary->type == UNEXPR_DEREFERENCE) { expression_t *value = unary->value; type_t *type = skip_typeref(value->base.datatype); @@ -2631,7 +2675,7 @@ type_t *revert_automatic_type_conversion(const expression_t *expression) } case EXPR_BUILTIN_SYMBOL: { const builtin_symbol_expression_t *builtin - = (const builtin_symbol_expression_t*) expression; + = &expression->builtin_symbol; return get_builtin_symbol_type(builtin->symbol); } case EXPR_ARRAY_ACCESS: { @@ -2653,10 +2697,10 @@ type_t *revert_automatic_type_conversion(const expression_t *expression) static expression_t *parse_reference(void) { - reference_expression_t *ref = allocate_ast_zero(sizeof(ref[0])); + expression_t *expression = allocate_expression_zero(EXPR_REFERENCE); - ref->expression.type = EXPR_REFERENCE; - ref->symbol = token.v.symbol; + reference_expression_t *ref = &expression->reference; + ref->symbol = token.v.symbol; declaration_t *declaration = get_declaration(ref->symbol, NAMESPACE_NORMAL); @@ -2678,7 +2722,7 @@ static expression_t *parse_reference(void) { parser_print_error_prefix(); fprintf(stderr, "unknown symbol '%s' found.\n", ref->symbol->string); - return (expression_t*) ref; + return expression; } } @@ -2690,7 +2734,7 @@ static expression_t *parse_reference(void) ref->declaration = declaration; ref->expression.datatype = type; - return (expression_t*) ref; + return expression; } static void check_cast_allowed(expression_t *expression, type_t *dest_type) @@ -2702,11 +2746,10 @@ static void check_cast_allowed(expression_t *expression, type_t *dest_type) static expression_t *parse_cast(void) { - unary_expression_t *cast = allocate_ast_zero(sizeof(cast[0])); + expression_t *cast = allocate_expression_zero(EXPR_UNARY); - cast->expression.type = EXPR_UNARY; - cast->type = UNEXPR_CAST; - cast->expression.source_position = token.source_position; + cast->unary.type = UNEXPR_CAST; + cast->base.source_position = token.source_position; type_t *type = parse_typename(); @@ -2715,28 +2758,25 @@ static expression_t *parse_cast(void) check_cast_allowed(value, type); - cast->expression.datatype = type; - cast->value = value; + cast->base.datatype = type; + cast->unary.value = value; - return (expression_t*) cast; + return cast; } static expression_t *parse_statement_expression(void) { - statement_expression_t *expression - = allocate_ast_zero(sizeof(expression[0])); - expression->expression.type = EXPR_STATEMENT; + expression_t *expression = allocate_expression_zero(EXPR_STATEMENT); - statement_t *statement = parse_compound_statement(); - expression->statement = statement; + statement_t *statement = parse_compound_statement(); + expression->statement.statement = statement; if(statement == NULL) { expect(')'); return NULL; } assert(statement->type == STATEMENT_COMPOUND); - compound_statement_t *compound_statement - = (compound_statement_t*) statement; + compound_statement_t *compound_statement = &statement->compound; /* find last statement and use it's type */ const statement_t *last_statement = NULL; @@ -2746,17 +2786,17 @@ static expression_t *parse_statement_expression(void) } if(last_statement->type == STATEMENT_EXPRESSION) { - const expression_statement_t *expression_statement = - (const expression_statement_t*) last_statement; - expression->expression.datatype + const expression_statement_t *expression_statement + = &last_statement->expression; + expression->base.datatype = expression_statement->expression->base.datatype; } else { - expression->expression.datatype = type_void; + expression->base.datatype = type_void; } expect(')'); - return (expression_t*) expression; + return expression; } static expression_t *parse_brace_expression(void) @@ -2872,50 +2912,47 @@ static expression_t *parse_offsetof(void) { eat(T___builtin_offsetof); - offsetof_expression_t *expression - = allocate_ast_zero(sizeof(expression[0])); - expression->expression.type = EXPR_OFFSETOF; - expression->expression.datatype = type_size_t; + expression_t *expression = allocate_expression_zero(EXPR_OFFSETOF); + expression->base.datatype = type_size_t; expect('('); - expression->type = parse_typename(); + expression->offsetofe.type = parse_typename(); expect(','); - expression->designator = parse_designator(); + expression->offsetofe.designator = parse_designator(); expect(')'); - return (expression_t*) expression; + return expression; } static expression_t *parse_va_arg(void) { eat(T___builtin_va_arg); - va_arg_expression_t *expression = allocate_ast_zero(sizeof(expression[0])); - expression->expression.type = EXPR_VA_ARG; + expression_t *expression = allocate_expression_zero(EXPR_VA_ARG); expect('('); - expression->arg = parse_assignment_expression(); + expression->va_arge.arg = parse_assignment_expression(); expect(','); - expression->expression.datatype = parse_typename(); + expression->base.datatype = parse_typename(); expect(')'); - return (expression_t*) expression; + return expression; } static expression_t *parse_builtin_symbol(void) { - builtin_symbol_expression_t *expression - = allocate_ast_zero(sizeof(expression[0])); - expression->expression.type = EXPR_BUILTIN_SYMBOL; + expression_t *expression = allocate_expression_zero(EXPR_BUILTIN_SYMBOL); + + symbol_t *symbol = token.v.symbol; - expression->symbol = token.v.symbol; + expression->builtin_symbol.symbol = symbol; next_token(); - type_t *type = get_builtin_symbol_type(expression->symbol); + type_t *type = get_builtin_symbol_type(symbol); type = automatic_type_conversion(type); - expression->expression.datatype = type; - return (expression_t*) expression; + expression->base.datatype = type; + return expression; } static expression_t *parse_primary_expression(void) @@ -3067,17 +3104,15 @@ static expression_t *parse_select_expression(unsigned precedence, bool is_pointer = (token.type == T_MINUSGREATER); next_token(); - select_expression_t *select = allocate_ast_zero(sizeof(select[0])); - - select->expression.type = EXPR_SELECT; - select->compound = compound; + expression_t *select = allocate_expression_zero(EXPR_SELECT); + select->select.compound = compound; if(token.type != T_IDENTIFIER) { parse_error_expected("while parsing select", T_IDENTIFIER, 0); - return (expression_t*) select; + return select; } - symbol_t *symbol = token.v.symbol; - select->symbol = symbol; + symbol_t *symbol = token.v.symbol; + select->select.symbol = symbol; next_token(); type_t *orig_type = compound->base.datatype; @@ -3139,18 +3174,19 @@ static expression_t *parse_select_expression(unsigned precedence, * code to revert this! */ type_t *expression_type = automatic_type_conversion(iter->type); - select->compound_entry = iter; - select->expression.datatype = expression_type; - return (expression_t*) select; + select->select.compound_entry = iter; + select->base.datatype = expression_type; + return select; } static expression_t *parse_call_expression(unsigned precedence, expression_t *expression) { (void) precedence; - call_expression_t *call = allocate_ast_zero(sizeof(call[0])); - call->expression.type = EXPR_CALL; - call->function = expression; + expression_t *result = allocate_expression_zero(EXPR_CALL); + + call_expression_t *call = &result->call; + call->function = expression; function_type_t *function_type = NULL; type_t *orig_type = expression->base.datatype; @@ -3250,7 +3286,7 @@ static expression_t *parse_call_expression(unsigned precedence, } } - return (expression_t*) call; + return result; } static type_t *semantic_arithmetic(type_t *type_left, type_t *type_right);