// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // FunctionFixer.cc -- // // Author : Rodolfo G. Esteves // Created On : Mon May 18 07:44:20 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Mon May 18 12:02:22 2015 // Update Count : 1 // #include #include #include #include #include "FunctionFixer.h" namespace Tuples { DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) { functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); mutateAll( functionDecl->get_oldDecls(), *this ); functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); index.visit( functionDecl ); rets.clear(); return functionDecl; } Type *FunctionFixer::mutate( FunctionType *functionType ) { typedef std::list< DeclarationWithType * > Decls; if ( functionType->get_returnVals().size() <= 1 ) return functionType; std::copy( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), back_inserter(rets) ); Type::Qualifiers qual; for ( Decls::iterator i = rets.begin(); i != rets.end(); i++ ) { (*i)->set_type( new PointerType( qual, (*i)->get_type() ) ); functionType->get_parameters().push_back( *i ); } // for functionType->get_returnVals() = *(new std::list< DeclarationWithType * >()); functionType->set_isVarArgs( false ); return functionType; } Statement *FunctionFixer::mutate( ReturnStmt *retStmt ) { bool tupleReturn = false; Expression *rhs = 0; // also check if returning multiple values if ( CastExpr *cst = dynamic_cast( retStmt->get_expr() ) ) { if ( ApplicationExpr *app = dynamic_cast( cst->get_arg() ) ) { if ( app->get_results().size() > 1 ) { // doesn't need to be ApplicationExpr tupleReturn = true; rhs = app; } } else if ( TupleExpr *t = dynamic_cast( cst->get_arg() ) ) { tupleReturn = true; assert( rets.size() == t->get_exprs().size() ); // stupid check, resolve expression rhs = t; } // if if ( tupleReturn ) { assert ( rhs != 0 ); std::list< Expression * > lhs; for ( std::list< DeclarationWithType * >::iterator d = rets.begin(); d != rets.end(); ++d ) { std::list largs; largs.push_back(new VariableExpr( *d )); Expression *exp = ResolvExpr::resolveInVoidContext( new CastExpr( new UntypedExpr(new NameExpr("*?"), largs), (*d)->get_type()), index ); lhs.push_back(exp); } // for std::list< Expression * > args; TupleExpr *tlhs = new TupleExpr; tlhs->set_exprs( lhs ); args.push_back( new AddressExpr(tlhs) ); args.push_back(rhs); return new ExprStmt( std::list< Label>(), new UntypedExpr( new NameExpr("?=?"), args ) ); } // if } // if /* else std::cerr << "Empty return statement" << std::endl; */ return retStmt; } Expression* FunctionFixer::mutate( VariableExpr *variableExpr ) { if ( rets.empty() ) return variableExpr; mutateAll( variableExpr->get_results(), *this ); if ( std::find( rets.begin(), rets.end(), variableExpr->get_var() ) != rets.end() ) // if ( PointerType *ptr = dynamic_cast(variableExpr->get_var()->get_type()) ) { if ( dynamic_cast(variableExpr->get_var()->get_type()) != 0 ) { std::list largs; largs.push_back( new AddressExpr(variableExpr) ); Expression *expr = ResolvExpr::resolveInVoidContext( /*new CastExpr(*/new UntypedExpr( new NameExpr( "*?" ), largs )/*, ptr->get_base()),*/, index); if ( ApplicationExpr *app = dynamic_cast< ApplicationExpr * >( expr ) ) { assert( app->get_args().size() == 1 ); app->get_args().pop_front(); app->get_args().push_back( variableExpr ); return app; } } return variableExpr; } /* Expression* FunctionFixer::mutate(ApplicationExpr *applicationExpr) { std::cerr << "In Application Expression" << std::endl; mutateAll( applicationExpr->get_results(), *this ); applicationExpr->set_function( maybeMutate( applicationExpr->get_function(), *this ) ); mutateAll( applicationExpr->get_args(), *this ); return applicationExpr; } */ } // namespace Tuples // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //