Statement* c_for_statement_walker::dismantle_c_for_statement(CForStatement *the_for){
    StatementList *replacement = create_statement_list(the_for->get_suif_env());
    StatementList *body  = create_statement_list(the_for->get_suif_env());
    Statement* original_body = the_for->get_body();
    the_for->set_body(0);
    body->append_statement(original_body);
    the_for->set_body(body);
    Statement* pre_pad = the_for->get_pre_pad();
    CodeLabelSymbol* break_lab = the_for->get_break_label();
    CodeLabelSymbol* continue_lab = the_for->get_continue_label();
    Statement* before = the_for->get_before();
    Expression* test = the_for->get_test();
    Statement* step = the_for->get_step();;

    if(before)remove_suif_object(before);
    if(test)remove_suif_object(test);
    if(step)remove_suif_object(step);
    if(body)remove_suif_object(body);
    if(pre_pad)remove_suif_object(pre_pad);
    the_for->set_break_label(0);
    the_for->set_continue_label(0);

    // I am guessing what pre-pad and post-pad do
    if (before)
	replacement->append_statement(before);
    
    // and loop if not out of range
    replacement->append_statement(
	create_label_location_statement(the_for->get_suif_env(), continue_lab));

    if(test) {
	    SuifEnv *env = the_for->get_suif_env();
	    DataType *bool_type = get_type_builder(env)->get_boolean_type();
	    test = create_unary_expression(env,bool_type,k_logical_not,test);
	    replacement->append_statement(create_branch_statement(env,test,break_lab));
	}

    if(pre_pad){
        replacement->append_statement(pre_pad);
    }

    append_flattened(replacement,body);
    append_flattened(replacement,step);
    replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_lab));
    replacement->append_statement(
        create_label_location_statement(body->get_suif_env(), break_lab));
    // end of loop

    the_for->get_parent()->replace(the_for, replacement);
    return replacement;
}
void NormalizeProcedureReturns::
do_procedure_definition( ProcedureDefinition *pd ) {
  ProcedureSymbol *ps = pd->get_procedure_symbol();
  if (!ps) return;
  ProcedureType *t = to<ProcedureType>(ps->get_type());
  if (!is_kind_of<CProcedureType>(t))
    return;
  CProcedureType *ct = to<CProcedureType>(t);
  DataType *result = ct->get_result_type();
  bool is_void = is_kind_of<VoidType>(result);

  for (Iter<ReturnStatement> iter = object_iterator<ReturnStatement>(pd);
       iter.is_valid(); iter.next()) {
    ReturnStatement *ret = &iter.current();
    if (ret == NULL) continue;
    
    Expression *ret_expr = ret->get_return_value();

    if (is_void) {
      if (ret_expr != NULL) {
	// Should not be here
	trash_it(remove_suif_object(ret_expr));
      }
    } else {
      if (ret_expr == NULL) {
	// build a NULL expression to match the DataType.
	Expression *x = build_empty_expression(result);
	ret->set_return_value(x);
      }
    }
  }
}
Statement* multi_way_branch_statement_walker::dismantle_multi_way_branch_statement(MultiWayBranchStatement *the_case){
    StatementList *replacement = create_statement_list(the_case->get_suif_env());

    Expression *operand = the_case->get_decision_operand ();
    remove_suif_object(operand);

    DataType *type = operand->get_result_type();

    CodeLabelSymbol *default_lab =  the_case->get_default_target();
    the_case->set_default_target(0);
    Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator();
    while (iter.is_valid()) {
	MultiWayBranchStatement::case_pair pair = iter.current();
	IInteger value = pair.first;
	CodeLabelSymbol *lab = pair.second;
	IntConstant *exp = create_int_constant(the_case->get_suif_env(),type, value);
//	Expression *exp = create_load_constant_expression(get_env(),type,iconst);
	TypeBuilder *type_builder = (TypeBuilder *)
          the_case->get_suif_env()->get_object_factory(TypeBuilder::get_class_name());
	Expression *compare =  
	  create_binary_expression(the_case->get_suif_env(),type_builder->get_boolean_type(),
				   k_is_equal_to,
				   deep_suif_clone(operand),
				   exp);
	replacement->append_statement(create_branch_statement(the_case->get_suif_env(),compare,lab));
	iter.next();
	}
    delete operand;
    replacement->append_statement(create_jump_statement(the_case->get_suif_env(),default_lab));
    the_case->get_parent()->replace(the_case,replacement);
    return replacement;
}
Walker::ApplyStatus multi_way_branch_statement_compactor::operator () (SuifObject *x)
    {
    MultiWayBranchStatement *the_case = to<MultiWayBranchStatement>(x);

    // is the table already compact?

    if (is_compact(the_case))
       return Walker::Continue;

    SymbolTable *scope = find_scope(x);
    if (!scope)
	return Walker::Continue;

    CodeLabelSymbol *default_lab =  the_case->get_default_target();

    // very special case - the case list is empty, so just jump to the default label

    if (the_case->get_case_count() == 0) {
	Statement *replacement = create_jump_statement(get_env(),default_lab);
	the_case->get_parent()->replace(the_case,replacement);
    	set_address(replacement);
    	return Walker::Replaced;
	}

    StatementList *replacement = create_statement_list(get_env());

    Expression *operand = the_case->get_decision_operand ();

    remove_suif_object(operand);

    DataType *type = operand->get_result_type();
    VariableSymbol *decision = create_variable_symbol(get_env(),get_type_builder(get_env())->get_qualified_type(type));
    scope->add_symbol(decision);

    replacement->append_statement(create_store_variable_statement(get_env(),decision,operand));

    the_case->set_default_target(0);
    MultiWayGroupList jump_list(get_env(),default_lab,decision);;
    
    Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator();
    while (iter.is_valid()) {
	MultiWayBranchStatement::case_pair pair = iter.current();
	jump_list.add_element(pair.first,pair.second);
	iter.next();
	}
    // we have built the new structure, now need to generate code for it

    jump_list.generate_code(replacement);
    
    the_case->get_parent()->replace(the_case,replacement);
    set_address(replacement);
    return Walker::Replaced;
    }
