void dmemory_lower_Alloc(ir_node *node) { assert(is_Alloc(node)); if (get_Alloc_where(node) != heap_alloc) return; ir_graph *irg = get_irn_irg(node); ir_type *type = get_Alloc_type(node); ir_node *count = get_Alloc_count(node); ir_node *res = NULL; ir_node *cur_mem = get_Alloc_mem(node); ir_node *block = get_nodes_block(node); if (is_Class_type(type)) { res = (*dmemory_model.alloc_object)(type, irg, block, &cur_mem); ddispatch_prepare_new_instance(type, res, irg, block, &cur_mem); } else if (is_Array_type(type)) { ir_type *eltype = get_array_element_type(type); res = (*dmemory_model.alloc_array)(eltype, count, irg, block, &cur_mem); } else { assert (0); } turn_into_tuple(node, pn_Alloc_max); set_irn_n(node, pn_Alloc_M, cur_mem); set_irn_n(node, pn_Alloc_res, res); }
{ const tp_op *tpop = get_type_tpop(tp); tpop->ops.set_type_size(tp, size); } unsigned get_type_alignment_bytes(ir_type *tp) { unsigned align = 1; if (tp->align > 0) return tp->align; /* alignment NOT set calculate it "on demand" */ if (tp->mode) align = (get_mode_size_bits(tp->mode) + 7) >> 3; else if (is_Array_type(tp)) align = get_type_alignment_bytes(get_array_element_type(tp)); else if (is_compound_type(tp)) { align = 0; for (size_t i = 0, n = get_compound_n_members(tp); i < n; ++i) { ir_type *t = get_entity_type(get_compound_member(tp, i)); unsigned a = get_type_alignment_bytes(t); if (a > align) align = a; } } else if (is_Method_type(tp)) { align = 0; } /* write back */ tp->align = align;
static bool check_initializer(const ir_initializer_t *initializer, const ir_type *type, const ir_entity *context) { bool fine = true; switch (get_initializer_kind(initializer)) { case IR_INITIALIZER_NULL: return fine; case IR_INITIALIZER_TARVAL: { ir_tarval *tv = get_initializer_tarval_value(initializer); if (get_type_mode(type) != get_tarval_mode(tv)) { report_error("tarval initializer for entity %+F has wrong mode: %+F vs %+F", context, get_type_mode(type), get_tarval_mode(tv)); fine = false; } return fine; } case IR_INITIALIZER_CONST: { ir_node *value = get_initializer_const_value(initializer); if (get_type_mode(type) != get_irn_mode(value)) { report_error("const initializer for entity %+F has wrong mode: %+F vs %+F", context, get_type_mode(type), get_irn_mode(value)); fine = false; } if (!constant_on_correct_irg(value)) { report_error("initializer const value %+F for entity %+F not on const-code irg", value, context); fine = false; } return fine; } case IR_INITIALIZER_COMPOUND: { size_t n_entries = get_initializer_compound_n_entries(initializer); if (is_Array_type(type)) { ir_type *element_type = get_array_element_type(type); /* TODO: check array bounds? */ for (size_t i = 0; i < n_entries; ++i) { const ir_initializer_t *sub_initializer = get_initializer_compound_value(initializer, i); check_initializer(sub_initializer, element_type, context); } } else if (is_compound_type(type)) { size_t n_members = get_compound_n_members(type); if (n_entries > n_members) { report_error("too many values in compound initializer of %+F", context); fine = false; } for (size_t i = 0; i < n_entries; ++i) { if (i >= n_members) break; ir_entity *member = get_compound_member(type, i); ir_type *member_type = get_entity_type(member); const ir_initializer_t *sub_initializer = get_initializer_compound_value(initializer, i); check_initializer(sub_initializer, member_type, context); } } else { report_error("compound initiailizer for non-array/compound type in entity %+F", context); fine = false; } return fine; } } report_error("invalid initializer for entity %+F", context); return false; }