示例#1
0
void c_typecastt::implicit_typecast_arithmetic(
  exprt &expr,
  c_typet c_type)
{
  typet new_type;
  
  const typet &expr_type=ns.follow(expr.type());
  
  switch(c_type)
  {
  case PTR:
    if(expr_type.id()==ID_array)
    {
      new_type.id(ID_pointer);
      new_type.subtype()=expr_type.subtype();
      break;
    }
    return;

  case BOOL:       new_type=bool_typet(); break;
  case CHAR:       assert(false); // should always be promoted to int
  case UCHAR:      assert(false); // should always be promoted to int
  case SHORT:      assert(false); // should always be promoted to int
  case USHORT:     assert(false); // should always be promoted to int
  case INT:        new_type=int_type(); break;
  case UINT:       new_type=uint_type(); break;
  case LONG:       new_type=long_int_type(); break;
  case ULONG:      new_type=long_uint_type(); break;
  case LONGLONG:   new_type=long_long_int_type(); break;
  case ULONGLONG:  new_type=long_long_uint_type(); break;
  case SINGLE:     new_type=float_type(); break;
  case DOUBLE:     new_type=double_type(); break;
  case LONGDOUBLE: new_type=long_double_type(); break;
  case RATIONAL:   new_type=rational_typet(); break;
  case REAL:       new_type=real_typet(); break;
  case INTEGER:    new_type=integer_typet(); break;
  case COMPLEX: return; // do nothing
  default: return;
  }

  if(new_type!=expr_type)
  {
    if(new_type.id()==ID_pointer &&
       expr_type.id()==ID_array)
    {
      exprt index_expr(ID_index, expr_type.subtype());
      index_expr.reserve_operands(2);
      index_expr.move_to_operands(expr);
      index_expr.copy_to_operands(gen_zero(index_type()));
      expr=exprt(ID_address_of, new_type);
      expr.move_to_operands(index_expr);
    }
    else
      do_typecast(expr, new_type);
  }
}
void printf_formattert::process_format(std::ostream &out)
{
  exprt tmp;
  format_constantt format_constant;

  format_constant.precision=6;
  format_constant.min_width=0;
  format_constant.zero_padding=false;

  char ch=next();

  if(ch=='0') // leading zeros
  {
    format_constant.zero_padding=true;
    ch=next();
  }

  while(isdigit(ch)) // width
  {
    format_constant.min_width*=10;
    format_constant.min_width+=ch-'0';
    ch=next();
  }

  if(ch=='.') // precision
  {
    format_constant.precision=0;
    ch=next();

    while(isdigit(ch))
    {
      format_constant.precision*=10;
      format_constant.precision+=ch-'0';
      ch=next();
    }
  }

  switch(ch)
  {
  case '%':
    out << ch;
    break;

  case 'f':
  case 'F':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), double_type()));
    break;

  case 'g':
  case 'G':
    if(format_constant.precision==0) format_constant.precision=1;
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), double_type()));
    break;

  case 's':
    {
      if(next_operand==operands.end()) break;
      // this is the address of a string
      const exprt &op=*(next_operand++);
      if(op.id()==ID_address_of &&
         op.operands().size()==1 &&
         op.op0().id()==ID_index &&
         op.op0().operands().size()==2 &&
         op.op0().op0().id()==ID_string_constant)
        out << format_constant(op.op0().op0());
    }
    break;

  case 'd':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), int_type()));
    break;

  case 'D':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), long_int_type()));
    break;

  case 'u':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), uint_type()));
    break;

  case 'U':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), long_uint_type()));
    break;

  default:
    out << '%' << ch;
  }
}