From 81bf9bd0b206ce8211d4e9d79d7193f8a7cd3315 Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Fri, 30 Nov 2007 14:49:17 +0000 Subject: [PATCH] Next wchar_t step: Initialization with wide string literals. [r18580] --- Makefile | 2 +- ast.h | 1 + ast2firm.c | 55 +++++++++++++++++++++++++++++++----- ast_t.h | 18 ++++++++---- main.c | 2 +- parser.c | 81 ++++++++++++++++++++++++++++++++++++++---------------- 6 files changed, 120 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index c84ffbc..c719eef 100644 --- 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 --- 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; diff --git a/ast2firm.c b/ast2firm.c index 515c7cc..29509cc 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -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 --- 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 --- 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 diff --git a/parser.c b/parser.c index fd91636..0c8b187 100644 --- 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; -- 2.20.1