print_char(border);
}
+static void print_char_literal(string_literal_expression_t const *const literal)
+{
+ if (literal->base.kind == EXPR_LITERAL_WIDE_CHARACTER)
+ print_char('L');
+ print_quoted_string(&literal->value, '\'');
+}
+
static void print_string_literal(const string_literal_expression_t *literal)
{
print_string(get_string_encoding_prefix(literal->encoding));
print_stringrep(&literal->suffix);
return;
- case EXPR_LITERAL_WIDE_CHARACTER:
- print_char('L');
- /* FALLTHROUGH */
- case EXPR_LITERAL_CHARACTER:
- print_quoted_string(&literal->value, '\'');
- return;
default:
break;
}
case EXPR_ENUM_CONSTANT:
case EXPR_FUNCNAME:
case EXPR_LITERAL_CASES:
+ case EXPR_LITERAL_CHARACTER:
+ case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_REFERENCE:
case EXPR_STRING_LITERAL:
/* Do not print () around subexpressions consisting of a single token. */
case EXPR_FUNCNAME: print_funcname( &expr->funcname); break;
case EXPR_LABEL_ADDRESS: print_label_address_expression(&expr->label_address); break;
case EXPR_LITERAL_CASES: print_literal( &expr->literal); break;
+ case EXPR_LITERAL_CHARACTER:
+ case EXPR_LITERAL_WIDE_CHARACTER: print_char_literal( &expr->string_literal); break;
case EXPR_OFFSETOF: print_offsetof_expression( &expr->offsetofe); break;
case EXPR_REFERENCE:
case EXPR_ENUM_CONSTANT: print_reference_expression( &expr->reference); break;
{
switch (expression->kind) {
case EXPR_LITERAL_CASES:
+ case EXPR_LITERAL_CHARACTER:
+ case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_CLASSIFY_TYPE:
case EXPR_OFFSETOF:
case EXPR_ALIGNOF:
size_t size = literal->value.size;
ir_tarval *tv;
+ switch (literal->base.kind) {
+ 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");
+ }
+
+ 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 character constant.
+ */
+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);
+ 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);
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");
}
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:
+ case EXPR_LITERAL_WIDE_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);
EXPR_LITERAL_BOOLEAN: \
case EXPR_LITERAL_INTEGER: \
case EXPR_LITERAL_FLOATINGPOINT: \
- case EXPR_LITERAL_CHARACTER: \
- case EXPR_LITERAL_WIDE_CHARACTER: \
case EXPR_LITERAL_MS_NOOP
/**
};
/**
- * integer/float constants, character and string literals
+ * integer, float and boolean constants
*/
struct literal_expression_t {
expression_base_t base;
ir_tarval *target_value;
};
+/**
+ * string and character literals
+ */
struct string_literal_expression_t {
expression_base_t base;
string_encoding_t encoding;
[EXPR_LITERAL_BOOLEAN] = sizeof(literal_expression_t),
[EXPR_LITERAL_INTEGER] = sizeof(literal_expression_t),
[EXPR_LITERAL_FLOATINGPOINT] = sizeof(literal_expression_t),
- [EXPR_LITERAL_CHARACTER] = sizeof(literal_expression_t),
- [EXPR_LITERAL_WIDE_CHARACTER] = sizeof(literal_expression_t),
+ [EXPR_LITERAL_CHARACTER] = sizeof(string_literal_expression_t),
+ [EXPR_LITERAL_WIDE_CHARACTER] = sizeof(string_literal_expression_t),
[EXPR_STRING_LITERAL] = sizeof(string_literal_expression_t),
[EXPR_COMPOUND_LITERAL] = sizeof(compound_literal_expression_t),
[EXPR_CALL] = sizeof(call_expression_t),
return;
case EXPR_LITERAL_CASES:
+ case EXPR_LITERAL_CHARACTER:
+ case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_ERROR:
case EXPR_STRING_LITERAL:
case EXPR_COMPOUND_LITERAL: // TODO init?
case EXPR_REFERENCE:
case EXPR_ENUM_CONSTANT:
case EXPR_LITERAL_CASES:
+ case EXPR_LITERAL_CHARACTER:
+ case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_STRING_LITERAL:
case EXPR_COMPOUND_LITERAL: // TODO descend into initialisers
case EXPR_LABEL_ADDRESS:
switch (token.string.encoding) {
case STRING_ENCODING_CHAR: {
literal = allocate_expression_zero(EXPR_LITERAL_CHARACTER);
- literal->base.type = c_mode & _CXX ? type_char : type_int;
- literal->literal.value = token.string.string;
+ literal->base.type = c_mode & _CXX ? type_char : type_int;
+ literal->string_literal.value = token.string.string;
- size_t len = literal->literal.value.size;
- if (len > 1) {
+ if (literal->string_literal.value.size > 1) {
if (!GNU_MODE && !(c_mode & _C99)) {
errorf(HERE, "more than 1 character in character constant");
} else {
case STRING_ENCODING_WIDE: {
literal = allocate_expression_zero(EXPR_LITERAL_WIDE_CHARACTER);
- literal->base.type = type_int;
- literal->literal.value = token.string.string;
+ literal->base.type = type_int;
+ literal->string_literal.value = token.string.string;
- size_t len = wstrlen(&literal->literal.value);
- if (len > 1) {
+ if (wstrlen(&literal->string_literal.value) > 1) {
warningf(WARN_MULTICHAR, HERE, "multi-character character constant");
}
break;
return;
case EXPR_LITERAL_CASES:
+ case EXPR_LITERAL_CHARACTER:
+ case EXPR_LITERAL_WIDE_CHARACTER:
case EXPR_REFERENCE:
case EXPR_ENUM_CONSTANT:
case EXPR_STRING_LITERAL: