void remove_function_pointerst::fix_return_type( code_function_callt &function_call, goto_programt &dest) { // are we returning anything at all? if(function_call.lhs().is_nil()) return; const code_typet &code_type= to_code_type(ns.follow(function_call.function().type())); // type already ok? if(type_eq( function_call.lhs().type(), code_type.return_type(), ns)) return; symbolt &tmp_symbol=new_tmp_symbol(); tmp_symbol.type=code_type.return_type(); tmp_symbol.location=function_call.location(); symbol_exprt tmp_symbol_expr; tmp_symbol_expr.type()=tmp_symbol.type; tmp_symbol_expr.set_identifier(tmp_symbol.name); exprt old_lhs=function_call.lhs(); function_call.lhs()=tmp_symbol_expr; goto_programt::targett t_assign=dest.add_instruction(); t_assign->make_assignment(); t_assign->code=code_assignt( old_lhs, typecast_exprt(tmp_symbol_expr, old_lhs.type())); }
void goto_convertt::convert_function_call( const code_function_callt &function_call, goto_programt &dest) { do_function_call( function_call.lhs(), function_call.function(), function_call.arguments(), dest); }
void remove_function_pointerst::fix_argument_types( code_function_callt &function_call) { const code_typet &code_type= to_code_type(ns.follow(function_call.function().type())); const code_typet::parameterst &function_parameters= code_type.parameters(); code_function_callt::argumentst &call_arguments= function_call.arguments(); for(unsigned i=0; i<function_parameters.size(); i++) { if(i<call_arguments.size()) { if(!type_eq(call_arguments[i].type(), function_parameters[i].type(), ns)) { call_arguments[i].make_typecast(function_parameters[i].type()); } } } }
std::string expr2javat::convert_code_function_call( const code_function_callt &src, unsigned indent) { if(src.operands().size()!=3) { unsigned precedence; return convert_norep(src, precedence); } std::string dest=indent_str(indent); if(src.lhs().is_not_nil()) { unsigned p; std::string lhs_str=convert(src.lhs(), p); // TODO: ggf. Klammern je nach p dest+=lhs_str; dest+='='; } const code_typet &code_type= to_code_type(src.function().type()); bool has_this=code_type.has_this() && !src.arguments().empty(); if(has_this) { unsigned p; std::string this_str=convert(src.arguments()[0], p); dest+=this_str; dest+=" . "; // extra spaces for readability } { unsigned p; std::string function_str=convert(src.function(), p); dest+=function_str; } dest+='('; const exprt::operandst &arguments=src.arguments(); bool first=true; forall_expr(it, arguments) { if(has_this && it==arguments.begin()) { } else { unsigned p; std::string arg_str=convert(*it, p); if(first) first=false; else dest+=", "; // TODO: ggf. Klammern je nach p dest+=arg_str; } } dest+=");"; return dest; }
void jsil_typecheckt::typecheck_function_call( code_function_callt &call) { if(call.operands().size()!=3) throw "function call expected to have three operands"; exprt &lhs=call.lhs(); typecheck_expr(lhs); exprt &f=call.function(); typecheck_expr(f); for(auto &arg : call.arguments()) typecheck_expr(arg); // Look for a function declaration symbol in the symbol table if(f.id()==ID_symbol) { const irep_idt &id=to_symbol_expr(f).get_identifier(); if(symbol_table.has_symbol(id)) { symbolt &s=symbol_table.lookup(id); if(s.type.id()==ID_code) { code_typet &codet=to_code_type(s.type); for(std::size_t i=0; i<codet.parameters().size(); i++) { if(i>=call.arguments().size()) break; const typet ¶m_type=codet.parameters()[i].type(); if(!param_type.id().empty() && param_type.is_not_nil()) { // check argument's type if parameter's type is given make_type_compatible(call.arguments()[i], param_type, true); } } // if there are too few arguments, add undefined if(codet.parameters().size()>call.arguments().size()) { for(std::size_t i=call.arguments().size(); i<codet.parameters().size(); ++i) call.arguments().push_back( exprt("undefined", jsil_undefined_type())); } // if there are too many arguments, remove while(codet.parameters().size()<call.arguments().size()) call.arguments().pop_back(); // check return type if exists if(!codet.return_type().id().empty() && codet.return_type().is_not_nil()) make_type_compatible(lhs, codet.return_type(), true); else make_type_compatible(lhs, jsil_any_type(), true); } else { // TODO: a symbol can be a variable evaluating to a string // which corresponds to a function identifier make_type_compatible(lhs, jsil_any_type(), true); } } else { // Should be function, declaration not found yet symbolt new_symbol; new_symbol.name=id; new_symbol.type=code_typet(); new_symbol.mode="jsil"; new_symbol.is_type=false; new_symbol.value=exprt("no-body-just-yet"); make_type_compatible(lhs, jsil_any_type(), true); if(symbol_table.add(new_symbol)) throw "failed to add expression symbol to symbol table"; } } else { // TODO: this might be a string literal // which corresponds to a function identifier make_type_compatible(lhs, jsil_any_type(), true); } }