+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 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: {
+ elem_type = ir_type_char;
+
+ ir_mode *const mode = get_type_mode(elem_type);
+ char const *p = value->begin;
+ for (size_t i = 0; i < slen; ++i) {
+ ir_tarval *tv = new_tarval_from_long(*p++, mode);
+ ir_initializer_t *val = create_initializer_tarval(tv);
+ set_initializer_compound_value(initializer, i, val);
+ }
+ goto finish;
+ }
+
+ case STRING_ENCODING_WIDE: {
+ elem_type = ir_type_wchar_t;
+
+ ir_mode *const mode = get_type_mode(elem_type);
+ char const *p = value->begin;
+ for (size_t i = 0; i < slen; ++i) {
+ assert(p <= value->begin + value->size);
+ utf32 v = read_utf8_char(&p);
+ ir_tarval *tv = new_tarval_from_long(v, mode);
+ ir_initializer_t *val = create_initializer_tarval(tv);
+ set_initializer_compound_value(initializer, i, val);
+ }
+ goto finish;
+ }
+ }
+ panic("invalid string encoding");
+
+finish:;
+ ir_type *const type = new_type_array(1, elem_type);
+ set_array_bounds_int(type, 0, 0, slen);
+ set_type_size_bytes( type, slen * get_type_size_bytes(elem_type));
+ set_type_state( type, layout_fixed);
+
+ ir_type *const global_type = get_glob_type();
+ ident *const id = id_unique(id_prefix);
+ dbg_info *const dbgi = get_dbg_info(src_pos);
+ ir_entity *const entity = new_d_entity(global_type, id, type, dbgi);
+ set_entity_ld_ident( entity, id);
+ set_entity_visibility( entity, ir_visibility_private);
+ add_entity_linkage( entity, IR_LINKAGE_CONSTANT);
+ set_entity_initializer(entity, initializer);
+
+ return create_symconst(dbgi, entity);
+}
+
+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);
+ if (tv == tarval_bad)
+ return false;
+
+ literal->base.type = type;
+ literal->target_value = tv;
+ return true;
+}
+
+static void create_integer_tarval(literal_expression_t *literal)