compound_graph_path_entry_t *prev;
};
-static void create_initializer_list(initializer_list_t *initializer,
- type_t *type, ir_entity *entity,
- compound_graph_path_entry_t *entry,
- int len);
+static void create_initializer_object(initializer_t *initializer, type_t *type,
+ ir_entity *entity, compound_graph_path_entry_t *entry, int len);
-static void create_initializer_value(initializer_value_t *initializer,
- ir_entity *entity,
- compound_graph_path_entry_t *entry,
- int len)
+static compound_graph_path *create_compound_path(ir_type *type,
+ compound_graph_path_entry_t *entry, int len)
{
- ir_node *node = expression_to_firm(initializer->value);
-
- ir_type *type = get_entity_type(entity);
compound_graph_path *path = new_compound_graph_path(type, len);
int i = len - 1;
}
assert(i == -1);
+ return path;
+}
+
+static void create_initializer_value(initializer_value_t *initializer,
+ ir_entity *entity,
+ compound_graph_path_entry_t *entry,
+ int len)
+{
+ ir_node *node = expression_to_firm(initializer->value);
+ ir_type *type = get_entity_type(entity);
+ compound_graph_path *path = create_compound_path(type, entry, len);
add_compound_ent_value_w_path(entity, node, path);
}
create_initializer_value((initializer_value_t*) sub_initializer,
entity, &entry, len);
} else {
- assert(sub_initializer->type == INITIALIZER_LIST);
type_t *type = skip_typeref(compound_entry->type);
- create_initializer_list((initializer_list_t*) sub_initializer,
- type, entity, &entry, len);
+ create_initializer_object(sub_initializer, type, entity, &entry,
+ len);
}
++i;
entity, &entry, len);
} else {
assert(sub_initializer->type == INITIALIZER_LIST);
- create_initializer_list((initializer_list_t*) sub_initializer,
- element_type, entity, &entry, len);
+ create_initializer_object(sub_initializer, element_type, entity,
+ &entry, len);
}
}
}
-static void create_initializer_list(initializer_list_t *initializer,
- type_t *type, ir_entity *entity,
- compound_graph_path_entry_t *entry, int len)
+static void create_initializer_string(initializer_string_t *initializer,
+ array_type_t *type, ir_entity *entity,
+ compound_graph_path_entry_t *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 *irtype = get_entity_type(entity);
+ size_t arr_len = get_array_type_size(type);
+ const char *p = initializer->string;
+ size_t i = 0;
+ for(i = 0; i < arr_len; ++i, ++p) {
+ entry.v.array_index = i;
+
+ ir_node *node = new_Const_long(mode_Bs, *p);
+ compound_graph_path *path = create_compound_path(irtype, &entry, len);
+ add_compound_ent_value_w_path(entity, node, path);
+
+ if(*p == '\0')
+ break;
+ }
+}
+
+static void create_initializer_object(initializer_t *initializer, type_t *type,
+ ir_entity *entity, compound_graph_path_entry_t *entry, int len)
{
if(type->type == TYPE_ARRAY) {
- create_initializer_array(initializer, (array_type_t*) type,
- entity, entry, len);
+ array_type_t *array_type = (array_type_t*) type;
+
+ if(initializer->type == INITIALIZER_STRING) {
+ initializer_string_t *string = (initializer_string_t*) initializer;
+ create_initializer_string(string, array_type, entity, entry, len);
+ } else {
+ assert(initializer->type == INITIALIZER_LIST);
+ initializer_list_t *list = (initializer_list_t*) initializer;
+ create_initializer_array(list, array_type, entity, entry, len);
+ }
} else {
+ assert(initializer->type == INITIALIZER_LIST);
+ initializer_list_t *list = (initializer_list_t*) initializer;
+
assert(type->type == TYPE_COMPOUND_STRUCT
|| type->type == TYPE_COMPOUND_UNION);
- create_initializer_compound(initializer, (compound_type_t*) type,
- entity, entry, len);
+ compound_type_t *compound_type = (compound_type_t*) type;
+ create_initializer_compound(list, compound_type, entity, entry, len);
}
}
set_entity_variability(init_entity, variability_initialized);
set_entity_visibility(init_entity, visibility_local);
- assert(initializer->type == INITIALIZER_LIST);
- initializer_list_t *list = (initializer_list_t*) initializer;
-
ir_graph *old_current_ir_graph = current_ir_graph;
current_ir_graph = get_const_code_irg();
type_t *type = skip_typeref(declaration->type);
- create_initializer_list(list, type, init_entity, NULL, 0);
+ create_initializer_object(initializer, type, init_entity, NULL, 0);
assert(current_ir_graph == get_const_code_irg());
current_ir_graph = old_current_ir_graph;
set_atomic_ent_value(entity, value);
}
} else {
- assert(initializer->type == INITIALIZER_LIST);
- initializer_list_t *list = (initializer_list_t*) initializer;
-
declaration_type_t declaration_type = declaration->declaration_type;
assert(declaration_type == DECLARATION_TYPE_LOCAL_VARIABLE_ENTITY
|| declaration_type == DECLARATION_TYPE_GLOBAL_VARIABLE);
set_entity_variability(entity, variability_initialized);
type_t *type = skip_typeref(declaration->type);
- create_initializer_list(list, type, entity, NULL, 0);
+ create_initializer_object(initializer, type, entity, NULL, 0);
}
}
set_entity_variability(entity, variability_uninitialized);
set_entity_visibility(entity, visibility_local);
+ ir_graph *old_current_ir_graph = current_ir_graph;
+ current_ir_graph = get_const_code_irg();
+
create_initializer(declaration);
+
+ assert(current_ir_graph == get_const_code_irg());
+ current_ir_graph = old_current_ir_graph;
}
static void declaration_statement_to_firm(declaration_statement_t *statement)
type_t *const type_left = skip_typeref(orig_type_left);
type_t *const type_right = skip_typeref(orig_type_right);
- if (type_left == type_right) {
+ if (types_compatible(type_left, type_right)) {
return;
}
}
#endif
+static initializer_t *initializer_from_string(array_type_t *type,
+ const char *string)
+{
+ /* TODO: check len vs. size of array type */
+ (void) type;
+
+ initializer_string_t *initializer
+ = allocate_ast_zero(sizeof(initializer[0]));
+
+ initializer->initializer.type = INITIALIZER_STRING;
+ initializer->string = string;
+
+ return (initializer_t*) initializer;
+}
+
static initializer_t *initializer_from_expression(type_t *type,
expression_t *expression)
{
- initializer_value_t *result = allocate_ast_zero(sizeof(result[0]));
/* TODO check that expression is a constant expression */
if(atype == ATOMIC_TYPE_CHAR
|| atype == ATOMIC_TYPE_SCHAR
|| atype == ATOMIC_TYPE_UCHAR) {
- /* it's fine TODO: check for length of string array... */
- goto initializer_from_expression_finished;
+
+ string_literal_t *literal = (string_literal_t*) expression;
+ return initializer_from_string(array_type, literal->value);
}
}
}
semantic_assign(type, &expression, "initializer");
-initializer_from_expression_finished:
+ initializer_value_t *result = allocate_ast_zero(sizeof(result[0]));
result->initializer.type = INITIALIZER_VALUE;
result->value = expression;
initializer_t *initializer = parse_initializer(type);
if(type->type == TYPE_ARRAY && initializer != NULL) {
- assert(initializer->type == INITIALIZER_LIST);
-
- initializer_list_t *list = (initializer_list_t*) initializer;
array_type_t *array_type = (array_type_t*) type;
if(array_type->size == NULL) {
cnst->expression.type = EXPR_CONST;
cnst->expression.datatype = type_size_t;
- cnst->v.int_value = list->len;
+
+ if(initializer->type == INITIALIZER_LIST) {
+ initializer_list_t *list
+ = (initializer_list_t*) initializer;
+ cnst->v.int_value = list->len;
+ } else {
+ assert(initializer->type == INITIALIZER_STRING);
+ initializer_string_t *string
+ = (initializer_string_t*) initializer;
+ cnst->v.int_value = strlen(string->string) + 1;
+ }
array_type->size = (expression_t*) cnst;
}
static void semantic_binexpr_assign(binary_expression_t *expression)
{
- expression_t *left = expression->left;
- type_t *type_left = left->datatype;
+ expression_t *left = expression->left;
+ type_t *orig_type_left = left->datatype;
- if(type_left == NULL)
+ if(orig_type_left == NULL)
return;
+ type_t *type_left = skip_typeref(orig_type_left);
+
if (type_left->type == TYPE_ARRAY) {
parse_error("Cannot assign to arrays.");
- } else if (type_left != NULL) {
- semantic_assign(type_left, &expression->right, "assignment");
+ return;
}
- expression->expression.datatype = type_left;
+ if(type_left->qualifiers & TYPE_QUALIFIER_CONST) {
+ parser_print_error_prefix();
+ fprintf(stderr, "assignment to readonly location '");
+ print_expression(left);
+ fprintf(stderr, "' (type ");
+ print_type_quoted(orig_type_left);
+ fprintf(stderr, ")\n");
+ }
+
+ semantic_assign(orig_type_left, &expression->right, "assignment");
+
+ expression->expression.datatype = orig_type_left;
}
static void semantic_comma(binary_expression_t *expression)