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
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;
}
}
+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;
INITIALIZER_VALUE,
INITIALIZER_LIST,
INITIALIZER_STRING,
- INITIALIZER_COUNT
+ INITIALIZER_WIDE_STRING
} initializer_type_t;
struct initializer_base_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 {
#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
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];
}
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;
}
}
}
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;