X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=32a2a9df7f965ffd74ca1c30b4aeb66e538223aa;hb=b5e161a375492f2af666767725c86d9dfab4f5f8;hp=844ced38873a515359c76ce737f99d737e729d3d;hpb=578e95b73d0ea28c38bbbef48f49fb00748f522e;p=cparser diff --git a/parser.c b/parser.c index 844ced3..32a2a9d 100644 --- a/parser.c +++ b/parser.c @@ -53,7 +53,8 @@ struct declaration_specifiers_t { source_position_t source_position; unsigned char declared_storage_class; unsigned char alignment; /**< Alignment, 0 if not set. */ - bool is_inline; + unsigned int is_inline : 1; + unsigned int deprecated : 1; decl_modifiers_t decl_modifiers; /**< MS __declspec extended modifier mask */ const char *deprecated_string; /**< can be set if declaration was marked deprecated. */ symbol_t *get_property_sym; /**< the name of the get property if set. */ @@ -145,7 +146,7 @@ static void semantic_comparison(binary_expression_t *expression); case T_restrict: \ case T_volatile: \ case T_inline: \ - case T_forceinline: + case T__forceinline: #ifdef PROVIDE_COMPLEX #define COMPLEX_SPECIFIERS \ @@ -173,7 +174,7 @@ static void semantic_comparison(binary_expression_t *expression); case T_enum: \ case T___typeof__: \ case T___builtin_va_list: \ - case T_declspec: \ + case T__declspec: \ COMPLEX_SPECIFIERS \ IMAGINARY_SPECIFIERS @@ -296,6 +297,8 @@ static size_t get_expression_struct_size(expression_kind_t kind) [EXPR_CLASSIFY_TYPE] = sizeof(classify_type_expression_t), [EXPR_FUNCTION] = sizeof(string_literal_expression_t), [EXPR_PRETTY_FUNCTION] = sizeof(string_literal_expression_t), + [EXPR_FUNCSIG] = sizeof(string_literal_expression_t), + [EXPR_FUNCDNAME] = sizeof(string_literal_expression_t), [EXPR_BUILTIN_SYMBOL] = sizeof(builtin_symbol_expression_t), [EXPR_BUILTIN_CONSTANT_P] = sizeof(builtin_constant_expression_t), [EXPR_BUILTIN_PREFETCH] = sizeof(builtin_prefetch_expression_t), @@ -939,32 +942,42 @@ static string_t parse_string_literals(void) return result; } +/** + * Parse one GNU attribute. + */ +static void parse_gnu_attribute(void) +{ + eat(T___attribute__); + expect('('); + expect('('); + while(true) { + if(token.type != T_IDENTIFIER) + break; + symbol_t *sym = token.v.symbol; + if(sym == sym_deprecated) { + } + next_token(); + if(token.type == '(') + eat_until_matching_token('('); + if(token.type != ',') + break; + next_token(); + } + expect(')'); + expect(')'); +end_error: + return; +} + +/** + * Parse GNU attributes. + */ static void parse_attributes(void) { while(true) { switch(token.type) { case T___attribute__: { - next_token(); - - expect('('); - int depth = 1; - while(depth > 0) { - switch(token.type) { - case T_EOF: - errorf(HERE, "EOF while parsing attribute"); - break; - case '(': - next_token(); - depth++; - break; - case ')': - next_token(); - depth--; - break; - default: - next_token(); - } - } + parse_gnu_attribute(); break; } case T_asm: @@ -1216,7 +1229,7 @@ static __attribute__((unused)) void debug_print_type_path( } fprintf(stderr, ".%s", entry->v.compound_entry->symbol->string); } else if(is_type_array(type)) { - fprintf(stderr, "[%u]", entry->v.index); + fprintf(stderr, "[%zd]", entry->v.index); } else { fprintf(stderr, "-INVALID-"); } @@ -1996,9 +2009,14 @@ typedef enum { SPECIFIER_FLOAT = 1 << 8, SPECIFIER_BOOL = 1 << 9, SPECIFIER_VOID = 1 << 10, + SPECIFIER_INT8 = 1 << 11, + SPECIFIER_INT16 = 1 << 12, + SPECIFIER_INT32 = 1 << 13, + SPECIFIER_INT64 = 1 << 14, + SPECIFIER_INT128 = 1 << 15, #ifdef PROVIDE_COMPLEX - SPECIFIER_COMPLEX = 1 << 11, - SPECIFIER_IMAGINARY = 1 << 12, + SPECIFIER_COMPLEX = 1 << 16, + SPECIFIER_IMAGINARY = 1 << 17, #endif } specifiers_t; @@ -2158,8 +2176,10 @@ static void parse_microsoft_extended_decl_modifier(declaration_specifiers_t *spe expect(')'); } else if(symbol == sym_deprecated) { next_token(); - DET_MOD(deprecated, DM_DEPRECATED); - if(token.type == '(') { + if(specifiers->deprecated != 0) + warningf(HERE, "deprecated used more than once"); + specifiers->deprecated = 1; + if(token.type == '(') { next_token(); if(token.type == T_STRING_LITERAL) { specifiers->deprecated_string = token.v.string.begin; @@ -2214,7 +2234,7 @@ 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_declspec: + case T__declspec: next_token(); expect('('); add_anchor_token(')'); @@ -2254,6 +2274,11 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) MATCH_TYPE_QUALIFIER(T_const, TYPE_QUALIFIER_CONST); MATCH_TYPE_QUALIFIER(T_restrict, TYPE_QUALIFIER_RESTRICT); MATCH_TYPE_QUALIFIER(T_volatile, TYPE_QUALIFIER_VOLATILE); + MATCH_TYPE_QUALIFIER(T__w64, TYPE_QUALIFIER_W64); + MATCH_TYPE_QUALIFIER(T___ptr32, TYPE_QUALIFIER_PTR32); + MATCH_TYPE_QUALIFIER(T___ptr64, TYPE_QUALIFIER_PTR64); + MATCH_TYPE_QUALIFIER(T___uptr, TYPE_QUALIFIER_UPTR); + MATCH_TYPE_QUALIFIER(T___sptr, TYPE_QUALIFIER_SPTR); case T___extension__: /* TODO */ @@ -2280,11 +2305,16 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers) MATCH_SPECIFIER(T_signed, SPECIFIER_SIGNED, "signed") MATCH_SPECIFIER(T_unsigned, SPECIFIER_UNSIGNED, "unsigned") MATCH_SPECIFIER(T__Bool, SPECIFIER_BOOL, "_Bool") + MATCH_SPECIFIER(T__int8, SPECIFIER_INT8, "_int8") + MATCH_SPECIFIER(T__int16, SPECIFIER_INT16, "_int16") + MATCH_SPECIFIER(T__int32, SPECIFIER_INT32, "_int32") + MATCH_SPECIFIER(T__int64, SPECIFIER_INT64, "_int64") + MATCH_SPECIFIER(T__int128, SPECIFIER_INT128, "_int128") #ifdef PROVIDE_COMPLEX MATCH_SPECIFIER(T__Complex, SPECIFIER_COMPLEX, "_Complex") MATCH_SPECIFIER(T__Imaginary, SPECIFIER_IMAGINARY, "_Imaginary") #endif - case T_forceinline: + case T__forceinline: /* only in microsoft mode */ specifiers->decl_modifiers |= DM_FORCEINLINE; @@ -2412,6 +2442,52 @@ finish_specifiers: | SPECIFIER_INT: atomic_type = ATOMIC_TYPE_ULONGLONG; break; + + case SPECIFIER_UNSIGNED | SPECIFIER_INT8: + atomic_type = unsigned_int8_type_kind; + break; + + case SPECIFIER_UNSIGNED | SPECIFIER_INT16: + atomic_type = unsigned_int16_type_kind; + break; + + case SPECIFIER_UNSIGNED | SPECIFIER_INT32: + atomic_type = unsigned_int32_type_kind; + break; + + case SPECIFIER_UNSIGNED | SPECIFIER_INT64: + atomic_type = unsigned_int64_type_kind; + break; + + case SPECIFIER_UNSIGNED | SPECIFIER_INT128: + atomic_type = unsigned_int128_type_kind; + break; + + case SPECIFIER_INT8: + case SPECIFIER_SIGNED | SPECIFIER_INT8: + atomic_type = int8_type_kind; + break; + + case SPECIFIER_INT16: + case SPECIFIER_SIGNED | SPECIFIER_INT16: + atomic_type = int16_type_kind; + break; + + case SPECIFIER_INT32: + case SPECIFIER_SIGNED | SPECIFIER_INT32: + atomic_type = int32_type_kind; + break; + + case SPECIFIER_INT64: + case SPECIFIER_SIGNED | SPECIFIER_INT64: + atomic_type = int64_type_kind; + break; + + case SPECIFIER_INT128: + case SPECIFIER_SIGNED | SPECIFIER_INT128: + atomic_type = int128_type_kind; + break; + case SPECIFIER_FLOAT: atomic_type = ATOMIC_TYPE_FLOAT; break; @@ -2477,6 +2553,7 @@ finish_specifiers: } type->base.qualifiers = type_qualifiers; + /* FIXME: check type qualifiers here */ type_t *result = typehash_insert(type); if(newtype && result != type) { @@ -2498,6 +2575,12 @@ static type_qualifiers_t parse_type_qualifiers(void) MATCH_TYPE_QUALIFIER(T_const, TYPE_QUALIFIER_CONST); MATCH_TYPE_QUALIFIER(T_restrict, TYPE_QUALIFIER_RESTRICT); MATCH_TYPE_QUALIFIER(T_volatile, TYPE_QUALIFIER_VOLATILE); + /* microsoft extended type modifiers */ + MATCH_TYPE_QUALIFIER(T__w64, TYPE_QUALIFIER_W64); + MATCH_TYPE_QUALIFIER(T___ptr32, TYPE_QUALIFIER_PTR32); + MATCH_TYPE_QUALIFIER(T___ptr64, TYPE_QUALIFIER_PTR64); + MATCH_TYPE_QUALIFIER(T___uptr, TYPE_QUALIFIER_UPTR); + MATCH_TYPE_QUALIFIER(T___sptr, TYPE_QUALIFIER_SPTR); default: return type_qualifiers; @@ -2954,6 +3037,7 @@ static declaration_t *parse_declarator( declaration_t *const declaration = allocate_declaration_zero(); declaration->declared_storage_class = specifiers->declared_storage_class; declaration->modifiers = specifiers->decl_modifiers; + declaration->deprecated = specifiers->deprecated; declaration->deprecated_string = specifiers->deprecated_string; declaration->get_property_sym = specifiers->get_property_sym; declaration->put_property_sym = specifiers->put_property_sym; @@ -4219,7 +4303,7 @@ static expression_t *parse_reference(void) declaration->used = true; /* check for deprecated functions */ - if(declaration->modifiers & DM_DEPRECATED) { + if(declaration->deprecated != 0) { const char *prefix = ""; if (is_type_function(declaration->type)) prefix = "function "; @@ -4376,7 +4460,6 @@ static expression_t *parse_function_keyword(void) static expression_t *parse_pretty_function_keyword(void) { eat(T___PRETTY_FUNCTION__); - /* TODO */ if (current_function == NULL) { errorf(HERE, "'__PRETTY_FUNCTION__' used outside of a function"); @@ -4388,6 +4471,34 @@ static expression_t *parse_pretty_function_keyword(void) return expression; } +static expression_t *parse_funcsig_keyword(void) +{ + next_token(); + + if (current_function == NULL) { + errorf(HERE, "'__FUNCSIG__' used outside of a function"); + } + + expression_t *expression = allocate_expression_zero(EXPR_FUNCSIG); + expression->base.type = type_char_ptr; + + return expression; +} + +static expression_t *parse_funcdname_keyword(void) +{ + next_token(); + + if (current_function == NULL) { + errorf(HERE, "'__FUNCDNAME__' used outside of a function"); + } + + expression_t *expression = allocate_expression_zero(EXPR_FUNCDNAME); + expression->base.type = type_char_ptr; + + return expression; +} + static designator_t *parse_designator(void) { designator_t *result = allocate_ast_zero(sizeof(result[0])); @@ -4686,7 +4797,7 @@ end_error: * Parses a MS assume() expression. */ static expression_t *parse_assume(void) { - eat(T_assume); + eat(T__assume); expression_t *expression = allocate_expression_zero(EXPR_UNARY_ASSUME); @@ -4719,6 +4830,8 @@ static expression_t *parse_primary_expression(void) case T___FUNCTION__: case T___func__: return parse_function_keyword(); case T___PRETTY_FUNCTION__: return parse_pretty_function_keyword(); + case T___FUNCSIG__: return parse_funcsig_keyword(); + case T___FUNCDNAME__: return parse_funcdname_keyword(); case T___builtin_offsetof: return parse_offsetof(); case T___builtin_va_start: return parse_va_start(); case T___builtin_va_arg: return parse_va_arg(); @@ -4736,7 +4849,7 @@ static expression_t *parse_primary_expression(void) case T___builtin_isunordered: return parse_compare_builtin(); case T___builtin_constant_p: return parse_builtin_constant(); case T___builtin_prefetch: return parse_builtin_prefetch(); - case T_assume: return parse_assume(); + case T__assume: return parse_assume(); case '(': return parse_brace_expression(); } @@ -5713,6 +5826,8 @@ static bool expression_has_effect(const expression_t *const expr) case EXPR_FUNCTION: return false; case EXPR_PRETTY_FUNCTION: return false; + case EXPR_FUNCSIG: return false; + case EXPR_FUNCDNAME: return false; case EXPR_BUILTIN_SYMBOL: break; /* handled in EXPR_CALL */ case EXPR_BUILTIN_CONSTANT_P: return false; case EXPR_BUILTIN_PREFETCH: return true;