X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=71f125b30db70a44c1e5328e539c369fb99c0886;hb=a3b59620bf02c87d9951a0f1e8b9cf7e87e6c321;hp=de7668c4cc5b61d882cc03980a9914e3764cca26;hpb=f3fe51846775845f20d8fc1ae5f60f4556599582;p=cparser diff --git a/parser.c b/parser.c index de7668c..71f125b 100644 --- a/parser.c +++ b/parser.c @@ -1091,8 +1091,8 @@ static initializer_t *initializer_from_expression(type_t *type, /* § 6.7.8.14/15 char array may be initialized by string literals */ type_t *const expr_type = expression->base.datatype; if (is_type_array(type) && expr_type->kind == TYPE_POINTER) { - array_type_t *const array_type = &type->array; - type_t *const element_type = skip_typeref(array_type->element_type); + array_type_t *const array_type = &type->array; + type_t *const element_type = skip_typeref(array_type->element_type); if (element_type->kind == TYPE_ATOMIC) { switch (expression->kind) { @@ -1110,7 +1110,8 @@ static initializer_t *initializer_from_expression(type_t *type, } } - default: break; + default: + break; } } } @@ -1146,6 +1147,24 @@ static initializer_t *parse_sub_initializer_elem(type_t *type) static bool had_initializer_brace_warning; +static void skip_designator(void) +{ + while(1) { + if(token.type == '.') { + next_token(); + if(token.type == T_IDENTIFIER) + next_token(); + } else if(token.type == '[') { + next_token(); + parse_constant_expression(); + if(token.type == ']') + next_token(); + } else { + break; + } + } +} + static initializer_t *parse_sub_initializer(type_t *type, expression_t *expression, type_t *expression_type) @@ -1194,6 +1213,13 @@ static initializer_t *parse_sub_initializer(type_t *type, type_t *element_type = array_type->element_type; element_type = skip_typeref(element_type); + if(token.type == '.') { + errorf(HERE, + "compound designator in initializer for array type '%T'", + type); + skip_designator(); + } + initializer_t *sub; had_initializer_brace_warning = false; if(expression == NULL) { @@ -1233,6 +1259,13 @@ static initializer_t *parse_sub_initializer(type_t *type, compound_type_t *compound_type = &type->compound; context_t *context = &compound_type->declaration->context; + if(token.type == '[') { + errorf(HERE, + "array designator in initializer for compound type '%T'", + type); + skip_designator(); + } + declaration_t *first = context->declarations; if(first == NULL) return NULL; @@ -3022,7 +3055,13 @@ type_t *revert_automatic_type_conversion(const expression_t *expression) } case EXPR_SELECT: { const select_expression_t *select = &expression->select; - return select->compound_entry->type; + type_t *orig_type = select->compound_entry->type; + type_t *type = skip_typeref(orig_type); + if(type->kind == TYPE_BITFIELD) { + return type->bitfield.base; + } else { + return orig_type; + } } case EXPR_UNARY_DEREFERENCE: { expression_t *value = expression->unary.value; @@ -3079,7 +3118,12 @@ static expression_t *parse_reference(void) } } - type_t *type = declaration->type; + type_t *type = declaration->type; + type_t *skipped_type = skip_typeref(type); + if(skipped_type->kind == TYPE_BITFIELD) { + type = skipped_type->bitfield.base; + } + /* we always do the auto-type conversions; the & and sizeof parser contains * code to revert this! */ type = automatic_type_conversion(type); @@ -3662,16 +3706,20 @@ static expression_t *parse_select_expression(unsigned precedence, } } if(iter == NULL) { - errorf(HERE, "'%T' has no member names '%Y'", type_left, symbol); + errorf(HERE, "'%T' has no member named '%Y'", orig_type, symbol); return create_invalid_expression(); } /* we always do the auto-type conversions; the & and sizeof parser contains * code to revert this! */ type_t *expression_type = automatic_type_conversion(iter->type); + if(expression_type->kind == TYPE_BITFIELD) { + expression_type = expression_type->bitfield.base; + } select->select.compound_entry = iter; select->base.datatype = expression_type; + return select; } @@ -3686,8 +3734,8 @@ static expression_t *parse_call_expression(unsigned precedence, (void) precedence; expression_t *result = allocate_expression_zero(EXPR_CALL); - call_expression_t *call = &result->call; - call->function = expression; + call_expression_t *call = &result->call; + call->function = expression; function_type_t *function_type = NULL; type_t *orig_type = expression->base.datatype; @@ -4331,6 +4379,9 @@ static bool has_const_fields(const compound_type_t *type) const declaration_t *declaration = context->declarations; for (; declaration != NULL; declaration = declaration->next) { + if (declaration->namespc != NAMESPACE_NORMAL) + continue; + const type_t *decl_type = skip_typeref(declaration->type); if (decl_type->base.qualifiers & TYPE_QUALIFIER_CONST) return true; @@ -5286,7 +5337,13 @@ static translation_unit_t *parse_translation_unit(void) initialize_builtin_types(); while(token.type != T_EOF) { - parse_external_declaration(); + if (token.type == ';') { + /* TODO error in strict mode */ + warningf(HERE, "stray ';' outside of function"); + next_token(); + } else { + parse_external_declaration(); + } } assert(context == &unit->context);