+ const char* const string = value->begin;
+ const size_t slen = value->size;
+
+ set_array_lower_bound_int(type, 0, 0);
+ set_array_upper_bound_int(type, 0, slen);
+ set_type_size_bytes(type, slen);
+ set_type_state(type, layout_fixed);
+
+ ir_initializer_t *initializer = create_initializer_compound(slen);
+ for (size_t i = 0; i < slen; ++i) {
+ ir_tarval *tv = new_tarval_from_long(string[i], mode);
+ ir_initializer_t *val = create_initializer_tarval(tv);
+ set_initializer_compound_value(initializer, i, val);
+ }
+ set_entity_initializer(entity, initializer);
+
+ return create_symconst(dbgi, entity);
+}
+
+static bool try_create_integer(literal_expression_t *literal,
+ type_t *type, unsigned char base)
+{
+ 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 *mode = atomic_modes[akind];
+ ir_tarval *tv = new_integer_tarval_from_str(string, size, 1, base, 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)
+{
+ unsigned us = 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') { ++us; }
+ if (*c == 'l' || *c == 'L') { ++ls; }
+ }
+ }
+
+ unsigned base;
+ switch (literal->base.kind) {
+ case EXPR_LITERAL_INTEGER_OCTAL: base = 8; break;
+ case EXPR_LITERAL_INTEGER: base = 10; break;
+ case EXPR_LITERAL_INTEGER_HEXADECIMAL: base = 16; break;
+ default: panic("invalid literal kind");
+ }
+
+ tarval_int_overflow_mode_t old_mode = tarval_get_integer_overflow_mode();
+
+ /* now try if the constant is small enough for some types */
+ tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
+ if (ls < 1) {
+ if (us == 0 && try_create_integer(literal, type_int, base))
+ goto finished;
+ if ((us == 1 || base != 10)
+ && try_create_integer(literal, type_unsigned_int, base))
+ goto finished;
+ }
+ if (ls < 2) {
+ if (us == 0 && try_create_integer(literal, type_long, base))
+ goto finished;
+ if ((us == 1 || base != 10)
+ && try_create_integer(literal, type_unsigned_long, base))
+ goto finished;
+ }
+ /* last try? then we should not report tarval_bad */
+ if (us != 1 && base == 10)
+ tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
+ if (us == 0 && try_create_integer(literal, type_long_long, base))
+ goto finished;
+
+ /* last try */
+ assert(us == 1 || base != 10);
+ tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
+ bool res = try_create_integer(literal, type_unsigned_long_long, base);
+ if (!res)
+ panic("internal error when parsing number literal");
+
+finished:
+ tarval_set_integer_overflow_mode(old_mode);
+}
+
+void determine_literal_type(literal_expression_t *literal)
+{
+ switch (literal->base.kind) {
+ case EXPR_LITERAL_INTEGER:
+ case EXPR_LITERAL_INTEGER_OCTAL:
+ case EXPR_LITERAL_INTEGER_HEXADECIMAL:
+ create_integer_tarval(literal);
+ return;
+ default:
+ break;
+ }
+}
+
+/**
+ * Creates a Const node representing a constant.
+ */
+static ir_node *literal_to_firm(const literal_expression_t *literal)
+{
+ type_t *type = skip_typeref(literal->base.type);
+ ir_mode *mode = get_ir_mode_storage(type);
+ const char *string = literal->value.begin;
+ size_t size = literal->value.size;
+ ir_tarval *tv;
+
+ switch (literal->base.kind) {
+ case EXPR_LITERAL_WIDE_CHARACTER: {
+ utf32 v = read_utf8_char(&string);
+ char buf[128];
+ size_t len = snprintf(buf, sizeof(buf), UTF32_PRINTF_FORMAT, v);