void convert_integer_literal(
  const std::string &src,
  exprt &dest,
  unsigned base)
{
  bool is_unsigned=false;
  unsigned long_cnt=0;

  for(unsigned i=src.size(); i!=0; i--)
  {
    char ch=src[i-1];
    if(ch=='u' || ch=='U')
      is_unsigned=true;
    else if(ch=='l' || ch=='L')
      long_cnt++;
    else
      break;
  }

  mp_integer value;

  if(base==10)
  {
    dest.value(src);
    value=string2integer(src, 10);
  }
  else if(base==8)
  {
    dest.hex_or_oct(true);
    value=string2integer(src, 8);
  }
  else
  {
    dest.hex_or_oct(true);
    std::string without_prefix(src, 2, std::string::npos);
    value=string2integer(without_prefix, 16);
  }

  typet type;
  irep_idt cpp_type;

  if(is_unsigned)
    type=typet("unsignedbv");
  else
    type=typet("signedbv");

  if(long_cnt==0) {
    type.width(config.ansi_c.int_width);

    if(!is_unsigned)
      cpp_type="signed_int";
    else
      cpp_type="unsigned_int";

  } else if(long_cnt==1) {
    type.width(config.ansi_c.long_int_width);

    if(!is_unsigned)
      cpp_type="signed_long_int";
    else
      cpp_type="unsigned_long_int";

  } else {
    type.width(config.ansi_c.long_long_int_width);

    if(!is_unsigned)
      cpp_type="signed_long_long_int";
    else
      cpp_type="unsigned_long_long_int";
  }

  type.set("#cpp_type", cpp_type);

  dest=from_integer(value, type);

  dest.cformat(src);

}
Example #2
0
exprt convert_integer_literal(const std::string &src)
{
  bool is_unsigned=false, is_imaginary=false;
  unsigned long_cnt=0;
  unsigned width_suffix=0;
  unsigned base=10;
  
  for(unsigned i=0; i<src.size(); i++)
  {
    register char ch=src[i];

    if(ch=='u' || ch=='U')
      is_unsigned=true;
    else if(ch=='l' || ch=='L')
      long_cnt++;
    else if(ch=='i' || ch=='I')
    {
      // This can be "1i128" in MS mode,
      // and "10i" (imaginary) for GCC.
      // If it's followed by a number, we do MS mode.
      if((i+1)<src.size() && isdigit(src[i+1]))
        width_suffix=atoi(src.c_str()+i+1);
      else 
        is_imaginary=true;
    }
    else if(ch=='j' || ch=='J')
      is_imaginary=true;
  }

  mp_integer value;

  if(src.size()>=2 && src[0]=='0' && tolower(src[1])=='x')
  {
    // hex; strip "0x"
    base=16;
    std::string without_prefix(src, 2, std::string::npos);
    value=string2integer(without_prefix, 16);
  }
  else if(src.size()>=2 && src[0]=='0' && tolower(src[1])=='b')
  {
    // binary; strip "0x"
    // see http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html
    base=2;
    std::string without_prefix(src, 2, std::string::npos);
    value=string2integer(without_prefix, 2);
  }
  else if(src.size()>=2 && src[0]=='0')
  {
    // octal
    base=8;
    value=string2integer(src, 8);
  }
  else
  {
    // The default is base 10.
    value=string2integer(src, 10);
  }

  if(width_suffix!=0)
  {
    // this is a Microsoft extension
    irep_idt c_type;
    
    if(width_suffix<=config.ansi_c.int_width)
      c_type=is_unsigned?ID_unsigned_int:ID_signed_int;
    else if(width_suffix<=config.ansi_c.long_int_width)
      c_type=is_unsigned?ID_unsigned_long_int:ID_signed_long_int;
    else
      c_type=is_unsigned?ID_unsigned_long_long_int:ID_signed_long_long_int;

    typet type=typet(is_unsigned?ID_unsignedbv:ID_signedbv);
    type.set(ID_width, width_suffix);
    type.set(ID_C_c_type, c_type);

    exprt result=from_integer(value, type);
    result.set(ID_C_cformat, src);
    
    return result;    
  }
    
  mp_integer value_abs=value;

  if(value<0)
    value_abs.negate();

  bool is_hex_or_oct_or_bin=(base==8) || (base==16) || (base==2);
  
  #define FITS(width, signed) \
    ((signed?!is_unsigned:(is_unsigned || is_hex_or_oct_or_bin)) && \
    (power(2, signed?width-1:width)>value_abs))

  unsigned width;
  bool is_signed=false;
  irep_idt c_type;

  if(FITS(config.ansi_c.int_width, true) && long_cnt==0) // int
  {
    width=config.ansi_c.int_width;
    is_signed=true;
    c_type=ID_signed_int;
  }
  else if(FITS(config.ansi_c.int_width, false) && long_cnt==0) // unsigned int
  {
    width=config.ansi_c.int_width;
    is_signed=false;
    c_type=ID_unsigned_int;
  }
  else if(FITS(config.ansi_c.long_int_width, true) && long_cnt!=2) // long int
  {
    width=config.ansi_c.long_int_width;
    is_signed=true;
    c_type=ID_signed_long_int;
  }
  else if(FITS(config.ansi_c.long_int_width, false) && long_cnt!=2) // unsigned long int
  {
    width=config.ansi_c.long_int_width;
    is_signed=false;
    c_type=ID_unsigned_long_int;
  }
  else if(FITS(config.ansi_c.long_long_int_width, true)) // long long int
  {
    width=config.ansi_c.long_long_int_width;
    is_signed=true;
    c_type=ID_signed_long_long_int;
  }
  else if(FITS(config.ansi_c.long_long_int_width, false)) // unsigned long long int
  {
    width=config.ansi_c.long_long_int_width;
    is_signed=false;
    c_type=ID_unsigned_long_long_int;
  }
  else
  {
    // Way too large. Should consider issuing a warning.
    width=config.ansi_c.long_long_int_width;

    if(is_unsigned)
    {
      is_signed=false;
      c_type=ID_unsigned_long_long_int;
    }
    else
      c_type=ID_signed_long_long_int;
  }
  
  typet type=typet(is_signed?ID_signedbv:ID_unsignedbv);

  type.set(ID_width, width);  
  type.set(ID_C_c_type, c_type);

  exprt result;

  if(is_imaginary)
  {
    complex_typet complex_type;
    complex_type.subtype()=type;
    result=exprt(ID_complex, complex_type);
    result.operands().resize(2);
    result.op0()=gen_zero(type);
    result.op1()=from_integer(value, type);
  }
  else
  {
    result=from_integer(value, type);
    result.set(ID_C_cformat, src);
  }

  return result;
}
Example #3
0
exprt convert_integer_literal(
  const std::string &src,
  unsigned base)
{
  bool is_unsigned=false;
  unsigned long_cnt=0;
  unsigned width_suffix=0;
  
  for(unsigned i=0; i<src.size(); i++)
  {
    register char ch=src[i];

    if(ch=='u' || ch=='U')
      is_unsigned=true;
    else if(ch=='l' || ch=='L')
      long_cnt++;
    else if(ch=='i' || ch=='I')
      width_suffix=atoi(src.c_str()+i+1);
  }

  mp_integer value;
  
  if(base==10)
  {
    value=string2integer(src, 10);
  }
  else if(base==8)
  {
    value=string2integer(src, 8);
  }
  else if(base==16)
  {
    std::string without_prefix(src, 2, std::string::npos);
    value=string2integer(without_prefix, 16);
  }
  else
    assert(false);

  if(width_suffix!=0)
  {
    // this is a Microsoft extension
    typet type=typet(is_unsigned?ID_unsignedbv:ID_signedbv);
    type.set(ID_width, width_suffix);

    exprt result=from_integer(value, type);
    result.set(ID_C_cformat, src);
    return result;    
  }
    
  mp_integer value_abs=value;

  if(value<0)
    value_abs.negate();

  unsigned min_width=config.ansi_c.int_width;
  
  if(long_cnt==1)
    min_width=config.ansi_c.long_int_width;
  else if(long_cnt>=2)
    min_width=config.ansi_c.long_long_int_width;

  bool is_hex_or_oct=(base==8) || (base==16);
  
  #define FITS(width, signed) \
    ((signed?!is_unsigned:(is_unsigned || is_hex_or_oct)) && \
    (width>=min_width) && \
    (power(2, signed?width-1:width)>value_abs))

  unsigned width;
  bool is_signed=false;

  if(FITS(config.ansi_c.int_width, true)) // int
  {
    width=config.ansi_c.int_width;
    is_signed=true;
  }
  else if(FITS(config.ansi_c.int_width, false)) // unsigned int
  {
    width=config.ansi_c.int_width;
    is_signed=false;
  }
  else if(FITS(config.ansi_c.long_int_width, true)) // long int
  {
    width=config.ansi_c.long_int_width;
    is_signed=true;
  }
  else if(FITS(config.ansi_c.long_int_width, false)) // unsigned long int
  {
    width=config.ansi_c.long_int_width;
    is_signed=false;
  }
  else if(FITS(config.ansi_c.long_long_int_width, true)) // long long int
  {
    width=config.ansi_c.long_long_int_width;
    is_signed=true;
  }
  else if(FITS(config.ansi_c.long_long_int_width, false)) // unsigned long long int
  {
    width=config.ansi_c.long_long_int_width;
    is_signed=false;
  }
  else
  {
    // way too large
    width=config.ansi_c.long_long_int_width;
  }
  
  typet type=typet(is_signed?ID_signedbv:ID_unsignedbv);

  type.set(ID_width, width);  

  exprt result=from_integer(value, type);
  result.set(ID_C_cformat, src);
  
  return result;
}