Statement *do_while_statement_walker::dismantle_do_while_statement(DoWhileStatement *the_do_while){
    Statement *result = 0;

    Expression *condition = the_do_while->get_condition();

    // we are going to reuse the condition so we must remove it
    // from the if statement first to avoid ownership conflicts

    remove_suif_object(condition);

    Statement *body = the_do_while->get_body();
    CodeLabelSymbol *break_label = the_do_while->get_break_label();
    CodeLabelSymbol *continue_label = the_do_while->get_continue_label();

    // likewise of these parts - remove from if.

    the_do_while->set_body(0);
    remove_suif_object(body);
    the_do_while->set_break_label(0);
    the_do_while->set_continue_label(0);

    if (body != 0) {
        StatementList *replacement = create_statement_list(body->get_suif_env());
        result = replacement;
        suif_assert(continue_label != 0);
        replacement-> append_statement(create_label_location_statement(body->get_suif_env(), continue_label));
	replacement->append_statement(body);
        replacement-> append_statement(create_branch_statement(body->get_suif_env(),
                                                 condition, continue_label));
        suif_assert(break_label != 0);
        replacement-> append_statement(create_label_location_statement(body->get_suif_env(), break_label));
        }

    the_do_while->get_parent()->replace(the_do_while,result);
    return result;
}
Esempio n. 6
0
void GCSymbolTablePass::execute(void)
{
  // Let's try a little optimization.
  // we'll do GC like the trash_it routine.
  // walk through all of the owned objects in the program.
  // for the non-symbols, walk through their sub-objects and
  // find any referenced symbols
  // throw away any that are not needed.
  FileSetBlock *fsb = get_suif_env()->get_file_set_block();
  if (fsb == NULL) return;

  static LString k_trash = "trash";
  // remove the trash annote.  we'll replace it later
  Annote *trash_annote = fsb->take_annote(k_trash);


  suif_hash_map<SymbolTableObject*,bool> referenced_map;
  suif_list<SymbolTableObject*> live_symbols;

  // Now we have a map of Object->parent object
  // We need another one for object -> referenced
  for (Iter<SuifObject> all_iter1 = object_iterator<SuifObject>(fsb);
       all_iter1.is_valid(); all_iter1.next()) {
    SuifObject *obj = &all_iter1.current();

    // for the ownership links of symbols:
    if (is_kind_of<SymbolTable>(obj)) continue;

    if (is_kind_of<SymbolTableObject>(obj)) {
      SymbolTableObject *sym = to<SymbolTableObject>(obj);
      //sym->print_to_default();

      if (referenced_map.find(sym) == referenced_map.end()) {
	//fprintf(stderr, "Found unreferenced Symbol:");
	// referenced_map[sym] = false;
	referenced_map.enter_value(sym, false);
      }
      // we will check these later.
      continue;
    }

    for (Iter<SymbolTableObject> ref_iter = 
	   suif_object_ref_iterator<SymbolTableObject>(obj, 
					    SuifObject::get_class_name());
	 ref_iter.is_valid(); ref_iter.next()) {
      SymbolTableObject *sym_ref = &ref_iter.current();
      
      suif_hash_map<SymbolTableObject*,bool>::iterator find =
	referenced_map.find(sym_ref);
      if (find == referenced_map.end()
	  || (*find).second == false) {
	//fprintf(stderr, "Found Symbol Reference:");
	//sym_ref->print_to_default();
	//referenced_map[sym_ref] = true;
	referenced_map.enter_value(sym_ref, true);
	live_symbols.push_back(sym_ref);
      }
    }
  }

  // Now we have to do a worklist algorithm with the live symbols.
  // any symbol they own or reference must also be live
  while (!live_symbols.empty()) {
    SymbolTableObject *obj = live_symbols.back();
    live_symbols.pop_back();
    // Implicit assumption:
    // it will NEVER OWN another symbol.
    // If it did, we just need to use the object_instance_iterator
    // to add these.
    
    // Everything it references is live.
    for (Iter<SymbolTableObject> ref_iter = 
	   suif_object_ref_iterator<SymbolTableObject>(obj, 
					    SuifObject::get_class_name());
	 ref_iter.is_valid(); ref_iter.next()) {
      SymbolTableObject *sym_ref = &ref_iter.current();
      
      suif_hash_map<SymbolTableObject*,bool>::iterator find =
	referenced_map.find(sym_ref);
      if (find == referenced_map.end()
	  || (*find).second == false) {
	//fprintf(stderr, "Found Symbol reference:");
	//sym_ref->print_to_default();
	// referenced_map[sym_ref] = true;
	referenced_map.enter_value(sym_ref, true);
	live_symbols.push_back(sym_ref);
      }
    }
  }

  if (trash_annote != NULL)
    fsb->append_annote(trash_annote);


  // walk over all of the reference
  // and delete or put back
  for (suif_hash_map<SymbolTableObject*, bool>::iterator obj_iter = 
	 referenced_map.begin();
       obj_iter != referenced_map.end(); obj_iter++) {
    bool is_referenced = (*obj_iter).second;
    if (!is_referenced) {
      SymbolTableObject *sym = (*obj_iter).first;
      //fprintf(stderr, "Trashing unused symbol:");
      //sym->print_to_default();
      SymbolTable *st = sym->get_symbol_table();
      if (st != NULL) {
	if (sym->get_name() != emptyLString) {
	  st->remove_all_from_lookup_table(sym);
	}
	st->remove_symbol_table_object(sym);
      }
      remove_suif_object(sym);
      trash_it(_suif_env, sym);
      //      delete sym;
    }
  }
  //  SuifGC::collect(_suif_env->get_file_set_block());
}
Statement* if_statement_walker::dismantle_if_statement(IfStatement* the_if){
    Statement *result = 0;
    ProcedureDefinition* proc_def = get_procedure_definition(the_if);

    Expression *condition = the_if->get_condition();
    // we are going to reuse the condition so we must remove it
    // from the if statement first to avoid ownership conflicts

    remove_suif_object(condition);
    //    the_if->set_condition(SourceOp());
    //    remove_source_op(condition);

    Statement *then_part = the_if->get_then_part();
    Statement *else_part = the_if->get_else_part();

    // likewise of these parts - remove from if.

    the_if->set_then_part(0);
    the_if->set_else_part(0);
    remove_suif_object(then_part);
    remove_suif_object(else_part);

    if (then_part != 0) {
    StatementList *replacement = create_statement_list( the_if->get_suif_env() );
	result = replacement;
    UnaryExpression* negated_condition = 
    create_unary_expression( the_if->get_suif_env(),
			      condition->get_result_type(),
			      k_logical_not,
			      condition );
	if (else_part != 0) {
	    CodeLabelSymbol *else_label = new_anonymous_label(proc_def->get_symbol_table());
	    CodeLabelSymbol *done_label = new_anonymous_label(proc_def->get_symbol_table());
	    replacement->append_statement(create_branch_statement(the_if->get_suif_env(),
                                                 negated_condition, else_label));
	    replacement->append_statement(then_part);
	    replacement->append_statement(create_jump_statement(the_if->get_suif_env(),done_label));
	    replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), else_label));
	    replacement->append_statement(else_part);
	    replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), done_label));
	    }
	else {
            CodeLabelSymbol *done_label = create_new_label(get_procedure_definition(the_if));
            replacement-> append_statement(create_branch_statement(the_if->get_suif_env(),
                                                 negated_condition, done_label));
            replacement->append_statement(then_part);
            replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label));
	    }
	}
    else {
	if (else_part != 0)
	    {
	    StatementList *replacement = create_statement_list(the_if->get_suif_env());
	    result = replacement;
       	    CodeLabelSymbol *done_label = create_new_label(proc_def);
            replacement->append_statement(create_branch_statement(the_if->get_suif_env(), condition, done_label));
            replacement->append_statement(else_part);
            replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label));
	    }
	else
	    {
	    EvalStatement *replacement = create_eval_statement(the_if->get_suif_env());
	    result = replacement;
	    replacement->append_expression(condition);
	    }
	}

    the_if->get_parent()->replace(the_if, result);
    return result;
}
Statement *for_statement_walker::dismantle_for_statement(ForStatement *the_for){
    StatementList *replacement = create_statement_list(the_for->get_suif_env());
    VariableSymbol*  index = the_for->get_index();
    DataType *type = unqualify_data_type(index->get_type());
    Expression *lower = the_for->get_lower_bound();
    Expression *upper = the_for->get_upper_bound();
    Expression *step = the_for->get_step();
    LString compare_op = the_for->get_comparison_opcode();
    Statement* body =  the_for->get_body();
    Statement* pre_pad = the_for->get_pre_pad();
//    Statement* post_pad = the_for->get_post_pad();
    CodeLabelSymbol* break_lab = the_for->get_break_label();
    CodeLabelSymbol* continue_lab = the_for->get_continue_label();
    the_for->set_index(0);
    remove_suif_object(lower);
    remove_suif_object(upper);
    remove_suif_object(step);
    remove_suif_object(body);
    remove_suif_object(pre_pad);
//    the_for->set_post_pad(0);
//    remove_suif_object(post_pad);
    the_for->set_break_label(0);
    the_for->set_continue_label(0);

    // I am guessing what pre-pad and post-pad do

    if(pre_pad != 0)replacement->append_statement(pre_pad);

    // initialize the index. Is this right? should we ever initialize to upper, for -ve steps?
    // Is index guaranteed not to be changed? Should we be creating a temporary?

    replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,lower));

    replacement->append_statement(create_label_location_statement(body->get_suif_env(), continue_lab));

    if (body != 0)
	replacement->append_statement(body);

    // increment the counter

    Expression *index_expr = 
      create_load_variable_expression(body->get_suif_env(),
				      unqualify_data_type(index->get_type()),
				      index);
    Expression *increment = 
      create_binary_expression(body->get_suif_env(),type,k_add,
			       index_expr,step);

    replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,increment));

    // and loop if not out of range

    Expression *compare =  
      create_binary_expression(body->get_suif_env(),type,
			       compare_op,
			       deep_suif_clone<Expression>(index_expr),
			       deep_suif_clone<Expression>(step));
    replacement->append_statement(create_branch_statement(body->get_suif_env(),compare,continue_lab));

    // end of loop

    replacement->append_statement(create_label_location_statement(body->get_suif_env(),break_lab));
