Next wchar_t step: Initialization with wide string literals.
authorChristoph Mallon <christoph.mallon@gmx.de>
Fri, 30 Nov 2007 14:49:17 +0000 (14:49 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Fri, 30 Nov 2007 14:49:17 +0000 (14:49 +0000)
[r18580]

Makefile
ast.h
ast2firm.c
ast_t.h
main.c
parser.c

index c84ffbc..c719eef 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 GOAL = cparser
 
-FIRM_HOME = $(HOME)/projects/firm
+FIRM_HOME = $(HOME)/jambuild
 FIRM_BUILD = $(FIRM_HOME)/build/i686-pc-linux-gnu/debug/
 FIRM_CFLAGS = -I$(FIRM_HOME)/libfirm/include -I$(FIRM_HOME)/obstack -I$(FIRM_HOME)/libcore -I$(FIRM_HOME)/libcore/libcore -I$(FIRM_HOME)
 FIRM_LIBS = -L$(FIRM_BUILD) -lfirm -llpp -lcore -lm -lz -ldl
diff --git a/ast.h b/ast.h
index fdb02b3..1c64fc8 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -34,6 +34,7 @@ typedef struct initializer_base_t           initializer_base_t;
 typedef struct initializer_list_t           initializer_list_t;
 typedef struct initializer_value_t          initializer_value_t;
 typedef struct initializer_string_t         initializer_string_t;
+typedef struct initializer_wide_string_t    initializer_wide_string_t;
 typedef union  initializer_t                initializer_t;
 
 typedef struct declaration_t                declaration_t;
index 515c7cc..29509cc 100644 (file)
@@ -2342,20 +2342,61 @@ static void create_initializer_string(initializer_string_t *initializer,
        }
 }
 
