void add_to_procedure_list(list<ProcedureSymbol*> *&procs, SymbolTable *table, bool flag_def_only) { assert( table ); assert( procs ); Iter<SymbolTableObject*> symbols_iter = table->get_symbol_table_object_iterator(); for ( ; symbols_iter.is_valid(); symbols_iter.next() ) { SymbolTableObject* s = symbols_iter.current(); if (s && s->isKindOf(ProcedureSymbol::get_class_name())) { ProcedureSymbol* sym = to<ProcedureSymbol>(s); if (flag_def_only && sym->get_definition() == 0) continue; // insert sorted const char *proc_name = sym->get_name().c_str(); //list<ProcedureSymbol*>::iterator it = procs->begin(); unsigned i; for (i = 0; i < procs->size(); ++i) { if (strcmp((*procs)[i]->get_name().c_str(), proc_name) > 0) break; } if (i == procs->size()) { procs->push_back(sym); } else { procs->insert(i-1, sym); } } } }
void DismantleStructuredReturns::do_file_set_block( FileSetBlock* file_set_block ) { suif_map<CProcedureType *,QualifiedType *> type_map; list<ArrayReferenceExpression*> ref_exprs; SuifEnv *env = 0; TypeBuilder *tb = 0; VoidType *vt = 0; for (Iter<ProcedureSymbol> iter = object_iterator<ProcedureSymbol>(file_set_block); iter.is_valid(); iter.next()) { ProcedureSymbol *sym = &iter.current(); Type *type = sym->get_type(); if (!is_kind_of<CProcedureType>(type)) continue; CProcedureType *cp_type = to<CProcedureType>(type); type = cp_type->get_result_type(); if (!env) { env = type->get_suif_env(); tb = (TypeBuilder*) env->get_object_factory(TypeBuilder::get_class_name()); vt = tb->get_void_type(); } suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); QualifiedType *qtype; if (t_iter == type_map.end()) { if (!is_kind_of<GroupType>(type) && !is_kind_of<ArrayType>(type)) continue; qtype = tb->get_qualified_type( tb->get_pointer_type(to<DataType>(type))); cp_type->set_result_type(vt); cp_type->insert_argument(0,qtype); type_map.enter_value(cp_type,qtype); } else { qtype = (*t_iter).second; } ProcedureDefinition *def = sym->get_definition(); if (!def) continue; ParameterSymbol *par = create_parameter_symbol(env,qtype); def->get_symbol_table()->append_symbol_table_object(par); def->insert_formal_parameter(0,par); // Convert all returns into assigned and returns for (Iter<ReturnStatement> ret_iter = object_iterator<ReturnStatement>(def->get_body()); ret_iter.is_valid(); ret_iter.next()) { ReturnStatement *ret = &ret_iter.current(); Expression *retval = ret->get_return_value(); ret->set_return_value(0); retval->set_parent(0); insert_statement_before(ret, create_store_statement(env,retval,create_var_use(par))); } } // Change all calls to the new form for (Iter<CallStatement> cs_iter = object_iterator<CallStatement>(file_set_block); cs_iter.is_valid(); cs_iter.next()) { CallStatement *call = &cs_iter.current(); Type *type = call->get_callee_address()->get_result_type(); Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type()); if (!is_kind_of<PointerType>(p_type)) continue; p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type()); if (!is_kind_of<CProcedureType>(p_type)) continue; CProcedureType *cp_type = to<CProcedureType>(p_type); suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); if (t_iter == type_map.end()) continue; QualifiedType *qtype = (*t_iter).second; DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type()) ->get_reference_type())); VariableSymbol *var = new_anonymous_variable(env,call,tb->get_qualified_type(var_type)); Expression *exp = create_symbol_address_expression( env, tb->get_pointer_type(var_type), var); call->insert_argument(0,exp); call->set_destination(0); } for (Iter<CallExpression> ce_iter = object_iterator<CallExpression>(file_set_block); ce_iter.is_valid(); ce_iter.next()) { CallExpression *call = &ce_iter.current(); Type *type = call->get_callee_address()->get_result_type(); Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type()); if (!is_kind_of<PointerType>(p_type)) continue; p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type()); if (!is_kind_of<CProcedureType>(p_type)) continue; CProcedureType *cp_type = to<CProcedureType>(p_type); ; suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); if (t_iter == type_map.end()) continue; QualifiedType *qtype = (*t_iter).second; DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type()) ->get_reference_type())); VariableSymbol *var = new_anonymous_variable(env,call,tb->get_qualified_type(var_type)); Expression *exp = create_symbol_address_expression( env, tb->get_pointer_type(var_type), var); call->insert_argument(0,exp); Statement *loc = get_expression_owner(call); call->get_parent()->replace(call,create_var_use(var)); call->set_parent(0); suif_assert(vt != 0); call->set_result_type(vt); EvalStatement *es = create_eval_statement(env); insert_statement_before(loc,es); // Would be better to turn this into a call statement es->append_expression(call); } }