//    if(post_pad != 0)replacement->append_statement(post_pad);
    the_for->get_parent()->replace(the_for,replacement);
    return replacement;
}
void EliminateArrayConvertsPass::do_procedure_definition(ProcedureDefinition* proc_def){
    suif_hash_map<ParameterSymbol*, Type*> params;
    TypeBuilder *tb = (TypeBuilder*)
         get_suif_env()->get_object_factory(TypeBuilder::get_class_name());

    // collect all procedure parameters of pointer type into params list
    for(Iter<ParameterSymbol*> iter = proc_def->get_formal_parameter_iterator();
        iter.is_valid(); iter.next())
    {
        ParameterSymbol* par_sym = iter.current();
        Type* par_type = tb->unqualify_type(par_sym->get_type());

        if(is_kind_of<PointerType>(par_type)){
            // put NULLs into the map at first,
            // they will later be overwritten
            params[par_sym] = NULL;
        }
    }
    if(params.size()==0) return;    // nothing to do
    
    // walk thru all AREs and look for arrays that are in the param list
    {for(Iter<ArrayReferenceExpression> iter =
        object_iterator<ArrayReferenceExpression>(proc_def);
            iter.is_valid(); iter.next())
        {
            ArrayReferenceExpression* are = &iter.current();
            if(is_kind_of<UnaryExpression>(are->get_base_array_address())){
                UnaryExpression* ue = to<UnaryExpression>(are->get_base_array_address());
                if(ue->get_opcode() == k_convert){
                    if(is_kind_of<LoadVariableExpression>(ue->get_source())){
                        LoadVariableExpression* lve = 
                            to<LoadVariableExpression>(ue->get_source());
                        VariableSymbol* array = lve->get_source();
            
                        for(suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.begin();
                            iter!=params.end();iter++)
                        {
                            ParameterSymbol* par_sym = (*iter).first;
                            if(par_sym == array){
                                // match!
                                Type* array_type;
                                suif_hash_map<ParameterSymbol*, Type*>::iterator iter =
                                    params.find(par_sym);
                                
                                if(iter==params.end() || (*iter).second==NULL){
                                    //array_type = to<PointerType>(ue->get_result_type())->get_reference_type();
                                    array_type = tb->get_qualified_type(ue->get_result_type());
                                    params[par_sym] = array_type;
                                    //printf("%s has type ",par_sym->get_name().c_str());
                                    //array_type->print_to_default();
                                }else{
                                    array_type = params[par_sym].second;
                                    suif_assert(is_kind_of<QualifiedType>(array_type));
                                }

                                array->replace(array->get_type(), array_type);
                                remove_suif_object(ue);
                                remove_suif_object(lve);
                                lve->replace(lve->get_result_type(), tb->unqualify_type(array_type));
                                // put the LoadVar directly under ARE
                                are->set_base_array_address(lve);
                                //are->print_to_default();
                            }
                        }
                    } else {
                        suif_warning(ue->get_source(),
                            ("Expecting a LoadVariableExpression here"));
                    }
                } else {
                    suif_warning(ue, ("Disallow converts in AREs for "
                            "things other than procedure parameters"));
                }
            }
        }
    }
}
Esempio n. 10
0
/**
    Remove all the array types collected by all the calls
    to array_type2multi_array_type.
    \see array_type2multi_array_type
*/
void OneDimArrayConverter::remove_all_one_dim_array_types(){
    for (int j=0;j < (int)all_array_types->size();j++)
    {
        remove_suif_object((*all_array_types)[j]);
    }
}
Esempio n. 11
0
/**
    Convert ArrayReferenceExpression \a top_array to a 
    MultiDimArrayExpression.
*/
void OneDimArrayConverter::
convert_array_expr2multi_array_expr(ArrayReferenceExpression* top_array){
    Expression* expr = top_array;
    unsigned int i = 0;

    suif_vector<Expression*> lower_bounds;
    suif_vector<Expression*> upper_bounds;
    list<Expression*> indices;
    IInteger bit_size, bit_alignment;
    suif_vector<ArrayReferenceExpression *> exprs;

    do{
        ArrayReferenceExpression* are = to<ArrayReferenceExpression>(expr);
        expr = are->get_base_array_address();
        exprs.push_back(are);
	} while(is_kind_of<ArrayReferenceExpression>(expr));

    // collect bounds and indeces
    for (unsigned int exp_ind = 0; exp_ind < exprs.size();exp_ind++)
    {
        ArrayReferenceExpression* are = exprs[exp_ind];
        DataType* type = are->get_base_array_address()->get_result_type();
        ArrayType* array_type;

		if(is_kind_of<ArrayType>(type)){
			array_type = to<ArrayType>(type);
		}else{
			array_type = to<ArrayType>(
				unwrap_ptr_ref_type(type)->get_base_type());
		}
        
        bit_size = array_type->get_element_type()->
                get_base_type()->get_bit_size();
        bit_alignment = array_type->get_element_type()->
                get_base_type()->get_bit_alignment();

        // What happens to ArrayType?? Does it become garbage?
        suif_assert(array_type->get_lower_bound());
        suif_assert(array_type->get_upper_bound());

        // clone bounds and add to the lists
        lower_bounds.push_back(array_type->get_lower_bound());
        upper_bounds.push_back(array_type->get_upper_bound());
        // save the index
        Expression* index = are->get_index();
        remove_suif_object(index); index->set_parent(NULL);
        indices.push_back(index);

        suif_assert(upper_bounds[i]);
        suif_assert(lower_bounds[i]);
        suif_assert(indices[i]);

        i++;
	}

    // Build the offset for the expression. We have to traverse upwards to do this
    Expression *top_expr_base = exprs[exprs.size()-1]->get_base_array_address();
    
	DataType* top_expr_base_type = top_expr_base->get_result_type();
	ArrayType* top_array_type;
	if(is_kind_of<ArrayType>(top_expr_base_type)){
		top_array_type = to<ArrayType>(top_expr_base_type);
	}else{
		top_array_type = to<ArrayType>(tb->unqualify_data_type(unwrap_ptr_ref_type(
			top_expr_base_type)));
	}
    
	Expression* inc    = create_int_constant(suif_env, 1);
    Expression* offset = create_int_constant(suif_env, 0);
    suif_vector<Expression *> elements;

    for (unsigned int ind = 0;ind < lower_bounds.size(); ind ++)
    {
        Expression *lower = lower_bounds[ind];
        Expression *upper = upper_bounds[ind];

        offset = 
            build_dyadic_expression(k_add, 
                offset,
                build_dyadic_expression(
                    k_multiply, 
                    deep_suif_clone(inc),
                    deep_suif_clone(lower)));
        
        Expression *element =
                    build_dyadic_expression(k_add, 
                        build_dyadic_expression(k_subtract,
                            deep_suif_clone(upper), 
                            deep_suif_clone(lower)),
                        create_int_constant(suif_env,1));

        inc = build_dyadic_expression(k_multiply, 
            inc, 
            deep_suif_clone(element));

	    elements.push_back(element);
    }
    // Now, inc and offset are ready

    // retrieve the multi-type
    MultiDimArrayType* multi_type;
	suif_map<ArrayType*, MultiDimArrayType*>::iterator type_iter =
	    type_map->find(top_array_type);
#ifdef CONVERT_TYPES
    suif_assert_message((type_iter != type_map->end()),
        ("Array type never translated"));
#else
    if(type_iter == type_map->end()){
        multi_type = array_type2multi_array_type(top_array_type);
    }else
#endif //CONVERT_TYPES
    multi_type = (*type_iter).second;

    remove_suif_object(top_expr_base);

    // add a convert to the necessary type
    top_expr_base = create_unary_expression(suif_env, 
            tb->get_pointer_type(multi_type), 
            k_convert, top_expr_base);
    //top_expr_base->print_to_default();

    // construct the expression to be returned 
    MultiDimArrayExpression* mae =
        create_multi_dim_array_expression(suif_env,
            top_array->get_result_type(), 
            top_expr_base, 
            offset);

    // now when we have the expression, set the indices
    for (list<Expression*>::iterator ind_iter = indices.begin();
        ind_iter!=indices.end(); ind_iter++)
    {
        Expression* index = *ind_iter;
        //printf("%p \t", index);index->print_to_default();
        mae->append_index(index);
    }

    for (suif_vector<Expression *>::iterator eiter = elements.begin();
        eiter != elements.end(); eiter ++)
    {
        Expression* element = *eiter;
        mae->append_element(element);
    }

    replace_expression(top_array, mae);
}