X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=dc0941f2ce7eed6aa6bd1f9e74f8dcb8755aaaa1;hb=d02d3f8e7d902c83e65d1afab30bcb2cc7384c92;hp=b425c62a48284971af43894a5e6060461aa42855;hpb=0a880c90fd6d1ec23c4ec1956f3b92694ec0a139;p=cparser diff --git a/ast2firm.c b/ast2firm.c index b425c62..dc0941f 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -1101,16 +1101,14 @@ static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode) * @param id_prefix a prefix for the name of the generated string constant * @param value the value of the string constant */ -static ir_node *string_to_firm(source_position_t const *const src_pos, char const *const id_prefix, string_encoding_t const enc, string_t const *const value) +static ir_node *string_to_firm(source_position_t const *const src_pos, char const *const id_prefix, string_t const *const value) { - size_t slen; - ir_type *elem_type; - ir_initializer_t *initializer; - switch (enc) { + size_t const slen = get_string_len(value) + 1; + ir_initializer_t *const initializer = create_initializer_compound(slen); + ir_type * elem_type; + switch (value->encoding) { case STRING_ENCODING_CHAR: { - slen = value->size + 1; - elem_type = ir_type_char; - initializer = create_initializer_compound(slen); + elem_type = ir_type_char; ir_mode *const mode = get_type_mode(elem_type); char const *p = value->begin; @@ -1123,9 +1121,7 @@ static ir_node *string_to_firm(source_position_t const *const src_pos, char cons } case STRING_ENCODING_WIDE: { - slen = wstrlen(value) + 1; - elem_type = ir_type_wchar_t; - initializer = create_initializer_compound(slen); + elem_type = ir_type_wchar_t; ir_mode *const mode = get_type_mode(elem_type); char const *p = value->begin; @@ -1161,14 +1157,12 @@ finish:; static bool try_create_integer(literal_expression_t *literal, type_t *type) { - const char *string = literal->value.begin; - size_t size = literal->value.size; - assert(type->kind == TYPE_ATOMIC); atomic_type_kind_t akind = type->atomic.akind; - ir_mode *const mode = atomic_modes[akind]; - ir_tarval *const tv = new_tarval_from_str(string, size, mode); + ir_mode *const mode = atomic_modes[akind]; + char const *const str = literal->value.begin; + ir_tarval *const tv = new_tarval_from_str(str, literal->suffix - str, mode); if (tv == tarval_bad) return false; @@ -1177,36 +1171,29 @@ static bool try_create_integer(literal_expression_t *literal, type_t *type) return true; } -static void create_integer_tarval(literal_expression_t *literal) +void determine_literal_type(literal_expression_t *const literal) { + assert(literal->base.kind == EXPR_LITERAL_INTEGER); + /* -1: signed only, 0: any, 1: unsigned only */ - int sign = literal->value.begin[0] != '0' /* decimal */ ? -1 : 0; - unsigned ls = 0; - const string_t *suffix = &literal->suffix; - /* parse suffix */ - if (suffix->size > 0) { - for (const char *c = suffix->begin; *c != '\0'; ++c) { - if (*c == 'u' || *c == 'U') sign = 1; - if (*c == 'l' || *c == 'L') { ++ls; } - } - } + int const sign = + !is_type_signed(literal->base.type) ? 1 : + literal->value.begin[0] == '0' ? 0 : + -1; /* Decimal literals only try signed types. */ tarval_int_overflow_mode_t old_mode = tarval_get_integer_overflow_mode(); + tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD); + + if (try_create_integer(literal, literal->base.type)) + goto finished; /* now try if the constant is small enough for some types */ - tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD); - if (ls < 1) { - if (sign <= 0 && try_create_integer(literal, type_int)) - goto finished; - if (sign >= 0 && try_create_integer(literal, type_unsigned_int)) - goto finished; - } - if (ls < 2) { - if (sign <= 0 && try_create_integer(literal, type_long)) - goto finished; - if (sign >= 0 && try_create_integer(literal, type_unsigned_long)) - goto finished; - } + if (sign >= 0 && try_create_integer(literal, type_unsigned_int)) + goto finished; + if (sign <= 0 && try_create_integer(literal, type_long)) + goto finished; + if (sign >= 0 && try_create_integer(literal, type_unsigned_long)) + goto finished; /* last try? then we should not report tarval_bad */ if (sign < 0) tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP); @@ -1224,17 +1211,6 @@ finished: tarval_set_integer_overflow_mode(old_mode); } -void determine_literal_type(literal_expression_t *literal) -{ - switch (literal->base.kind) { - case EXPR_LITERAL_INTEGER: - create_integer_tarval(literal); - return; - default: - break; - } -} - /** * Creates a Const node representing a constant. */ @@ -1287,7 +1263,7 @@ static ir_node *char_literal_to_firm(string_literal_expression_t const *literal) size_t size = literal->value.size; ir_tarval *tv; - switch (literal->encoding) { + switch (literal->value.encoding) { case STRING_ENCODING_WIDE: { utf32 v = read_utf8_char(&string); char buf[128]; @@ -3144,19 +3120,19 @@ static ir_node *function_name_to_firm( case FUNCNAME_PRETTY_FUNCTION: case FUNCNAME_FUNCDNAME: if (current_function_name == NULL) { - const source_position_t *const src_pos = &expr->base.source_position; - const char *name = current_function_entity->base.symbol->string; - const string_t string = { name, strlen(name) }; - current_function_name = string_to_firm(src_pos, "__func__.%u", STRING_ENCODING_CHAR, &string); + source_position_t const *const src_pos = &expr->base.source_position; + char const *const name = current_function_entity->base.symbol->string; + string_t const string = { name, strlen(name), STRING_ENCODING_CHAR }; + current_function_name = string_to_firm(src_pos, "__func__.%u", &string); } return current_function_name; case FUNCNAME_FUNCSIG: if (current_funcsig == NULL) { - const source_position_t *const src_pos = &expr->base.source_position; - ir_entity *ent = get_irg_entity(current_ir_graph); - const char *const name = get_entity_ld_name(ent); - const string_t string = { name, strlen(name) }; - current_funcsig = string_to_firm(src_pos, "__FUNCSIG__.%u", STRING_ENCODING_CHAR, &string); + source_position_t const *const src_pos = &expr->base.source_position; + ir_entity *const ent = get_irg_entity(current_ir_graph); + char const *const name = get_entity_ld_name(ent); + string_t const string = { name, strlen(name), STRING_ENCODING_CHAR }; + current_funcsig = string_to_firm(src_pos, "__FUNCSIG__.%u", &string); } return current_funcsig; } @@ -3347,7 +3323,7 @@ static ir_node *_expression_to_firm(expression_t const *const expr) case EXPR_VA_COPY: return va_copy_expression_to_firm( &expr->va_copye); case EXPR_VA_START: return va_start_expression_to_firm( &expr->va_starte); - case EXPR_STRING_LITERAL: return string_to_firm(&expr->base.source_position, "str.%u", expr->string_literal.encoding, &expr->string_literal.value); + case EXPR_STRING_LITERAL: return string_to_firm(&expr->base.source_position, "str.%u", &expr->string_literal.value); case EXPR_ERROR: break; } @@ -3786,15 +3762,10 @@ static ir_initializer_t *create_ir_initializer_value( /** test wether type can be initialized by a string constant */ static bool is_string_type(type_t *type) { - type_t *inner; - if (is_type_pointer(type)) { - inner = skip_typeref(type->pointer.points_to); - } else if(is_type_array(type)) { - inner = skip_typeref(type->array.element_type); - } else { + if (!is_type_array(type)) return false; - } + type_t *const inner = skip_typeref(type->array.element_type); return is_type_integer(inner); } @@ -3827,8 +3798,7 @@ static ir_initializer_t *create_ir_initializer_list( break; descend_into_subtype(&path); } - } else if (sub_initializer->kind == INITIALIZER_STRING - || sub_initializer->kind == INITIALIZER_WIDE_STRING) { + } else if (sub_initializer->kind == INITIALIZER_STRING) { /* we might have to descend into types until we're at a scalar * type */ while (true) { @@ -3861,58 +3831,39 @@ static ir_initializer_t *create_ir_initializer_list( return result; } -static ir_initializer_t *create_ir_initializer_string( - const initializer_string_t *initializer, type_t *type) +static ir_initializer_t *create_ir_initializer_string(initializer_t const *const init, type_t *type) { type = skip_typeref(type); - size_t string_len = initializer->string.size; assert(type->kind == TYPE_ARRAY); assert(type->array.size_constant); - size_t len = type->array.size; - ir_initializer_t *irinitializer = create_initializer_compound(len); - - const char *string = initializer->string.begin; - ir_mode *mode = get_ir_mode_storage(type->array.element_type); - - for (size_t i = 0; i < len; ++i) { - char c = 0; - if (i < string_len) - c = string[i]; - - ir_tarval *tv = new_tarval_from_long(c, mode); - ir_initializer_t *char_initializer = create_initializer_tarval(tv); - - set_initializer_compound_value(irinitializer, i, char_initializer); - } - - return irinitializer; -} - -static ir_initializer_t *create_ir_initializer_wide_string( - const initializer_wide_string_t *initializer, type_t *type) -{ - assert(type->kind == TYPE_ARRAY); - assert(type->array.size_constant); - size_t len = type->array.size; - size_t string_len = wstrlen(&initializer->string); - ir_initializer_t *irinitializer = create_initializer_compound(len); - - const char *p = initializer->string.begin; - ir_mode *mode = get_type_mode(ir_type_wchar_t); - - for (size_t i = 0; i < len; ++i) { - utf32 c = 0; - if (i < string_len) { - c = read_utf8_char(&p); + string_literal_expression_t const *const str = get_init_string(init); + size_t const str_len = str->value.size; + size_t const arr_len = type->array.size; + ir_initializer_t *const irinit = create_initializer_compound(arr_len); + ir_mode *const mode = get_ir_mode_storage(type->array.element_type); + char const * p = str->value.begin; + switch (str->value.encoding) { + case STRING_ENCODING_CHAR: + for (size_t i = 0; i != arr_len; ++i) { + char const c = i < str_len ? *p++ : 0; + ir_tarval *const tv = new_tarval_from_long(c, mode); + ir_initializer_t *const tvinit = create_initializer_tarval(tv); + set_initializer_compound_value(irinit, i, tvinit); } - ir_tarval *tv = new_tarval_from_long(c, mode); - ir_initializer_t *char_initializer = create_initializer_tarval(tv); + break; - set_initializer_compound_value(irinitializer, i, char_initializer); + case STRING_ENCODING_WIDE: + for (size_t i = 0; i != arr_len; ++i) { + utf32 const c = i < str_len ? read_utf8_char(&p) : 0; + ir_tarval *const tv = new_tarval_from_long(c, mode); + ir_initializer_t *const tvinit = create_initializer_tarval(tv); + set_initializer_compound_value(irinit, i, tvinit); + } + break; } - return irinitializer; + return irinit; } static ir_initializer_t *create_ir_initializer( @@ -3920,11 +3871,7 @@ static ir_initializer_t *create_ir_initializer( { switch(initializer->kind) { case INITIALIZER_STRING: - return create_ir_initializer_string(&initializer->string, type); - - case INITIALIZER_WIDE_STRING: - return create_ir_initializer_wide_string(&initializer->wide_string, - type); + return create_ir_initializer_string(initializer, type); case INITIALIZER_LIST: return create_ir_initializer_list(&initializer->list, type);