// Both the if and then portion are call statements
bool IfConversionPass2::ConvertCallsIf(IfStatement* toConvert)
{
  Statement* thenPart = Denormalize(toConvert->get_then_part()) ;
  Statement* elsePart = Denormalize(toConvert->get_else_part()) ;

  CallStatement* thenCall = dynamic_cast<CallStatement*>(thenPart) ;
  CallStatement* elseCall = dynamic_cast<CallStatement*>(elsePart) ;

  assert(thenCall != NULL) ;
  assert(elseCall != NULL) ;

  CallStatement* boolSelectCall = 
    CreateBoolCall(thenCall->get_destination()) ;

  // Create call expression for each of the call statements
  //  and append them to the boolean select we are creating.

  Expression* thenCallValue = thenCall->get_callee_address() ;
  thenCall->set_callee_address(NULL) ;

  CallExpression* thenCallExp = 
    create_call_expression(theEnv,
			   thenCall->get_destination()->get_type()->get_base_type(),
			   thenCallValue) ;

  // Append all of the call arguments to the expression
  for (int i = 0 ; i < thenCall->get_argument_count() ; ++i)
  {
    Expression* nextArg = thenCall->get_argument(i) ;
    nextArg->set_parent(NULL) ;
    thenCallExp->append_argument(nextArg) ;
  }

  boolSelectCall->append_argument(thenCallExp) ;

  Expression* elseCallValue = elseCall->get_callee_address() ;
  elseCall->set_callee_address(NULL) ;
  CallExpression* elseCallExp =
    create_call_expression(theEnv,
			   thenCall->get_destination()->get_type()->get_base_type(),
			   elseCallValue) ;

  // Append all of the call arguments to the expression
  for (int i = 0 ; i < elseCall->get_argument_count() ; ++i)
  {
    Expression* nextArg = elseCall->get_argument(i) ;
    nextArg->set_parent(NULL) ;
    elseCallExp->append_argument(nextArg) ;
  }

  boolSelectCall->append_argument(elseCallExp) ;

  Expression* condition = toConvert->get_condition() ;
  toConvert->set_condition(NULL) ;
  boolSelectCall->append_argument(condition) ;

  toConvert->get_parent()->replace(toConvert, boolSelectCall) ;  
  return true ;
}
Beispiel #2
0
static
String handle_static_call_statement(CPrintStyleModule *state,
				    const SuifObject *obj)
{
  CallStatement *expr =
    to<CallStatement>(obj);
  String addr = state->print_to_string(expr->get_callee_address());
  String return_str;
  if (expr->get_destination() != NULL) {
    return_str += state->print_to_string(expr->get_destination());
    return_str += " = ";
  }

  return_str += String("(") + addr + ")(";
  bool needs_comma = false;
  for (Iter<Expression *> iter = expr->get_argument_iterator();
       iter.is_valid();
       iter.next()) {
    Expression *opn = iter.current();
    if (needs_comma) {
      return_str += ",";
    } else {
      needs_comma = true;
    }
    String op = state->print_to_string(opn);
    return_str += op;
  }
  return_str += ")";
  return(return_str);
}
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);
        }
    }