/*-------------------------------------------------------------------- * src_viewer::build_stree */ void src_viewer::build_stree() { /* create a new src tree */ stree = new code_tree; stree->set_map_fn((map_tn_fn) &map_tree_node, this); stree->id = new source_id( current_file_block, current_file_name ); stree_cache->push_back( stree ); post_progress(this, "Loading source file ...", 0); /* create link to source */ DefinitionBlock *def_block = current_file_block->get_definition_block(); int count = def_block->get_procedure_definition_count(); for ( int i = 0 ; i<count; i++ ) { ProcedureDefinition *proc = def_block->get_procedure_definition(i); ExecutionObject* body = proc->get_body(); if ( body ) { stree->build( proc ); } post_progress( this, "Loading SUIF procedures..", ((float) (i+1))/count*100); } unpost_progress( this ); }
ProcedureDefinition* NodeBuilder::new_proc_defn1(LString name, DataType* return_type, ParameterSymbol* arg) { list<QualifiedType*> argtypes; argtypes.push_back(to<QualifiedType>(arg->get_type())); CProcedureType *cproctype = _type_builder->get_c_procedure_type(return_type, argtypes); ProcedureSymbol* psym = create_procedure_symbol(_suif_env, cproctype, name); _symtab->add_symbol(psym); ProcedureDefinition* pdfn = create_procedure_definition(_suif_env, psym, 0, create_basic_symbol_table(_suif_env, _symtab), 0); pdfn->append_formal_parameter(arg); psym->set_definition(pdfn); return pdfn; }
/*-------------------------------------------------------------------- * output_viewer::print_output * */ bool output_viewer::print_output(String file) { const char* filename = file.c_str(); post_progress(this, "Loading output file ...", 0); text->clear(); FILE *fd = fopen( filename, "r" ); if (!fd) { text->fout() << "Cannot open file " << filename << endl; text->update(); unpost_progress( this ); return false; } /* read the file */ fseek(fd, 0, SEEK_END); long length = ftell(fd); fseek(fd, 0, SEEK_SET); char *buffer = new char[length]; int l = fread(buffer, 1, length, fd); buffer[l] = 0; fclose(fd); int current_line = 1; int current_src_line = -1; bool new_src_line = false; bool parse_error = false; int scope = 0; scope_node *current_scope = 0; int state = NORMAL_STATE; erase_mappings(); // erase previous mappings char *next_line; char *current_src_file = 0; for (char *line = buffer; line; line = next_line) { next_line = strchr(line, '\n'); if (next_line) { *next_line++ = 0; } /* * Preprocess C */ bool found_line_num; char *ppc = preprocess_c(line, state, current_src_file, current_src_line, found_line_num); /* * Scan for "{" and "}" to determine current scope. */ for (char *p = ppc; *p; p++) { if (*p == '{') { if (scope == 0) { current_scope = new scope_node; current_scope->first_line = current_line; current_scope->proc = 0; proc_scopes->push_back(current_scope); } scope++; } else if (*p == '}') { scope--; if (scope < 0) { parse_error = true; } if (scope == 0) { current_scope->last_line = current_line; } } } delete (ppc); /* Check if current line has line number annotation */ if (found_line_num) { new_src_line = true; continue; // don't print it out } /* * Record the line, if nec. */ if (new_src_line) { /* enter this line as a node */ output_node *node = new output_node(current_src_line, current_src_file, current_line); if (current_scope) { current_scope->nodes.push_back(node); /* match current scope to procedure */ if (current_scope->proc == 0) { SuifObject *tn = map_line_to_tree_node( find_file_block(String(current_src_file)), current_src_line); if (tn) { current_scope->proc = get_procedure_definition( tn ); } } } new_src_line = false; } /* print the line out */ text->fout() << line << endl; current_line++; } delete (buffer); text->update(); if (scope != 0 || parse_error) { display_message(this, "Warning: unable to parse the file `%s'.", filename); } if ( proc_scopes->empty()) { display_message(this, "Warning: cannot find line number information in " "the file `%s'.", filename); unpost_progress( this ); return false; } /* * Get the file set entry of this file */ if (!current_fse) { if ( current_src_file ) { current_fse = find_file_block(current_src_file); } if (!current_fse) { display_message(this, "Warning: cannot find the corresponding file set entry."); unpost_progress(this); return false; } } /* * Create new output tree */ delete outtree; outtree = new code_tree; outtree->set_map_fn( (map_tn_fn) &map_tree_node, this ); // iterate over the procedures DefinitionBlock *def_block = current_fse->get_definition_block(); int num_procs = def_block->get_procedure_definition_count(); for (int i = 0; i < num_procs; ++i) { ProcedureDefinition *proc = def_block->get_procedure_definition(i); ExecutionObject *body = proc->get_body(); if ( body ) { outtree->build( proc ); } post_progress(this, "Loading output file..", ((float) (i+1))/num_procs*100); } /* create tags */ outtree->create_tags(text); unpost_progress(this); return true; }
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); } }