예제 #1
0
/*--------------------------------------------------------------------
 * 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 );
}
예제 #2
0
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;
}
예제 #3
0
/*--------------------------------------------------------------------
 * 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);
        }
    }