source: translator/Tuples/MultRet.cc @ a0d9f94

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since a0d9f94 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

initial commit

  • Property mode set to 100644
File size: 4.5 KB
Line 
1#include <list>
2#include <vector>
3#include <cassert>
4#include <algorithm>
5
6#include "MultRet.h"
7#include "SynTree/Statement.h"
8#include "SynTree/Expression.h"
9#include "SynTree/Declaration.h"
10#include "SynTree/Type.h"
11
12namespace Tuples {
13
14  MVRMutator::MVRMutator() : newVars( 0 ), newCode( 0 )
15  {
16  }
17
18  MVRMutator::~MVRMutator()
19  {
20  }
21
22  int MVRMutator::curVal = 0;
23
24  Statement *MVRMutator::mutate( ExprStmt *exprStmt ){
25    MVRMutator toplevel;
26    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), toplevel ) );
27
28    if ( toplevel.hasCode() ) {
29      assert ( toplevel.getVars() != 0 );
30
31      typedef std::list<Statement *> Statements;
32
33      CompoundStmt *code = new CompoundStmt( std::list< Label >() );
34
35      // copy variables
36      Statements &vars = toplevel.getVars()->get_kids();
37      for( Statements::iterator i = vars.begin(); i != vars.end(); i++ )
38        code->get_kids().push_back( *i );
39
40      // copy statements
41      Statements &block = toplevel.getCode()->get_kids();
42      for( Statements::iterator i = block.begin(); i != block.end(); i++ )
43        code->get_kids().push_back( *i );
44
45      return code;
46    } else
47      return exprStmt;
48  }
49
50
51  Expression *MVRMutator::mutate( ApplicationExpr *appExpr )
52  {
53    // appExpr->set_function(  maybeMutate( appExpr->get_function(), *this ) );
54    bool mulretp = false;
55    VariableExpr *funname;
56    if ( (funname = dynamic_cast<VariableExpr *>(appExpr->get_function())) == 0 ) goto DoArgs;
57
58    FunctionDecl *fundecl;
59    if ((fundecl = dynamic_cast<FunctionDecl *>(funname->get_var())) == 0) goto DoArgs;
60
61    {
62      typedef std::list<DeclarationWithType*> RetType;
63
64      RetType &rets = fundecl->get_functionType()->get_returnVals();
65      if ( rets.size() <= 1 ) goto DoArgs;
66      mulretp = true;
67
68      if( newVars == 0 )
69        newVars = new CompoundStmt( std::list<Label>(0) );
70
71      for (RetType::iterator i = rets.begin() ; i != rets.end(); i++) {
72        DeclStmt *arg = newVar( *i );
73        newVars->get_kids().push_back( arg );
74        add_pending( arg->get_decl() );
75      }
76    }
77
78  DoArgs:
79     // mutate the argument list
80    typedef std::list< Expression *> Exprs;
81    Exprs &args = appExpr->get_args();
82    std::list< Expression * > newArgs;
83    for( Exprs::iterator i = args.begin(); i != args.end(); i++ ) {
84      MVRMutator next;
85      Expression *mutated = (*i)->acceptMutator( next );
86
87      if ( next.hasCode() ) {
88        // merge new vars and bodies
89        typedef std::list< Statement * > Stmts;
90        Stmts &vars = next.getVars()->get_kids();
91        Stmts &block = next.getCode()->get_kids();
92
93        if (newVars == 0)
94          newVars = new CompoundStmt( std::list< Label >() );
95        for( Stmts::iterator i = vars.begin(); i != vars.end(); i++ )  // std::splice? -- need to append lists
96          newVars->get_kids().push_back( *i );
97
98        if (newCode == 0)
99          newCode = new CompoundStmt( std::list< Label >() );
100        for( Stmts::iterator i = block.begin(); i != block.end(); i++ )
101          newCode->get_kids().push_back( *i );
102
103      }
104
105      if ( next.hasResults() ) {
106        Exprs &res = next.get_results();
107        for( Exprs::iterator i = res.begin(); i != res.end(); i++ )
108          newArgs.push_back( *i );
109      } else
110        newArgs.push_back( mutated );
111    }
112
113    appExpr->get_args() = newArgs;  // new argument list
114
115
116    if ( mulretp ) {
117      // add 'out' parameters
118      if ( ! argsToAdd.empty() )
119        for(std::list< Expression *>::iterator i = argsToAdd.begin(); i != argsToAdd.end(); i++)
120          (appExpr->get_args()).push_back( *i );
121      // clear 'out' parameters ( so that the list can be reused -- substitute by auto_ptr later? )
122
123      if (newCode == 0)
124        newCode = new CompoundStmt( std::list<Label>(0) );
125    }
126
127    // add to block of code
128    if ( newCode != 0 )
129      newCode->get_kids().push_back( new ExprStmt( std::list<Label>(), appExpr ) );
130
131    return appExpr;
132  }
133
134  // Auxiliary function to generate new names for the `output' parameters
135  DeclStmt *MVRMutator::newVar( DeclarationWithType *reqDecl ) {
136    // std::ostrstream os;
137    // os << "__" << curVal++ << "__";// << std::ends;
138    // os.freeze( false );
139
140    ObjectDecl *decl;
141    if ((decl = dynamic_cast<ObjectDecl *>( reqDecl )) != 0)
142      // return new DeclStmt( new ObjectDecl( std::string (os.str(), os.pcount()), );
143      return new DeclStmt( std::list<Label>(), decl );
144    else
145      return 0;
146  }
147
148  void MVRMutator::add_pending( Declaration *decl ) {
149    ObjectDecl *obj;
150    if ( (obj = dynamic_cast< ObjectDecl * >( decl )) == 0 ) return;
151
152    VariableExpr *var = new VariableExpr(obj, 0 );
153    results.push_back( var ); // probably change this name to newResults or something
154    argsToAdd.push_back( new AddressExpr( var ) );
155    return;
156  }
157}
Note: See TracBrowser for help on using the repository browser.