예제 #1
0
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));
}
예제 #2
0
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));
}
예제 #3
0
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();
}
예제 #4
0
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+="|";      
    }