void add_failed_symbol(symbolt &symbol, symbol_tablet &symbol_table) { if(!symbol.is_lvalue) return; if(symbol.type.get(ID_C_failed_symbol)!="") return; if(symbol.type.id()==ID_pointer) { symbolt new_symbol; new_symbol.is_lvalue=true; new_symbol.module=symbol.module; new_symbol.mode=symbol.mode; new_symbol.base_name=failed_symbol_id(symbol.base_name); new_symbol.name=failed_symbol_id(symbol.name); new_symbol.type=symbol.type.subtype(); new_symbol.value.make_nil(); new_symbol.type.set(ID_C_is_failed_symbol, true); symbol.type.set(ID_C_failed_symbol, new_symbol.name); if(new_symbol.type.id()==ID_pointer) add_failed_symbol(new_symbol, symbol_table); // recursive call symbol_table.move(new_symbol); } }
code_function_callt function_to_call( symbol_tablet &symbol_table, const irep_idt &id, const irep_idt &argument) { // already there? symbol_tablet::symbolst::const_iterator s_it= symbol_table.symbols.find(id); if(s_it==symbol_table.symbols.end()) { // not there pointer_typet p(char_type()); p.subtype().set(ID_C_constant, true); code_typet function_type; function_type.return_type()=empty_typet(); function_type.parameters().push_back( code_typet::parametert(p)); symbolt new_symbol; new_symbol.name=id; new_symbol.base_name=id; new_symbol.type=function_type; symbol_table.move(new_symbol); s_it=symbol_table.symbols.find(id); assert(s_it!=symbol_table.symbols.end()); } // signature is expected to be // (type *) -> ... if(s_it->second.type.id()!=ID_code || to_code_type(s_it->second.type).parameters().size()!=1 || to_code_type(s_it->second.type).parameters()[0].type().id()!=ID_pointer) { std::string error="function `"+id2string(id)+"' has wrong signature"; throw error; } string_constantt function_id_string(argument); code_function_callt call; call.lhs().make_nil(); call.function()= symbol_exprt(s_it->second.name, s_it->second.type); call.arguments().resize(1); call.arguments()[0]= typecast_exprt( address_of_exprt( index_exprt( function_id_string, from_integer(0, index_type()))), to_code_type(s_it->second.type).parameters()[0].type()); return call; }
symbol_exprt add_stack_depth_symbol(symbol_tablet &symbol_table) { const irep_idt identifier="$stack_depth"; signedbv_typet type(sizeof(int)*8); symbolt new_symbol; new_symbol.name=identifier; new_symbol.base_name=identifier; new_symbol.pretty_name=identifier; new_symbol.type=type; new_symbol.is_static_lifetime=true; new_symbol.value=from_integer(0, type); new_symbol.mode=ID_C; new_symbol.is_thread_local=true; new_symbol.is_lvalue=true; symbol_table.move(new_symbol); return symbol_exprt(identifier, type); }
bool java_entry_point( symbol_tablet &symbol_table, const irep_idt &main_class, message_handlert &message_handler) { // check if the entry point is already there if(symbol_table.symbols.find(goto_functionst::entry_point())!= symbol_table.symbols.end()) return false; // silently ignore messaget message(message_handler); symbolt symbol; // main function symbol // find main symbol if(config.main!="") { // Add java:: prefix std::string main_identifier="java::"+config.main; symbol_tablet::symbolst::const_iterator s_it; // Does it have a type signature? (':' suffix) if(config.main.rfind(':')==std::string::npos) { std::string prefix=main_identifier+':'; std::set<irep_idt> matches; for(const auto & s : symbol_table.symbols) if(has_prefix(id2string(s.first), prefix) && s.second.type.id()==ID_code) matches.insert(s.first); if(matches.empty()) { message.error() << "main symbol `" << config.main << "' not found" << messaget::eom; return true; } else if(matches.size()==1) { s_it=symbol_table.symbols.find(*matches.begin()); assert(s_it!=symbol_table.symbols.end()); } else { message.error() << "main symbol `" << config.main << "' is ambiguous:\n"; for(const auto & s : matches) message.error() << " " << s << '\n'; message.error() << messaget::eom; return true; } } else { // just look it up s_it=symbol_table.symbols.find(main_identifier); if(s_it==symbol_table.symbols.end()) { message.error() << "main symbol `" << config.main << "' not found" << messaget::eom; return true; } } // function symbol symbol=s_it->second; if(symbol.type.id()!=ID_code) { message.error() << "main symbol `" << config.main << "' not a function" << messaget::eom; return true; } // check if it has a body if(symbol.value.is_nil()) { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; return true; } } else { // no function given, we look for the main class assert(config.main==""); // are we given a main class? if(main_class.empty()) return false; // silently ignore std::string entry_method= id2string(main_class)+".main"; std::string prefix="java::"+entry_method+":"; // look it up std::set<irep_idt> matches; for(symbol_tablet::symbolst::const_iterator s_it=symbol_table.symbols.begin(); s_it!=symbol_table.symbols.end(); s_it++) { if(s_it->second.type.id()==ID_code && has_prefix(id2string(s_it->first), prefix)) matches.insert(s_it->first); } if(matches.empty()) { // Not found, silently ignore return false; } if(matches.size()>=2) { message.error() << "main method in `" << main_class << "' is ambiguous" << messaget::eom; return true; // give up with error, no main } // function symbol symbol=symbol_table.symbols.find(*matches.begin())->second; // check if it has a body if(symbol.value.is_nil()) { message.error() << "main method `" << main_class << "' has no body" << messaget::eom; return true; // give up with error } } assert(!symbol.value.is_nil()); assert(symbol.type.id()==ID_code); const code_typet &code_type=to_code_type(symbol.type); create_initialize(symbol_table); if(java_static_lifetime_init(symbol_table, symbol.location, message_handler)) return true; code_blockt init_code; // build call to initialization function { symbol_tablet::symbolst::iterator init_it= symbol_table.symbols.find(INITIALIZE); if(init_it==symbol_table.symbols.end()) { message.error() << "failed to find " INITIALIZE " symbol" << messaget::eom; return true; // give up with error } code_function_callt call_init; call_init.lhs().make_nil(); call_init.add_source_location()=symbol.location; call_init.function()=init_it->second.symbol_expr(); init_code.move_to_operands(call_init); } // build call to the main method code_function_callt call_main; call_main.add_source_location()=symbol.location; call_main.function()=symbol.symbol_expr(); const code_typet::parameterst ¶meters= code_type.parameters(); exprt::operandst main_arguments; main_arguments.resize(parameters.size()); for(std::size_t param_number=0; param_number<parameters.size(); param_number++) { bool is_this=param_number==0 && parameters[param_number].get_this(); bool allow_null=config.main!="" && !is_this; main_arguments[param_number]= object_factory(parameters[param_number].type(), init_code, allow_null, symbol_table); } call_main.arguments()=main_arguments; init_code.move_to_operands(call_main); // add "main" symbolt new_symbol; code_typet main_type; main_type.return_type()=empty_typet(); new_symbol.name=goto_functionst::entry_point(); new_symbol.type.swap(main_type); new_symbol.value.swap(init_code); new_symbol.mode=ID_java; if(symbol_table.move(new_symbol)) { message.error() << "failed to move main symbol" << messaget::eom; return true; } return false; }
bool java_entry_point( symbol_tablet &symbol_table, const irep_idt &main_class, message_handlert &message_handler, bool assume_init_pointers_not_null, size_t max_nondet_array_length) { // check if the entry point is already there if(symbol_table.symbols.find(goto_functionst::entry_point())!= symbol_table.symbols.end()) return false; // silently ignore messaget message(message_handler); main_function_resultt res= get_main_symbol(symbol_table, main_class, message_handler); if(res.stop_convert) return res.stop_convert; symbolt symbol=res.main_function; assert(!symbol.value.is_nil()); assert(symbol.type.id()==ID_code); create_initialize(symbol_table); if(java_static_lifetime_init( symbol_table, symbol.location, message_handler, assume_init_pointers_not_null, max_nondet_array_length)) return true; code_blockt init_code; // build call to initialization function { symbol_tablet::symbolst::iterator init_it= symbol_table.symbols.find(INITIALIZE); if(init_it==symbol_table.symbols.end()) { message.error() << "failed to find " INITIALIZE " symbol" << messaget::eom; return true; // give up with error } code_function_callt call_init; call_init.lhs().make_nil(); call_init.add_source_location()=symbol.location; call_init.function()=init_it->second.symbol_expr(); init_code.move_to_operands(call_init); } // build call to the main method code_function_callt call_main; source_locationt loc=symbol.location; loc.set_function(symbol.name); source_locationt &dloc=loc; call_main.add_source_location()=dloc; call_main.function()=symbol.symbol_expr(); call_main.function().add_source_location()=dloc; if(to_code_type(symbol.type).return_type()!=empty_typet()) { auxiliary_symbolt return_symbol; return_symbol.mode=ID_C; return_symbol.is_static_lifetime=false; return_symbol.name="return'"; return_symbol.base_name="return"; return_symbol.type=to_code_type(symbol.type).return_type(); symbol_table.add(return_symbol); call_main.lhs()=return_symbol.symbol_expr(); } exprt::operandst main_arguments= java_build_arguments( symbol, init_code, symbol_table, assume_init_pointers_not_null, max_nondet_array_length, message_handler); call_main.arguments()=main_arguments; init_code.move_to_operands(call_main); java_record_outputs(symbol, main_arguments, init_code, symbol_table); // add "main" symbolt new_symbol; code_typet main_type; main_type.return_type()=empty_typet(); new_symbol.name=goto_functionst::entry_point(); new_symbol.type.swap(main_type); new_symbol.value.swap(init_code); new_symbol.mode=ID_java; if(symbol_table.move(new_symbol)) { message.error() << "failed to move main symbol" << messaget::eom; return true; } return false; }