| 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: // | 
|---|