本文整理汇总了C++中goto_programt::destructive_insert方法的典型用法代码示例。如果您正苦于以下问题:C++ goto_programt::destructive_insert方法的具体用法?C++ goto_programt::destructive_insert怎么用?C++ goto_programt::destructive_insert使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类goto_programt
的用法示例。
在下文中一共展示了goto_programt::destructive_insert方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: remove_virtual_function
//.........这里部分代码省略.........
functions.begin()->symbol_expr;
return;
}
// the final target is a skip
goto_programt final_skip;
goto_programt::targett t_final=final_skip.add_instruction();
t_final->source_location=vcall_source_loc;
t_final->make_skip();
// build the calls and gotos
goto_programt new_code_calls;
goto_programt new_code_gotos;
exprt this_expr=code.arguments()[0];
// If necessary, cast to the last candidate function to
// get the object's clsid. By the structure of get_functions,
// this is the parent of all other classes under consideration.
const auto &base_classid=functions.back().class_id;
const auto &base_function_symbol=functions.back().symbol_expr;
symbol_typet suggested_type(base_classid);
exprt c_id2=get_class_identifier_field(this_expr, suggested_type, ns);
std::map<irep_idt, goto_programt::targett> calls;
// Note backwards iteration, to get the least-derived candidate first.
for(auto it=functions.crbegin(), itend=functions.crend(); it!=itend; ++it)
{
const auto &fun=*it;
auto insertit=calls.insert(
{fun.symbol_expr.get_identifier(), goto_programt::targett()});
// Only create one call sequence per possible target:
if(insertit.second)
{
goto_programt::targett t1=new_code_calls.add_instruction();
t1->source_location=vcall_source_loc;
if(!fun.symbol_expr.get_identifier().empty())
{
// call function
t1->make_function_call(code);
auto &newcall=to_code_function_call(t1->code);
newcall.function()=fun.symbol_expr;
pointer_typet need_type(symbol_typet(fun.symbol_expr.get(ID_C_class)));
if(!type_eq(newcall.arguments()[0].type(), need_type, ns))
newcall.arguments()[0].make_typecast(need_type);
}
else
{
// No definition for this type; shouldn't be possible...
t1->make_assertion(false_exprt());
}
insertit.first->second=t1;
// goto final
goto_programt::targett t3=new_code_calls.add_instruction();
t3->source_location=vcall_source_loc;
t3->make_goto(t_final, true_exprt());
}
// If this calls the base function we just fall through.
// Otherwise branch to the right call:
if(fun.symbol_expr!=base_function_symbol)
{
exprt c_id1=constant_exprt(fun.class_id, string_typet());
goto_programt::targett t4=new_code_gotos.add_instruction();
t4->source_location=vcall_source_loc;
t4->make_goto(insertit.first->second, equal_exprt(c_id1, c_id2));
}
}
goto_programt new_code;
// patch them all together
new_code.destructive_append(new_code_gotos);
new_code.destructive_append(new_code_calls);
new_code.destructive_append(final_skip);
// set locations
Forall_goto_program_instructions(it, new_code)
{
const irep_idt property_class=it->source_location.get_property_class();
const irep_idt comment=it->source_location.get_comment();
it->source_location=target->source_location;
it->function=target->function;
if(!property_class.empty())
it->source_location.set_property_class(property_class);
if(!comment.empty())
it->source_location.set_comment(comment);
}
goto_programt::targett next_target=target;
next_target++;
goto_program.destructive_insert(next_target, new_code);
// finally, kill original invocation
target->make_skip();
}
示例2: remove_virtual_function
void remove_virtual_functionst::remove_virtual_function(
goto_programt &goto_program,
goto_programt::targett target)
{
const code_function_callt &code=
to_code_function_call(target->code);
const exprt &function=code.function();
assert(function.id()==ID_virtual_function);
assert(!code.arguments().empty());
functionst functions;
get_functions(function, functions);
if(functions.empty())
{
target->make_skip();
return; // give up
}
// only one option?
if(functions.size()==1)
{
assert(target->is_function_call());
to_code_function_call(target->code).function()=
functions.begin()->symbol_expr;
return;
}
// the final target is a skip
goto_programt final_skip;
goto_programt::targett t_final=final_skip.add_instruction();
t_final->make_skip();
// build the calls and gotos
goto_programt new_code_calls;
goto_programt new_code_gotos;
for(functionst::const_iterator
it=functions.begin();
it!=functions.end();
it++)
{
// call function
goto_programt::targett t1=new_code_calls.add_instruction();
t1->make_function_call(code);
to_code_function_call(t1->code).function()=it->symbol_expr;
// goto final
goto_programt::targett t3=new_code_calls.add_instruction();
t3->make_goto(t_final, true_exprt());
exprt this_expr=code.arguments()[0];
if(this_expr.type().id()!=ID_pointer ||
this_expr.type().id()!=ID_struct)
{
symbol_typet symbol_type(it->class_id);
this_expr=typecast_exprt(this_expr, pointer_typet(symbol_type));
}
exprt deref=dereference_exprt(this_expr, this_expr.type().subtype());
exprt c_id1=constant_exprt(it->class_id, string_typet());
exprt c_id2=build_class_identifier(deref);
goto_programt::targett t4=new_code_gotos.add_instruction();
t4->make_goto(t1, equal_exprt(c_id1, c_id2));
}
goto_programt new_code;
// patch them all together
new_code.destructive_append(new_code_gotos);
new_code.destructive_append(new_code_calls);
new_code.destructive_append(final_skip);
// set locations
Forall_goto_program_instructions(it, new_code)
{
const irep_idt property_class=it->source_location.get_property_class();
const irep_idt comment=it->source_location.get_comment();
it->source_location=target->source_location;
it->function=target->function;
if(!property_class.empty()) it->source_location.set_property_class(property_class);
if(!comment.empty()) it->source_location.set_comment(comment);
}
goto_programt::targett next_target=target;
next_target++;
goto_program.destructive_insert(next_target, new_code);
// finally, kill original invocation
target->make_skip();
}