Use struct string_literal_expression_t instead of struct literal_expression_t for...
authorChristoph Mallon <christoph.mallon@gmx.de>
Wed, 23 May 2012 17:36:18 +0000 (19:36 +0200)
committerChristoph Mallon <christoph.mallon@gmx.de>
Tue, 5 Jun 2012 06:35:05 +0000 (08:35 +0200)
ast.c
ast2firm.c
ast_t.h
parser.c
walk.c

diff --git a/ast.c b/ast.c
index 2daa235..6ddf111 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -232,6 +232,13 @@ static void print_quoted_string(const string_t *const string, char border)
        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));
@@ -252,12 +259,6 @@ static void print_literal(const literal_expression_t *literal)
                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;
        }
@@ -658,6 +659,8 @@ static bool needs_parentheses(expression_t const *const expr, unsigned const top
                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. */
@@ -702,6 +705,8 @@ static void print_expression_prec(expression_t const *expr, unsigned const top_p
        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;
@@ -1782,6 +1787,8 @@ expression_classification_t is_constant_expression(const expression_t *expressio
 {
        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:
index 21ec74b..f41a882 100644 (file)
@@ -1253,6 +1253,47 @@ static ir_node *literal_to_firm(const literal_expression_t *literal)
        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);
@@ -1282,25 +1323,6 @@ static ir_node *literal_to_firm(const literal_expression_t *literal)
                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");
        }
@@ -3326,6 +3348,8 @@ static ir_node *_expression_to_firm(expression_t const *const expr)
        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);
diff --git a/ast_t.h b/ast_t.h
index 371295e..10ed251 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -229,8 +229,6 @@ typedef enum funcname_kind_t {
             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
 
 /**
@@ -252,7 +250,7 @@ struct expression_base_t {
 };
 
 /**
- * integer/float constants, character and string literals
+ * integer, float and boolean constants
  */
 struct literal_expression_t {
        expression_base_t  base;
@@ -263,6 +261,9 @@ struct literal_expression_t {
        ir_tarval         *target_value;
 };
 
+/**
+ * string and character literals
+ */
 struct string_literal_expression_t {
        expression_base_t  base;
        string_encoding_t  encoding;
index 0a2b4e9..5649114 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -325,8 +325,8 @@ static size_t get_expression_struct_size(expression_kind_t kind)
                [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),
@@ -1489,6 +1489,8 @@ unary:
                        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?
@@ -4650,6 +4652,8 @@ static bool expression_returns(expression_t const *const expr)
                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:
@@ -5858,11 +5862,10 @@ static expression_t *parse_character_constant(void)
        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 {
@@ -5875,11 +5878,10 @@ static expression_t *parse_character_constant(void)
 
        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;
diff --git a/walk.c b/walk.c
index 5c65515..1e98f4d 100644 (file)
--- a/walk.c
+++ b/walk.c
@@ -177,6 +177,8 @@ static void walk_expression(expression_t *const expr,
                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: