void ansi_c_convertt::convert_expr(exprt &expr) { if(expr.id()==ID_sideeffect) { const irep_idt &statement=expr.get(ID_statement); if(statement==ID_statement_expression) { assert(expr.operands().size()==1); convert_code(to_code(expr.op0())); return; // done } } Forall_operands(it, expr) convert_expr(*it); if(expr.id()==ID_symbol) { expr.remove(ID_C_id_class); expr.remove(ID_C_base_name); } else if(expr.id()==ID_sizeof) { if(expr.operands().size()==0) { typet &type=static_cast<typet &>(expr.add(ID_type_arg)); convert_type(type); } } else if(expr.id()==ID_designated_initializer) { exprt &designator=static_cast<exprt &>(expr.add(ID_designator)); convert_expr(designator); } else if(expr.id()==ID_alignof) { if(expr.operands().size()==0) { typet &type=static_cast<typet &>(expr.add(ID_type_arg)); convert_type(type); } } else if(expr.id()==ID_gcc_builtin_va_arg) { convert_type(expr.type()); } else if(expr.id()==ID_generic_selection) { assert(expr.operands().size()==1); irept::subt &generic_associations= expr.add(ID_generic_associations).get_sub(); Forall_irep(it, generic_associations) { convert_expr(static_cast<exprt &>(it->add(ID_value))); convert_type(static_cast<typet &>(it->add(ID_type_arg))); }
void cvc_convt::convert_expr(const exprt &expr) { const exprt::operandst &op=expr.operands(); if(expr.id()==ID_implies) { if(op.size()!=2) throw "implication takes two operands"; out << "("; convert_expr(op[0]); out << ") => ("; convert_expr(op[1]); out << ")"; } else if(expr.id()==ID_constraint_select_one) { if(op.size()<2) throw "constraint_select_one takes at least two operands"; // TODO throw "cvc_convt::convert_expr needs constraint_select_one"; } else if(expr.id()==ID_or || expr.id()==ID_and || expr.id()==ID_xor || expr.id()==ID_nor || expr.id()==ID_nand) { if(op.empty()) throw "operator `"+expr.id_string()+"' takes at least one operand"; else if(op.size()==1) convert_expr(op[0]); else { forall_expr(it, op) { if(it!=op.begin()) { if(expr.id()==ID_or) out << " OR "; else if(expr.id()==ID_nor) out << " NOR "; else if(expr.id()==ID_and) out << " AND "; else if(expr.id()==ID_nand) out << " NAND "; else if(expr.id()==ID_xor) out << " XOR "; else assert(false); } out << "("; convert_expr(*it); out << ")"; } } } else if(expr.id()==ID_not)
void cvc_convt::convert_array_index(const exprt &expr) { if(expr.type()==gen_array_index_type()) { convert_expr(expr); } else { exprt tmp(ID_typecast, gen_array_index_type()); tmp.copy_to_operands(expr); convert_expr(tmp); } }
void ansi_c_convertt::convert_declaration(ansi_c_declarationt &declaration) { c_storage_spect c_storage_spec; convert_type(declaration.type(), c_storage_spec); declaration.set_is_inline(c_storage_spec.is_inline); declaration.set_is_static(c_storage_spec.is_static); declaration.set_is_extern(c_storage_spec.is_extern); declaration.set_is_thread_local(c_storage_spec.is_thread_local); declaration.set_is_register(c_storage_spec.is_register); // do not overwrite is_typedef -- it's done by the parser // typedefs are macros if(declaration.get_is_typedef()) declaration.set_is_macro(true); if(declaration.value().is_not_nil()) { if(declaration.value().type().id()==ID_code) convert_code(to_code(declaration.value())); else convert_expr(declaration.value()); } }
void cvc_convt::convert_as_bv(const exprt &expr) { if(expr.type().id()==ID_bool) { if(expr.is_true()) out << "0bin1"; else if(expr.is_false()) out << "0bin0"; else { out << "IF "; convert_expr(expr); out << " THEN 0bin1 ELSE 0bin0 ENDIF"; } } else convert_expr(expr); }
literalt cvc_convt::convert(const exprt &expr) { //out << "%% E: " << expr << std::endl; if(expr.type().id()!=ID_bool) { std::string msg="cvc_convt::convert got " "non-boolean expression: "; msg+=expr.pretty(); throw msg; } // Three special cases in which we don't need to generate // a handle. if(expr.is_true()) return const_literal(true); else if(expr.is_false()) return const_literal(false); else if(expr.id()==ID_literal) return to_literal_expr(expr).get_literal(); // Generate new handle literalt l(no_boolean_variables, false); no_boolean_variables++; find_symbols(expr); // define new handle out << "ASSERT "; convert_literal(l); out << " <=> ("; convert_expr(expr); out << ");" << std::endl << std::endl; return l; }
void cvc_convt::convert_address_of_rec(const exprt &expr) { if(expr.id()==ID_symbol || expr.id()==ID_constant || expr.id()==ID_string_constant) { out << "(# object:=" << pointer_logic.add_object(expr) << ", offset:=" << bin_zero(config.ansi_c.pointer_width) << " #)"; } else if(expr.id()==ID_index) { if(expr.operands().size()!=2) throw "index takes two operands"; const exprt &array=expr.op0(); const exprt &index=expr.op1(); if(index.is_zero()) { if(array.type().id()==ID_pointer) convert_expr(array); else if(array.type().id()==ID_array) convert_address_of_rec(array); else assert(false); } else { out << "(LET P: "; out << cvc_pointer_type(); out << " = "; if(array.type().id()==ID_pointer) convert_expr(array); else if(array.type().id()==ID_array) convert_address_of_rec(array); else assert(false); out << " IN P WITH .offset:=BVPLUS(" << config.ansi_c.pointer_width << ", P.offset, "; convert_expr(index); out << "))"; } } else if(expr.id()==ID_member) { if(expr.operands().size()!=1) throw "member takes one operand"; const exprt &struct_op=expr.op0(); out << "(LET P: "; out << cvc_pointer_type(); out << " = "; convert_address_of_rec(struct_op); const irep_idt &component_name= to_member_expr(expr).get_component_name(); mp_integer offset=member_offset( to_struct_type(struct_op.type()), component_name, ns); typet index_type(ID_unsignedbv); index_type.set(ID_width, config.ansi_c.pointer_width); exprt index=from_integer(offset, index_type); out << " IN P WITH .offset:=BVPLUS(" << config.ansi_c.pointer_width << ", P.offset, "; convert_expr(index); out << "))"; } else throw "don't know how to take address of: "+expr.id_string(); }