unsigned alignment(const typet &type, const namespacet &ns) { if(type.id()==ID_array || type.id()==ID_incomplete_array) return alignment(type.subtype(), ns); else if(type.id()==ID_struct || type.id()==ID_union) { const struct_union_typet::componentst &components= to_struct_union_type(type).components(); unsigned result=1; // get the max // (should really be the smallest common denominator) for(struct_union_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) result=std::max(result, alignment(it->type(), ns)); return result; } else if(type.id()==ID_unsignedbv || type.id()==ID_signedbv || type.id()==ID_fixedbv || type.id()==ID_floatbv) { unsigned width=type.get_int(ID_width); return width%8?width/8+1:width/8; } else if(type.id()==ID_pointer) { unsigned width=config.ansi_c.pointer_width; return width%8?width/8+1:width/8; } else if(type.id()==ID_symbol) return alignment(ns.follow(type), ns); return 1; }
exprt c_sizeoft::sizeof_rec(const typet &type) { exprt dest; if(type.id()==ID_signedbv || type.id()==ID_unsignedbv || type.id()==ID_floatbv || type.id()==ID_fixedbv || type.id()==ID_c_enum || type.id()==ID_incomplete_c_enum) { // We round up to bytes. // See special treatment for bit-fields below. unsigned bits=type.get_int(ID_width); unsigned bytes=bits/8; if((bits%8)!=0) bytes++; dest=from_integer(bytes, size_type()); } else if(type.id()==ID_pointer) { // the following is an MS extension if(type.get_bool(ID_C_ptr32)) return from_integer(4, size_type()); unsigned bits=config.ansi_c.pointer_width; unsigned bytes=bits/8; if((bits%8)!=0) bytes++; dest=from_integer(bytes, size_type()); } else if(type.id()==ID_bool) { // We fit booleans into a byte. dest=from_integer(1, size_type()); } else if(type.id()==ID_array) { const exprt &size_expr= to_array_type(type).size(); if(size_expr.is_nil()) { // treated like an empty array dest=from_integer(0, size_type()); } else { exprt tmp_dest=sizeof_rec(type.subtype()); if(tmp_dest.is_nil()) return tmp_dest; mp_integer a, b; if(!to_integer(tmp_dest, a) && !to_integer(size_expr, b)) { dest=from_integer(a*b, size_type()); } else { dest.id(ID_mult); dest.type()=size_type(); dest.copy_to_operands(size_expr); dest.move_to_operands(tmp_dest); c_implicit_typecast(dest.op0(), dest.type(), ns); c_implicit_typecast(dest.op1(), dest.type(), ns); } } } else if(type.id()==ID_struct) { const struct_typet::componentst &components= to_struct_type(type).components(); dest=from_integer(0, size_type()); mp_integer bit_field_width=0; for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { const typet &sub_type=ns.follow(it->type()); if(it->get_bool(ID_is_type)) { } else if(sub_type.id()==ID_code) { } else if(it->get_is_bit_field()) { // this needs to be a signedbv/unsignedbv/enum if(sub_type.id()!=ID_signedbv && sub_type.id()!=ID_unsignedbv && sub_type.id()!=ID_c_enum) return nil_exprt(); // We just sum them up. // This assumes they are properly padded. bit_field_width+=sub_type.get_int(ID_width); } else { exprt tmp=sizeof_rec(sub_type); if(tmp.is_nil()) return tmp; dest=plus_exprt(dest, tmp); } } if(bit_field_width!=0) dest=plus_exprt(dest, from_integer(bit_field_width/8, size_type())); } else if(type.id()==ID_union) { const irept::subt &components= type.find(ID_components).get_sub(); mp_integer max_size=0; forall_irep(it, components) { if(it->get_bool(ID_is_type)) continue; const typet &sub_type=static_cast<const typet &>(it->find(ID_type)); if(sub_type.id()==ID_code) { } else { exprt tmp=sizeof_rec(sub_type); if(tmp.is_nil()) return tmp; simplify(tmp, ns); mp_integer tmp_int; if(to_integer(tmp, tmp_int)) return static_cast<const exprt &>(get_nil_irep()); if(tmp_int>max_size) max_size=tmp_int; } } dest=from_integer(max_size, size_type()); } else if(type.id()==ID_symbol)
c_typecastt::c_typet c_typecastt::get_c_type( const typet &type) { unsigned width=type.get_int(ID_width); if(type.id()==ID_signedbv) { if(width<=config.ansi_c.char_width) return CHAR; else if(width<=config.ansi_c.short_int_width) return SHORT; else if(width<=config.ansi_c.int_width) return INT; else if(width<=config.ansi_c.long_int_width) return LONG; else if(width<=config.ansi_c.long_long_int_width) return LONGLONG; else return LARGE_SIGNED_INT; } else if(type.id()==ID_unsignedbv) { if(type.get(ID_C_c_type)==ID_bool) return BOOL; if(width<=config.ansi_c.char_width) return UCHAR; else if(width<=config.ansi_c.short_int_width) return USHORT; else if(width<=config.ansi_c.int_width) return UINT; else if(width<=config.ansi_c.long_int_width) return ULONG; else if(width<=config.ansi_c.long_long_int_width) return ULONGLONG; else return LARGE_UNSIGNED_INT; } else if(type.id()==ID_bool) return BOOL; else if(type.id()==ID_floatbv || type.id()==ID_fixedbv) { if(width<=config.ansi_c.single_width) return SINGLE; else if(width<=config.ansi_c.double_width) return DOUBLE; else if(width<=config.ansi_c.long_double_width) return LONGDOUBLE; } else if(type.id()==ID_pointer) { if(type.subtype().id()==ID_empty) return VOIDPTR; else return PTR; } else if(type.id()==ID_array) { return PTR; } else if(type.id()==ID_c_enum || type.id()==ID_incomplete_c_enum) { return INT; } else if(type.id()==ID_symbol) return get_c_type(ns.follow(type)); else if(type.id()==ID_rational) return RATIONAL; else if(type.id()==ID_real) return REAL; else if(type.id()==ID_complex) return COMPLEX; return OTHER; }