unsigned size = get_atomic_type_size(kind);
if ((flags & ATOMIC_TYPE_FLAG_FLOAT)
&& !(flags & ATOMIC_TYPE_FLAG_COMPLEX)) {
- if (size == 4) {
- return get_modeF();
- } else if (size == 8) {
- return get_modeD();
- } else {
- panic("unexpected kind");
+ switch (size) {
+ case 4: return get_modeF();
+ case 8: return get_modeD();
+ default: panic("unexpected kind");
}
} else if (flags & ATOMIC_TYPE_FLAG_INTEGER) {
char name[64];
{
assert(entity->kind == ENTITY_COMPOUND_MEMBER);
type_t *base = skip_typeref(entity->declaration.type);
- assert(base->kind == TYPE_ATOMIC || base->kind == TYPE_ENUM);
+ assert(is_type_integer(base));
ir_type *irbase = get_ir_type(base);
unsigned bit_size = entity->compound_member.bit_size;
- assert(!is_type_float(base));
if (is_type_signed(base)) {
return get_signed_int_type_for_bit_size(irbase, bit_size, base);
} else {
/* anonymous bitfield member, skip */
if (entry->compound_member.bitfield)
continue;
- assert(entry_type->kind == TYPE_COMPOUND_STRUCT
- || entry_type->kind == TYPE_COMPOUND_UNION);
+ assert(is_type_compound(entry_type));
ident = id_unique("anon.%u");
} else {
ident = new_id_from_str(symbol->string);
static ir_type *get_ir_type_incomplete(type_t *type)
{
- assert(type != NULL);
type = skip_typeref(type);
if (type->base.firm_type != NULL) {
ir_type *get_ir_type(type_t *type)
{
- assert(type != NULL);
-
type = skip_typeref(type);
if (type->base.firm_type != NULL) {
* @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;
- 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;
+ 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);
}
case STRING_ENCODING_WIDE: {
- slen = wstrlen(value);
- 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;
for (size_t i = 0; i < slen; ++i) {
- assert(p < value->begin + value->size);
+ 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);
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;
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);
tarval_set_integer_overflow_mode(old_mode);
}
-void determine_literal_type(literal_expression_t *literal)
+/**
+ * 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_INTEGER:
- create_integer_tarval(literal);
- return;
- default:
+ assert(literal->target_value != NULL);
+ tv = literal->target_value;
+ break;
+
+ case EXPR_LITERAL_FLOATINGPOINT:
+ tv = new_tarval_from_str(string, size, mode);
+ break;
+
+ case EXPR_LITERAL_BOOLEAN:
+ if (string[0] == 't') {
+ tv = get_mode_one(mode);
+ } else {
+ assert(string[0] == 'f');
+ case EXPR_LITERAL_MS_NOOP:
+ tv = get_mode_null(mode);
+ }
break;
+
+ default:
+ panic("Invalid literal kind found");
}
+
+ dbg_info *dbgi = get_dbg_info(&literal->base.source_position);
+ ir_node *res = new_d_Const(dbgi, tv);
+ ir_mode *mode_arith = get_ir_mode_arithmetic(type);
+ return create_conv(dbgi, res, mode_arith);
}
/**
- * Creates a Const node representing a constant.
+ * Creates a Const node representing a character constant.
*/
-static ir_node *literal_to_firm(const literal_expression_t *literal)
+static ir_node *char_literal_to_firm(string_literal_expression_t const *literal)
{
type_t *type = skip_typeref(literal->base.type);
ir_mode *mode = get_ir_mode_storage(type);
size_t size = literal->value.size;
ir_tarval *tv;
- switch (literal->base.kind) {
- case EXPR_LITERAL_WIDE_CHARACTER: {
+ switch (literal->value.encoding) {
+ case STRING_ENCODING_WIDE: {
utf32 v = read_utf8_char(&string);
char buf[128];
size_t len = snprintf(buf, sizeof(buf), UTF32_PRINTF_FORMAT, v);
break;
}
- case EXPR_LITERAL_CHARACTER: {
+ case STRING_ENCODING_CHAR: {
long long int v;
bool char_is_signed
= get_atomic_type_flags(ATOMIC_TYPE_CHAR) & ATOMIC_TYPE_FLAG_SIGNED;
break;
}
- case EXPR_LITERAL_INTEGER:
- assert(literal->target_value != NULL);
- tv = literal->target_value;
- break;
-
- case EXPR_LITERAL_FLOATINGPOINT:
- tv = new_tarval_from_str(string, size, mode);
- break;
-
- case EXPR_LITERAL_BOOLEAN:
- if (string[0] == 't') {
- tv = get_mode_one(mode);
- } else {
- assert(string[0] == 'f');
- case EXPR_LITERAL_MS_NOOP:
- tv = get_mode_null(mode);
- }
- break;
-
default:
panic("Invalid literal kind found");
}
default:
break;
}
- panic("trying to get pn_Cmp from non-comparison binexpr type");
+ panic("trying to get ir_relation from non-comparison binexpr type");
}
/**
case EXPR_BINARY_MOD:
case EXPR_BINARY_MOD_ASSIGN: {
ir_node *pin = new_Pin(new_NoMem());
- assert(!mode_is_float(mode));
ir_node *op = new_d_Mod(dbgi, pin, left, right, mode,
op_pin_state_floats);
ir_node *res = new_d_Proj(dbgi, op, mode, pn_Mod_res);
case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
return create_assign_binop(expression);
default:
- panic("TODO binexpr type");
+ panic("invalid binexpr type");
}
}
compound_t *compound = type->compound.compound;
entity_t *iter = compound->members.entities;
- for ( ; iter != NULL; iter = iter->base.next) {
- if (iter->base.symbol == symbol) {
- break;
- }
- }
- assert(iter != NULL);
+ for (; iter->base.symbol != symbol; iter = iter->base.next) {}
assert(iter->kind == ENTITY_COMPOUND_MEMBER);
assert(iter->declaration.kind == DECLARATION_KIND_COMPOUND_MEMBER);
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) + 1 };
- 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) + 1 };
- 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;
}
case EXPR_FUNCNAME: return function_name_to_firm( &expr->funcname);
case EXPR_LABEL_ADDRESS: return label_address_to_firm( &expr->label_address);
case EXPR_LITERAL_CASES: return literal_to_firm( &expr->literal);
+ case EXPR_LITERAL_CHARACTER: return char_literal_to_firm( &expr->string_literal);
case EXPR_OFFSETOF: return offsetof_to_firm( &expr->offsetofe);
case EXPR_REFERENCE: return reference_expression_to_firm( &expr->reference);
case EXPR_ENUM_CONSTANT: return enum_constant_to_firm( &expr->reference);
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;
}
compound_t *compound = type->compound.compound;
entity_t *iter = compound->members.entities;
- for ( ; iter != NULL; iter = iter->base.next, ++index) {
- if (iter->base.symbol == symbol) {
- assert(iter->kind == ENTITY_COMPOUND_MEMBER);
- break;
- }
- }
- assert(iter != NULL);
+ for (; iter->base.symbol != symbol; iter = iter->base.next, ++index) {}
+ assert(iter->kind == ENTITY_COMPOUND_MEMBER);
/* revert previous initialisations of other union elements */
if (type->kind == TYPE_COMPOUND_UNION) {
orig_type = iter->declaration.type;
} else {
expression_t *array_index = designator->array_index;
- assert(designator->array_index != NULL);
assert(is_type_array(type));
long index = fold_constant_to_int(array_index);
- assert(index >= 0);
-#ifndef NDEBUG
- if (type->array.size_constant) {
- long array_size = type->array.size;
- assert(index < array_size);
- }
-#endif
+ assert(0 <= index && (!type->array.size_constant || (size_t)index < type->array.size));
top->type = orig_type;
top->index = (size_t) index;
/** 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);
}
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) {
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(
{
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);
assert(s->kind == STATEMENT_ASM);
char const *const text = s->asms.asm_text.begin;
- size_t size = s->asms.asm_text.size;
-
- /* skip the last \0 */
- if (text[size - 1] == '\0')
- --size;
-
- ident *const id = new_id_from_chars(text, size);
+ size_t const size = s->asms.asm_text.size;
+ ident *const id = new_id_from_chars(text, size);
add_irp_asm(id);
}
}