source: translator/Tuples/MultRet.cc@ 643a2e1

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 643a2e1 was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 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.