X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftr%2Ftype.c;h=d0820ac58f375993f9d6597187c2f664d8c1a0cc;hb=b9d11a19d0b84d6824633806283af13546ce495d;hp=39f323cc6edeba027831617a8766d3bf5b22cdd8;hpb=818d589726eeaeb4c52d66bcccb3d082d44b0b5a;p=libfirm diff --git a/ir/tr/type.c b/ir/tr/type.c index 39f323cc6..d0820ac58 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -361,6 +361,7 @@ int get_type_alignment_bits(ir_type *tp) { void set_type_alignment_bits(ir_type *tp, int align) { assert(tp && tp->kind == k_type); + assert((align == -1 || (align & (align - 1)) == 0) && "type alignment not power of two"); /* Methods don't have an alignment. */ if (tp->type_op != type_method) { tp->align = align; @@ -369,7 +370,11 @@ set_type_alignment_bits(ir_type *tp, int align) { void set_type_alignment_bytes(ir_type *tp, int align) { - set_type_alignment_bits(tp, 8*align); + if (align == -1) { + set_type_alignment_bits(tp, -1); + } else { + set_type_alignment_bits(tp, 8*align); + } } /* Returns a human readable string for the enum entry. */ @@ -765,7 +770,8 @@ ir_type *new_d_type_class (ident *name, dbg_info *db) { res->attr.ca.supertypes = NEW_ARR_F (ir_type *, 0); res->attr.ca.peculiarity = peculiarity_existent; res->attr.ca.type_info = NULL; - res->attr.ca.final = 0; + res->attr.ca.vtable_size = 0; + res->attr.ca.clss_flags = cf_none; res->attr.ca.dfn = 0; hook_new_type(res); return res; @@ -971,12 +977,44 @@ void set_class_peculiarity (ir_type *clss, peculiarity pec) { clss->attr.ca.peculiarity = pec; } +/* Returns the size of the virtual function table. */ +unsigned (get_class_vtable_size)(const ir_type *clss) { + return _get_class_vtable_size(clss); +} + +/* Sets a new size of the virtual function table. */ +void (set_class_vtable_size)(ir_type *clss, unsigned size) { + _set_class_vtable_size(clss, size); +} + +/* Returns non-zero if a class is final. */ int (is_class_final)(const ir_type *clss) { return _is_class_final(clss); } -void (set_class_final)(ir_type *clss, int final) { - _set_class_final(clss, final); +/* Sets if a class is final. */ +void (set_class_final)(ir_type *clss, int flag) { + _set_class_final(clss, flag); +} + +/* Returns non-zero if a class is an interface. */ +int (is_class_interface)(const ir_type *clss) { + return _is_class_interface(clss); +} + +/* Sets the class interface flag. */ +void (set_class_interface)(ir_type *clss, int flag) { + _set_class_interface(clss, flag); +} + +/* Returns non-zero if a class is abstract. */ +int (is_class_abstract)(const ir_type *clss) { + return _is_class_abstract(clss); +} + +/* Sets the class abstract flag. */ +void (set_class_abstract)(ir_type *clss, int final) { + _set_class_abstract(clss, final); } void set_class_dfn (ir_type *clss, int dfn) { @@ -1514,6 +1552,7 @@ void free_array_attrs (ir_type *array) { assert(array && (array->type_op == type_array)); free(array->attr.aa.lower_bound); free(array->attr.aa.upper_bound); + free(array->attr.aa.order); } /* manipulate private fields of array ir_type */ @@ -1930,3 +1969,60 @@ ir_type *get_associated_type(const ir_type *tp) { void set_default_size_bits(ir_type *tp, int size) { tp->size = size; } + +/* + * Allocate an area of size bytes aligned at alignment + * at the start or the end of a frame type. + * The frame type must have already an fixed layout. + */ +entity *frame_alloc_area(type *frame_type, int size, int alignment, int at_start) +{ + entity *area; + ir_type *tp; + ident *name; + char buf[32]; + int frame_align, i, offset, frame_size; + static unsigned area_cnt = 0; + static ir_type *a_byte = NULL; + + assert(is_frame_type(frame_type)); + assert(get_type_state(frame_type) == layout_fixed); + + if (! a_byte) + a_byte = new_type_primitive(new_id_from_chars("byte", 4), mode_Bu); + + snprintf(buf, sizeof(buf), "area%u", area_cnt++); + name = new_id_from_str(buf); + + /* align the size */ + frame_align = get_type_alignment_bytes(frame_type); + size = (size + frame_align - 1) & -frame_align; + + tp = new_type_array(mangle_u(get_type_ident(frame_type), name), 1, a_byte); + set_array_bounds_int(tp, 0, 0, size); + set_type_alignment_bytes(tp, alignment); + + frame_size = get_type_size_bytes(frame_type); + if (at_start) { + /* fix all offsets so far */ + for (i = get_class_n_members(frame_type) - 1; i >= 0; --i) { + entity *ent = get_class_member(frame_type, i); + + set_entity_offset_bytes(ent, get_entity_offset_bytes(ent) + size); + } + /* calculate offset and new type size */ + offset = 0; + frame_size += size; + } + else { + /* calculate offset and new type size */ + offset = (frame_size + alignment - 1) & -alignment; + frame_size = offset + size; + } + + area = new_entity(frame_type, name, tp); + set_entity_offset_bytes(area, offset); + set_type_size_bytes(frame_type, frame_size); + + return area; +}