+static void create_initializer_wide_string(
+       const initializer_wide_string_t *const initializer, array_type_t *const type,
+       ir_entity *const entity, compound_graph_path_entry_t *const last_entry,
+       int len)
+{
+       type_t *element_type = type->element_type;
+       element_type         = skip_typeref(element_type);
+
+       compound_graph_path_entry_t entry;
+       entry.type = COMPOUND_GRAPH_ENTRY_ARRAY;
+       entry.prev = last_entry;
+       ++len;
+
+       ir_type           *const irtype  = get_entity_type(entity);
+       const size_t             arr_len = get_array_type_size(type);
+       const wchar_rep_t *      p       = initializer->string.begin;
+       const wchar_rep_t *const end     = p + initializer->string.size;
+       for (size_t i = 0; i < arr_len && p != end; ++i, ++p) {
+               entry.v.array_index = i;
+
+               ir_node             *node = new_Const_long(mode_Is, *p);
+               compound_graph_path *path = create_compound_path(irtype, &entry, len);
+               add_compound_ent_value_w_path(entity, node, path);
+       }
+}
+
 static void create_initializer_object(initializer_t *initializer, type_t *type,
                ir_entity *entity, compound_graph_path_entry_t *entry, int len)
 {
        if(is_type_array(type)) {
                array_type_t *array_type = &type->array;
 
-               if(initializer->type == INITIALIZER_STRING) {
-                       initializer_string_t *string = &initializer->string;
-                       create_initializer_string(string, array_type, entity, entry, len);
-               } else {
-                       assert(initializer->type == INITIALIZER_LIST);
-                       initializer_list_t *list = &initializer->list;
-                       create_initializer_array(list, array_type, entity, entry, len);
+               switch (initializer->type) {
+                       case INITIALIZER_STRING: {
+                               initializer_string_t *const string = &initializer->string;
+                               create_initializer_string(string, array_type, entity, entry, len);
+                               return;
+                       }
+
+                       case INITIALIZER_WIDE_STRING: {
+                               initializer_wide_string_t *const string = &initializer->wide_string;
+                               create_initializer_wide_string(string, array_type, entity, entry, len);
+                               return;
+                       }
+
+                       case INITIALIZER_LIST: {
+                               initializer_list_t *const list = &initializer->list;
+                               create_initializer_array(list, array_type, entity, entry, len);
+                               return;
+                       }
+
+                       case INITIALIZER_VALUE:
+                               break;
                }
+               panic("Unhandled initializer");
        } else {
                assert(initializer->type == INITIALIZER_LIST);
                initializer_list_t *list = &initializer->list;
diff --git a/ast_t.h b/ast_t.h
index dbcc4f4..1f67819 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -251,7 +251,7 @@ typedef enum {
        INITIALIZER_VALUE,
        INITIALIZER_LIST,
        INITIALIZER_STRING,
-       INITIALIZER_COUNT
+       INITIALIZER_WIDE_STRING
 } initializer_type_t;
 
 struct initializer_base_t {
@@ -274,12 +274,18 @@ struct initializer_string_t {
        const char         *string;
 };
 
+struct initializer_wide_string_t {
+       initializer_base_t  initializer;
+       wide_string_t       string;
+};
+
 union initializer_t {
-       initializer_type_t   type;
-       initializer_base_t   base;
-       initializer_value_t  value;
-       initializer_list_t   list;
-       initializer_string_t string;
+       initializer_type_t        type;
+       initializer_base_t        base;
+       initializer_value_t       value;
+       initializer_list_t        list;
+       initializer_string_t      string;
+       initializer_wide_string_t wide_string;
 };
 
 struct declaration_t {
diff --git a/main.c b/main.c
index dbe4cfb..4bfb5c0 100644 (file)
--- a/main.c
+++ b/main.c
@@ -25,7 +25,7 @@
 #include "write_fluffy.h"
 
 #ifndef PREPROCESSOR
-#define PREPROCESSOR "cpp -std=c99"
+#define PREPROCESSOR "cpp -std=c99 -U__WCHAR_TYPE__ -D__WCHAR_TYPE__=int"
 #endif
 
 #ifndef LINKER
index fd91636..0c8b187 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -236,11 +236,12 @@ static type_t *allocate_type_zero(type_type_t type)
 static size_t get_initializer_size(initializer_type_t type)
 {
        static const size_t sizes[] = {
-               [INITIALIZER_VALUE]  = sizeof(initializer_value_t),
-               [INITIALIZER_STRING] = sizeof(initializer_string_t),
-               [INITIALIZER_LIST]   = sizeof(initializer_list_t)
+               [INITIALIZER_VALUE]       = sizeof(initializer_value_t),
+               [INITIALIZER_STRING]      = sizeof(initializer_string_t),
+               [INITIALIZER_WIDE_STRING] = sizeof(initializer_wide_string_t),
+               [INITIALIZER_LIST]        = sizeof(initializer_list_t)
        };
-       assert(type < INITIALIZER_COUNT);
+       assert(type < sizeof(sizes) / sizeof(*sizes));
        assert(sizes[type] != 0);
        return sizes[type];
 }
@@ -1093,27 +1094,45 @@ static initializer_t *initializer_from_string(array_type_t *type,
        return initializer;
 }
 
+static initializer_t *initializer_from_wide_string(array_type_t *const type,
+                                                   wide_string_t *const string)
+{
+       /* TODO: check len vs. size of array type */
+       (void) type;
+
+       initializer_t *const initializer =
+               allocate_initializer(INITIALIZER_WIDE_STRING);
+       initializer->wide_string.string = *string;
+
+       return initializer;
+}
+
 static initializer_t *initializer_from_expression(type_t *type,
                                                   expression_t *expression)
 {
        /* TODO check that expression is a constant expression */
 
        /* ยง 6.7.8.14/15 char array may be initialized by string literals */
-       if(is_type_array(type) && expression->type == EXPR_STRING_LITERAL) {
-               array_type_t *array_type   = &type->array;
-               type_t       *element_type = array_type->element_type;
-
-               if(element_type->type == TYPE_ATOMIC) {
-                       atomic_type_t      *atomic_type = &element_type->atomic;
-                       atomic_type_type_t  atype       = atomic_type->atype;
+       type_t *const expr_type = expression->base.datatype;
+       if (is_type_array(type) && expr_type->type == TYPE_POINTER) {
+               array_type_t *const array_type     = &type->array;
+               type_t       *const element_type   = skip_typeref(array_type->element_type);
+
+               if (element_type->type == TYPE_ATOMIC) {
+                       switch (expression->type) {
+                               case EXPR_STRING_LITERAL:
+                                       if (element_type->atomic.atype == ATOMIC_TYPE_CHAR) {
+                                               return initializer_from_string(array_type,
+                                                       expression->string.value);
+                                       }
 
-                       /* TODO handle wide strings */
-                       if(atype == ATOMIC_TYPE_CHAR
-                                       || atype == ATOMIC_TYPE_SCHAR
-                                       || atype == ATOMIC_TYPE_UCHAR) {
+                               case EXPR_WIDE_STRING_LITERAL:
+                                       if (get_unqualified_type(element_type) == skip_typeref(type_wchar_t)) {
+                                               return initializer_from_wide_string(array_type,
+                                                       &expression->wide_string.value);
+                                       }
 
-                               string_literal_expression_t *literal = &expression->string;
-                               return initializer_from_string(array_type, literal->value);
+                               default: break;
                        }
                }
        }
@@ -2427,13 +2446,27 @@ static void parse_init_declarator_rest(declaration_t *declaration)
 
                        cnst->base.datatype = type_size_t;
 
-                       if(initializer->type == INITIALIZER_LIST) {
-                               initializer_list_t *list = &initializer->list;
-                               cnst->conste.v.int_value = list->len;
-                       } else {
-                               assert(initializer->type == INITIALIZER_STRING);
-                               initializer_string_t *string = &initializer->string;
-                               cnst->conste.v.int_value = strlen(string->string) + 1;
+                       switch (initializer->type) {
+                               case INITIALIZER_LIST: {
+                                       initializer_list_t *const list = &initializer->list;
+                                       cnst->conste.v.int_value = list->len;
+                                       break;
+                               }
+
+                               case INITIALIZER_STRING: {
+                                       initializer_string_t *const string = &initializer->string;
+                                       cnst->conste.v.int_value = strlen(string->string) + 1;
+                                       break;
+                               }
+
+                               case INITIALIZER_WIDE_STRING: {
+                                       initializer_wide_string_t *const string = &initializer->wide_string;
+                                       cnst->conste.v.int_value = string->string.size;
+                                       break;
+                               }
+
+                               default:
+                                       panic("invalid initializer type");
                        }
 
                        array_type->size = cnst;