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; } }