void bv_spect::from_type(const typet &type) { if(type.id()==ID_unsignedbv) is_signed=false; else if(type.id()==ID_signedbv) is_signed=true; else assert(0); width=unsafe_string2unsigned(type.get_string(ID_width)); }
inline static unsigned bv_width( const typet &type, const namespacet &ns) { if(type.id()==ID_c_enum_tag) { const typet &t=ns.follow_tag(to_c_enum_tag_type(type)); assert(t.id()==ID_c_enum); return bv_width(t.subtype(), ns); } return unsafe_string2unsigned(type.get_string(ID_width)); }
exprt boolbvt::bv_get_rec( const bvt &bv, const std::vector<bool> &unknown, std::size_t offset, const typet &type) const { if(type.id()==ID_symbol) return bv_get_rec(bv, unknown, offset, ns.follow(type)); std::size_t width=boolbv_width(type); assert(bv.size()==unknown.size()); assert(bv.size()>=offset+width); if(type.id()==ID_bool) { if(!unknown[offset]) { switch(prop.l_get(bv[offset]).get_value()) { case tvt::tv_enumt::TV_FALSE: return false_exprt(); case tvt::tv_enumt::TV_TRUE: return true_exprt(); default: return false_exprt(); // default } } return nil_exprt(); } bvtypet bvtype=get_bvtype(type); if(bvtype==IS_UNKNOWN) { if(type.id()==ID_array) { const typet &subtype=type.subtype(); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0) { exprt::operandst op; op.reserve(width/sub_width); for(std::size_t new_offset=0; new_offset<width; new_offset+=sub_width) { op.push_back( bv_get_rec(bv, unknown, offset+new_offset, subtype)); } exprt dest=exprt(ID_array, type); dest.operands().swap(op); return dest; } } else if(type.id()==ID_struct_tag) { return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_struct_tag_type(type))); } else if(type.id()==ID_union_tag) { return bv_get_rec(bv, unknown, offset, ns.follow_tag(to_union_tag_type(type))); } else if(type.id()==ID_struct) { const struct_typet &struct_type=to_struct_type(type); const struct_typet::componentst &components=struct_type.components(); std::size_t new_offset=0; exprt::operandst op; op.reserve(components.size()); for(struct_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { const typet &subtype=ns.follow(it->type()); op.push_back(nil_exprt()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0) { op.back()=bv_get_rec(bv, unknown, offset+new_offset, subtype); new_offset+=sub_width; } } struct_exprt dest(type); dest.operands().swap(op); return dest; } else if(type.id()==ID_union) { const union_typet &union_type=to_union_type(type); const union_typet::componentst &components=union_type.components(); assert(!components.empty()); // Any idea that's better than just returning the first component? std::size_t component_nr=0; union_exprt value(union_type); value.set_component_name( components[component_nr].get_name()); const typet &subtype=components[component_nr].type(); value.op()=bv_get_rec(bv, unknown, offset, subtype); return value; } else if(type.id()==ID_vector) { const typet &subtype=ns.follow(type.subtype()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0 && width%sub_width==0) { std::size_t size=width/sub_width; exprt value(ID_vector, type); value.operands().resize(size); for(std::size_t i=0; i<size; i++) value.operands()[i]= bv_get_rec(bv, unknown, i*sub_width, subtype); return value; } } else if(type.id()==ID_complex) { const typet &subtype=ns.follow(type.subtype()); std::size_t sub_width=boolbv_width(subtype); if(sub_width!=0 && width==sub_width*2) { exprt value(ID_complex, type); value.operands().resize(2); value.op0()=bv_get_rec(bv, unknown, 0*sub_width, subtype); value.op1()=bv_get_rec(bv, unknown, 1*sub_width, subtype); return value; } } } std::string value; for(std::size_t bit_nr=offset; bit_nr<offset+width; bit_nr++) { char ch; if(unknown[bit_nr]) ch='0'; else switch(prop.l_get(bv[bit_nr]).get_value()) { case tvt::tv_enumt::TV_FALSE: ch='0'; break; case tvt::tv_enumt::TV_TRUE: ch='1'; break; case tvt::tv_enumt::TV_UNKNOWN: ch='0'; break; default: assert(false); } value=ch+value; } switch(bvtype) { case IS_UNKNOWN: if(type.id()==ID_string) { mp_integer int_value=binary2integer(value, false); irep_idt s; if(int_value>=string_numbering.size()) s=irep_idt(); else s=string_numbering[int_value.to_long()]; return constant_exprt(s, type); } break; case IS_RANGE: { mp_integer int_value=binary2integer(value, false); mp_integer from=string2integer(type.get_string(ID_from)); constant_exprt value_expr(type); value_expr.set_value(integer2string(int_value+from)); return value_expr; } break; default: case IS_C_ENUM: constant_exprt value_expr(type); value_expr.set_value(value); return value_expr; } return nil_exprt(); }
std::string type2name(const typet &type) { std::string result; // qualifiers first if(type.get_bool(ID_C_constant)) result+="c"; if(type.get_bool(ID_C_restricted)) result+="r"; if(type.get_bool(ID_C_volatile)) result+="v"; if(type.id()==irep_idt()) throw "Empty type encountered."; else if(type.id()==ID_empty) result+="V"; else if(type.id()==ID_signedbv) result+="S" + type.get_string(ID_width); else if(type.id()==ID_unsignedbv) result+="U" + type.get_string(ID_width); else if(type.id()==ID_bool) result+="B"; else if(type.id()==ID_integer) result+="I"; else if(type.id()==ID_real) result+="R"; else if(type.id()==ID_complex) result+="C"; else if(type.id()==ID_floatbv) result+="F" + type.get_string(ID_width); else if(type.id()==ID_fixedbv) result+="X" + type.get_string(ID_width); else if(type.id()==ID_natural) result+="N"; else if(type.id()==ID_pointer) result+="*"; else if(type.id()==ID_reference) result+="&"; else if(type.id()==ID_code) { const code_typet &t=to_code_type(type); const code_typet::argumentst arguments=t.arguments(); result+="P("; for(code_typet::argumentst::const_iterator it=arguments.begin(); it!=arguments.end(); it++) { result+=type2name(it->type()); result+="'" + id2string(it->get_identifier()) + "'|"; } result.resize(result.size()-1); result+=")"; } else if(type.id()==ID_array) { const array_typet &t=to_array_type(type); if(t.size().is_nil()) result+="ARR?"; else result+="ARR"+t.size().get_string(ID_value); } else if(type.id()==ID_symbol) { result+="SYM#"+type.get_string(ID_identifier)+"#"; } else if(type.id()==ID_struct || type.id()==ID_union) { if(type.id()==ID_struct) result+="ST"; if(type.id()==ID_union) result+="UN"; const struct_union_typet &t=to_struct_union_type(type); const struct_union_typet::componentst &components = t.components(); result+="["; for(struct_union_typet::componentst::const_iterator it=components.begin(); it!=components.end(); it++) { if(it!=components.begin()) result+="|"; result+=type2name(it->type()); result+="'"+it->get_string(ID_name)+"'|"; } result+="]"; } else if(type.id()==ID_incomplete_struct) result +="ST?"; else if(type.id()==ID_incomplete_union) result +="UN?"; else if(type.id()==ID_c_enum) result +="EN"+type.get_string(ID_width); else if(type.id()==ID_incomplete_c_enum) result +="EN?"; else if(type.id()==ID_c_bitfield) result+="BF"+type.get_string(ID_size); else if(type.id()==ID_vector) result+="VEC"+type.get_string(ID_size); else throw (std::string("Unknown type '") + type.id_string() + "' encountered."); if(type.has_subtype()) { result+="{"; result+=type2name(type.subtype()); result+="}"; } if(type.has_subtypes()) { result+="$"; forall_subtypes(it, type) { result+=type2name(*it); result+="|"; }