1 | //
|
---|
2 | // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
|
---|
3 | //
|
---|
4 | // The contents of this file are covered under the licence agreement in the
|
---|
5 | // file "LICENCE" distributed with Cforall.
|
---|
6 | //
|
---|
7 | // FunctionFixer.cc --
|
---|
8 | //
|
---|
9 | // Author : Rodolfo G. Esteves
|
---|
10 | // Created On : Mon May 18 07:44:20 2015
|
---|
11 | // Last Modified By : Peter A. Buhr
|
---|
12 | // Last Modified On : Mon May 18 12:02:22 2015
|
---|
13 | // Update Count : 1
|
---|
14 | //
|
---|
15 |
|
---|
16 | #include <list>
|
---|
17 | #include <vector>
|
---|
18 | #include <cassert>
|
---|
19 | #include <algorithm>
|
---|
20 |
|
---|
21 | #include "FunctionFixer.h"
|
---|
22 |
|
---|
23 | namespace Tuples {
|
---|
24 | DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) {
|
---|
25 | functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
|
---|
26 | mutateAll( functionDecl->get_oldDecls(), *this );
|
---|
27 | functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
|
---|
28 | index.visit( functionDecl );
|
---|
29 | rets.clear();
|
---|
30 | return functionDecl;
|
---|
31 | }
|
---|
32 |
|
---|
33 | Type *FunctionFixer::mutate( FunctionType *functionType ) {
|
---|
34 | typedef std::list< DeclarationWithType * > Decls;
|
---|
35 |
|
---|
36 | if ( functionType->get_returnVals().size() <= 1 ) return functionType;
|
---|
37 | std::copy( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), back_inserter(rets) );
|
---|
38 |
|
---|
39 | Type::Qualifiers qual;
|
---|
40 | for ( Decls::iterator i = rets.begin(); i != rets.end(); i++ ) {
|
---|
41 | (*i)->set_type( new PointerType( qual, (*i)->get_type() ) );
|
---|
42 | functionType->get_parameters().push_back( *i );
|
---|
43 | } // for
|
---|
44 |
|
---|
45 | functionType->get_returnVals() = *(new std::list< DeclarationWithType * >());
|
---|
46 |
|
---|
47 | functionType->set_isVarArgs( false );
|
---|
48 | return functionType;
|
---|
49 | }
|
---|
50 |
|
---|
51 | Statement *FunctionFixer::mutate( ReturnStmt *retStmt ) {
|
---|
52 | bool tupleReturn = false;
|
---|
53 | Expression *rhs = 0;
|
---|
54 | // also check if returning multiple values
|
---|
55 | if ( CastExpr *cst = dynamic_cast<CastExpr *>( retStmt->get_expr() ) ) {
|
---|
56 | if ( ApplicationExpr *app = dynamic_cast<ApplicationExpr *>( cst->get_arg() ) ) {
|
---|
57 | if ( app->get_results().size() > 1 ) { // doesn't need to be ApplicationExpr
|
---|
58 | tupleReturn = true;
|
---|
59 | rhs = app;
|
---|
60 | }
|
---|
61 | } else if ( TupleExpr *t = dynamic_cast<TupleExpr *>( cst->get_arg() ) ) {
|
---|
62 | tupleReturn = true;
|
---|
63 | assert( rets.size() == t->get_exprs().size() ); // stupid check, resolve expression
|
---|
64 | rhs = t;
|
---|
65 | } // if
|
---|
66 |
|
---|
67 | if ( tupleReturn ) {
|
---|
68 | assert ( rhs != 0 );
|
---|
69 | std::list< Expression * > lhs;
|
---|
70 | for ( std::list< DeclarationWithType * >::iterator d = rets.begin(); d != rets.end(); ++d ) {
|
---|
71 | std::list<Expression *> largs;
|
---|
72 | largs.push_back(new VariableExpr( *d ));
|
---|
73 | Expression *exp = ResolvExpr::resolveInVoidContext( new CastExpr( new UntypedExpr(new NameExpr("*?"), largs), (*d)->get_type()),
|
---|
74 | index );
|
---|
75 | lhs.push_back(exp);
|
---|
76 | } // for
|
---|
77 | std::list< Expression * > args;
|
---|
78 | TupleExpr *tlhs = new TupleExpr; tlhs->set_exprs( lhs );
|
---|
79 | args.push_back( new AddressExpr(tlhs) );
|
---|
80 | args.push_back(rhs);
|
---|
81 |
|
---|
82 | return new ExprStmt( std::list< Label>(), new UntypedExpr( new NameExpr("?=?"), args ) );
|
---|
83 | } // if
|
---|
84 | } // if
|
---|
85 | /*
|
---|
86 | else
|
---|
87 | std::cerr << "Empty return statement" << std::endl;
|
---|
88 | */
|
---|
89 |
|
---|
90 | return retStmt;
|
---|
91 | }
|
---|
92 |
|
---|
93 | Expression* FunctionFixer::mutate( VariableExpr *variableExpr ) {
|
---|
94 | if ( rets.empty() ) return variableExpr;
|
---|
95 | mutateAll( variableExpr->get_results(), *this );
|
---|
96 | if ( std::find( rets.begin(), rets.end(), variableExpr->get_var() ) != rets.end() )
|
---|
97 | // if ( PointerType *ptr = dynamic_cast<PointerType *>(variableExpr->get_var()->get_type()) ) {
|
---|
98 | if ( dynamic_cast<PointerType *>(variableExpr->get_var()->get_type()) != 0 ) {
|
---|
99 | std::list<Expression *> largs;
|
---|
100 | largs.push_back( new AddressExpr(variableExpr) );
|
---|
101 | Expression *expr = ResolvExpr::resolveInVoidContext( /*new CastExpr(*/new UntypedExpr( new NameExpr( "*?" ), largs )/*,
|
---|
102 | ptr->get_base()),*/, index);
|
---|
103 | if ( ApplicationExpr *app = dynamic_cast< ApplicationExpr * >( expr ) ) {
|
---|
104 | assert( app->get_args().size() == 1 );
|
---|
105 | app->get_args().pop_front();
|
---|
106 | app->get_args().push_back( variableExpr );
|
---|
107 | return app;
|
---|
108 | }
|
---|
109 | }
|
---|
110 | return variableExpr;
|
---|
111 | }
|
---|
112 |
|
---|
113 | /*
|
---|
114 | Expression* FunctionFixer::mutate(ApplicationExpr *applicationExpr) {
|
---|
115 | std::cerr << "In Application Expression" << std::endl;
|
---|
116 | mutateAll( applicationExpr->get_results(), *this );
|
---|
117 | applicationExpr->set_function( maybeMutate( applicationExpr->get_function(), *this ) );
|
---|
118 | mutateAll( applicationExpr->get_args(), *this );
|
---|
119 | return applicationExpr;
|
---|
120 | }
|
---|
121 | */
|
---|
122 | } // namespace Tuples
|
---|
123 | // Local Variables: //
|
---|
124 | // tab-width: 4 //
|
---|
125 | // mode: c++ //
|
---|
126 | // compile-command: "make install" //
|
---|
127 | // End: //
|
---|