copy line and pragma directive parsers from lexer
[cparser] / ast2firm.c
index b425c62..dc0941f 100644 (file)
@@ -1101,16 +1101,14 @@ static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode)
  * @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 + 1;
-               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;
@@ -1123,9 +1121,7 @@ static ir_node *string_to_firm(source_position_t const *const src_pos, char cons
        }
 
        case STRING_ENCODING_WIDE: {
-               slen        = wstrlen(value) + 1;
-               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;
@@ -1161,14 +1157,12 @@ finish:;
 
 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;
 
@@ -1177,36 +1171,29 @@ static bool try_create_integer(literal_expression_t *literal, type_t *type)
        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);
@@ -1224,17 +1211,6 @@ finished:
        tarval_set_integer_overflow_mode(old_mode);
 }
 
-void determine_literal_type(literal_expression_t *literal)
-{
-       switch (literal->base.kind) {
-       case EXPR_LITERAL_INTEGER:
-               create_integer_tarval(literal);
-               return;
-       default:
-               break;
-       }
-}
-
 /**
  * Creates a Const node representing a constant.
  */
@@ -1287,7 +1263,7 @@ static ir_node *char_literal_to_firm(string_literal_expression_t const *literal)
        size_t      size   = literal->value.size;
        ir_tarval  *tv;
 
-       switch (literal->encoding) {
+       switch (literal->value.encoding) {
        case STRING_ENCODING_WIDE: {
                utf32  v = read_utf8_char(&string);
                char   buf[128];
@@ -3144,19 +3120,19 @@ static ir_node *function_name_to_firm(
        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) };
-                       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) };
-                       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;
        }
@@ -3347,7 +3323,7 @@ static ir_node *_expression_to_firm(expression_t const *const expr)
        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;
        }
@@ -3786,15 +3762,10 @@ static ir_initializer_t *create_ir_initializer_value(
 /** 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);
 }
 
@@ -3827,8 +3798,7 @@ static ir_initializer_t *create_ir_initializer_list(
                                        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) {
@@ -3861,58 +3831,39 @@ static ir_initializer_t *create_ir_initializer_list(
        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(
@@ -3920,11 +3871,7 @@ 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);