Changeset 01aeade
- Timestamp:
- May 19, 2015, 7:57:09 AM (8 years ago)
- Branches:
- aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- a08ba92
- Parents:
- 51587aa
- Location:
- translator
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
translator/Common/CompilerError.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // CompilerError.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:20:37 2015 13 // Update Count : 2 14 14 // 15 15 16 #ifndef COMPILER_ERROR_H 16 17 #define COMPILER_ERROR_H … … 19 20 //#include "../config.h" 20 21 21 class CompilerError : public std::exception 22 { 23 public: 24 CompilerError(); 25 CompilerError( std::string what ) : what( what ) {} 26 ~CompilerError() throw () {} 22 class CompilerError : public std::exception { 23 public: 24 CompilerError(); 25 CompilerError( std::string what ) : what( what ) {} 26 ~CompilerError() throw () {} 27 27 28 std::string get_what() const { return what; } 29 void set_what( std::string newValue ) { what = newValue; } 30 31 private: 32 std::string what; 28 std::string get_what() const { return what; } 29 void set_what( std::string newValue ) { what = newValue; } 30 private: 31 std::string what; 33 32 }; 34 33 35 #endif / * COMPILER_ERROR_H */34 #endif // COMPILER_ERROR_H 36 35 37 /*38 Local Variables:39 mode: c++40 End:41 */42 36 // Local Variables: // 43 37 // tab-width: 4 // -
translator/Common/SemanticError.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // SemanticError.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:21:25 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: SemanticError.cc,v 1.1 2002/04/27 19:57:10 rcbilson Exp $19 *20 */21 15 22 16 #include <iostream> … … 28 22 #include "SemanticError.h" 29 23 30 SemanticError::SemanticError() 31 { 24 SemanticError::SemanticError() { 32 25 } 33 26 34 SemanticError::SemanticError( std::string error ) 35 { 36 errors.push_back( std::string( "Error: " ) + error ); 27 SemanticError::SemanticError( std::string error ) { 28 errors.push_back( std::string( "Error: " ) + error ); 37 29 } 38 30 39 void 40 SemanticError::append( SemanticError &other ) 41 { 42 errors.splice( errors.end(), other.errors ); 31 void SemanticError::append( SemanticError &other ) { 32 errors.splice( errors.end(), other.errors ); 43 33 } 44 34 45 bool 46 SemanticError::isEmpty() const 47 { 48 return errors.empty(); 35 bool SemanticError::isEmpty() const { 36 return errors.empty(); 49 37 } 50 38 51 void 52 SemanticError::print( std::ostream &os ) 53 { 54 std::copy( errors.begin(), errors.end(), std::ostream_iterator< std::string >( os, "\n" ) ); 39 void SemanticError::print( std::ostream &os ) { 40 std::copy( errors.begin(), errors.end(), std::ostream_iterator< std::string >( os, "\n" ) ); 55 41 } 42 56 43 // Local Variables: // 57 44 // tab-width: 4 // -
translator/Common/SemanticError.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // SemanticError.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:22:23 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: SemanticError.h,v 1.1 2002/04/27 19:57:10 rcbilson Exp $19 *20 */21 15 22 16 #ifndef SEMANTICERROR_H … … 29 23 #include <iostream> 30 24 31 class SemanticError : public std::exception 32 { 33 public: 34 SemanticError(); 35 SemanticError( std::string error ); 36 template< typename T > SemanticError( const std::string &error, const T *obj ); 37 ~SemanticError() throw() {} 25 class SemanticError : public std::exception { 26 public: 27 SemanticError(); 28 SemanticError( std::string error ); 29 template< typename T > SemanticError( const std::string &error, const T *obj ); 30 ~SemanticError() throw() {} 38 31 39 40 41 32 void append( SemanticError &other ); 33 bool isEmpty() const; 34 void print( std::ostream &os ); 42 35 43 // constructs an exception using the given message and the printed 44 // representation of the obj (T must have a print method) 45 46 private: 47 std::list< std::string > errors; 36 // constructs an exception using the given message and the printed 37 // representation of the obj (T must have a print method) 38 private: 39 std::list< std::string > errors; 48 40 }; 49 41 50 42 template< typename T > 51 SemanticError::SemanticError( const std::string &error, const T *obj ) 52 { 53 std::ostrstream os; 54 os << "Error: " << error; 55 obj->print( os ); 56 errors.push_back( std::string( os.str(), os.pcount() ) ); 43 SemanticError::SemanticError( const std::string &error, const T *obj ) { 44 std::ostrstream os; 45 os << "Error: " << error; 46 obj->print( os ); 47 errors.push_back( std::string( os.str(), os.pcount() ) ); 57 48 } 58 49 59 #endif /* SEMANTICERROR_H */ 50 #endif // SEMANTICERROR_H 51 60 52 // Local Variables: // 61 53 // tab-width: 4 // -
translator/Common/UnimplementedError.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // UnimplementedError.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:23:08 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: UnimplementedError.h,v 1.1 2002/09/02 20:31:53 rcbilson Exp $19 *20 */21 15 22 #ifndef COMMON_UNIMPLEMENTEDERROR_H23 #define COMMON_UNIMPLEMENTEDERROR_H16 #ifndef _UNIMPLEMENTEDERROR_H 17 #define _UNIMPLEMENTEDERROR_H 24 18 25 19 #include <string> 26 20 27 class UnimplementedError : public std::exception 28 { 29 public: 30 UnimplementedError(); 31 UnimplementedError( std::string what ) : what( what ) {} 32 ~UnimplementedError() throw () {} 21 class UnimplementedError : public std::exception { 22 public: 23 UnimplementedError(); 24 UnimplementedError( std::string what ) : what( what ) {} 25 ~UnimplementedError() throw () {} 33 26 34 std::string get_what() const { return what; } 35 void set_what( std::string newValue ) { what = newValue; } 36 37 private: 38 std::string what; 27 std::string get_what() const { return what; } 28 void set_what( std::string newValue ) { what = newValue; } 29 private: 30 std::string what; 39 31 }; 40 32 41 #endif /* #ifndef COMMON_UNIMPLEMENTEDERROR_H */ 33 #endif // _UNIMPLEMENTEDERROR_H 34 42 35 // Local Variables: // 43 36 // tab-width: 4 // -
translator/Common/UniqueName.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // UniqueName.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:23:41 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: UniqueName.cc,v 1.1 2002/04/30 03:30:14 rcbilson Exp $19 *20 */21 15 22 16 #include <string> … … 25 19 #include "UniqueName.h" 26 20 27 UniqueName::UniqueName( const std::string &base ) 28 : base( base ), count( 0 ) 29 { 21 UniqueName::UniqueName( const std::string &base ) : base( base ), count( 0 ) { 30 22 } 31 23 32 std::string 33 UniqueName::newName( const std::string &additional ) 34 { 35 std::ostrstream os; 36 os << base << additional << count++; 37 return std::string( os.str(), os.pcount() ); 24 std::string UniqueName::newName( const std::string &additional ) { 25 std::ostrstream os; 26 os << base << additional << count++; 27 return std::string( os.str(), os.pcount() ); 38 28 } 39 29 -
translator/Common/UniqueName.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // UniqueName.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:24:20 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: UniqueName.h,v 1.1 2002/04/30 03:30:14 rcbilson Exp $19 *20 */21 15 22 16 #ifndef UNIQUENAME_H … … 25 19 #include <string> 26 20 27 class UniqueName 28 { 29 public: 30 UniqueName( const std::string &base = "" ); 31 32 std::string newName( const std::string &additional = "" ); 33 34 private: 35 std::string base; 36 int count; 21 class UniqueName { 22 public: 23 UniqueName( const std::string &base = "" ); 24 std::string newName( const std::string &additional = "" ); 25 private: 26 std::string base; 27 int count; 37 28 }; 38 29 39 #endif /* #ifndef UNIQUENAME_H */ 30 #endif // UNIQUENAME_H 31 40 32 // Local Variables: // 41 33 // tab-width: 4 // -
translator/Common/utility.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // utility.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 0 14 // 15 /* 16 * This file is part of the Cforall project 17 * 18 * Some useful template utility functions 19 * 20 * $Id: utility.h,v 1.17 2003/11/26 18:05:21 rgesteve Exp $ 21 * 22 */ 23 24 #ifndef COMMON_UTILITY_H 25 #define COMMON_UTILITY_H 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:27:38 2015 13 // Update Count : 2 14 // 15 16 #ifndef _UTILITY_H 17 #define _UTILITY_H 26 18 27 19 #include <iostream> … … 33 25 34 26 template< typename T > 35 static inline T* 36 maybeClone( const T *orig ) 37 { 38 if ( orig ) { 39 return orig->clone(); 40 } else { 41 return 0; 42 } 27 static inline T * maybeClone( const T *orig ) { 28 if ( orig ) { 29 return orig->clone(); 30 } else { 31 return 0; 32 } // if 43 33 } 44 34 45 35 template< typename T, typename U > 46 static inline T* 47 maybeBuild( const U *orig ) 48 { 49 if ( orig ) { 50 return orig->build(); 51 } else { 52 return 0; 53 } 36 static inline T * maybeBuild( const U *orig ) { 37 if ( orig ) { 38 return orig->build(); 39 } else { 40 return 0; 41 } // if 54 42 } 55 43 56 44 template< typename Input_iterator > 57 void 58 printEnums( Input_iterator begin, Input_iterator end, const char * const *name_array, std::ostream &os ) 59 { 60 for ( Input_iterator i = begin; i != end; ++i ) { 61 os << name_array[ *i ] << ' '; 62 } 45 void printEnums( Input_iterator begin, Input_iterator end, const char * const *name_array, std::ostream &os ) { 46 for ( Input_iterator i = begin; i != end; ++i ) { 47 os << name_array[ *i ] << ' '; 48 } // for 63 49 } 64 50 65 51 template< typename Container > 66 void 67 deleteAll( Container &container ) 68 { 69 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { 70 delete *i; 71 } 52 void deleteAll( Container &container ) { 53 for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) { 54 delete *i; 55 } // for 72 56 } 73 57 74 58 template< typename Container > 75 void 76 printAll( const Container &container, std::ostream &os, int indent = 0 ) 77 { 78 for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) { 79 if ( *i ) { 80 os << std::string(indent, ' '); 81 (*i)->print( os, indent + 2 ); 82 os << std::endl; 83 } 84 } 59 void printAll( const Container &container, std::ostream &os, int indent = 0 ) { 60 for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) { 61 if ( *i ) { 62 os << std::string(indent, ' '); 63 (*i)->print( os, indent + 2 ); 64 os << std::endl; 65 } // if 66 } // for 85 67 } 86 68 87 69 template< typename SrcContainer, typename DestContainer > 88 void 89 cloneAll( const SrcContainer &src, DestContainer &dest ) 90 { 91 typename SrcContainer::const_iterator in = src.begin(); 92 std::back_insert_iterator< DestContainer > out( dest ); 93 while ( in != src.end() ) { 94 *out++ = (*in++)->clone(); 95 } 70 void cloneAll( const SrcContainer &src, DestContainer &dest ) { 71 typename SrcContainer::const_iterator in = src.begin(); 72 std::back_insert_iterator< DestContainer > out( dest ); 73 while ( in != src.end() ) { 74 *out++ = (*in++)->clone(); 75 } // while 96 76 } 97 77 98 78 template< typename Container > 99 void 100 assertAll( const Container &container ) 101 { 102 int count = 0; 103 for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) { 104 if ( !(*i) ) { 105 std::cerr << count << " is null" << std::endl; 106 } 107 } 108 } 109 110 static inline std::string 111 assign_strptr( std::string *str ) 112 { 113 if ( str == 0 ) { 114 return ""; 115 } else { 116 std::string tmp; 117 tmp = *str; 118 delete str; 119 return tmp; 120 } 79 void assertAll( const Container &container ) { 80 int count = 0; 81 for ( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) { 82 if ( !(*i) ) { 83 std::cerr << count << " is null" << std::endl; 84 } // if 85 } // for 86 } 87 88 static inline std::string assign_strptr( std::string *str ) { 89 if ( str == 0 ) { 90 return ""; 91 } else { 92 std::string tmp; 93 tmp = *str; 94 delete str; 95 return tmp; 96 } // if 121 97 } 122 98 123 99 template< class T, typename ResultType, ResultType (T::* memfunc)() > 124 ResultType dispatch( T *pT){125 100 ResultType dispatch( T *pT ) { 101 return (pT->*memfunc)(); 126 102 } 127 103 128 104 template < typename T > 129 std::list<T> tail( std::list<T> l ) 130 { 131 if (! l.empty()){ 132 std::list<T> ret(++(l.begin()), l.end()); 133 return ret; 134 } 105 std::list<T> tail( std::list<T> l ) { 106 if ( ! l.empty() ) { 107 std::list<T> ret(++(l.begin()), l.end()); 108 return ret; 109 } // if 135 110 } 136 111 137 112 template < typename T > 138 113 std::list<T> flatten( std::list < std::list<T> > l) { 139 140 141 142 143 144 case 0:145 146 case 1:147 148 default:149 150 151 152 } 114 typedef std::list <T> Ts; 115 116 Ts ret; 117 118 switch ( l.size() ){ 119 case 0: 120 return ret; 121 case 1: 122 return l.front(); 123 default: 124 ret = flatten(tail(l)); 125 ret.insert(ret.begin(), l.front().begin(), l.front().end()); 126 return ret; 127 } // switch 153 128 } 154 129 155 130 template < typename T > 156 131 std::string toString ( T value ) { 157 132 std::ostrstream os; 158 133 159 160 161 162 134 os << value; // << std::ends; 135 os.freeze( false ); 136 137 return std::string(os.str(), os.pcount()); 163 138 } 164 139 165 140 template< class Constructed, typename Arg > 166 141 Constructed *ctor( Arg arg ) { 167 168 142 Constructed *c = new Constructed( arg ); 143 return c; 169 144 } 170 145 171 146 template< class Constructed, typename Arg > 172 147 Constructed ctor_noptr( Arg arg ) { 173 148 return Constructed( arg ); 174 149 } 175 150 176 151 template< typename T > 177 152 void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) { 178 179 180 181 182 153 // TIter should secretly be a typename std::list< T >::iterator 154 // ( g++ 3.2 issues a 'is implicitly a typename' warning if I make this explicit ) 155 typename std::list< T >::iterator next = pos; advance( next, 1 ); 156 157 //if ( next != org.end() ) { 183 158 org.erase( pos ); 184 159 org.splice( next, with ); 185 160 //} 186 161 187 162 return; 188 163 } 189 164 190 165 template< typename T1, typename T2 > 191 166 T2 *cast_ptr( T1 *from ) { 192 167 return dynamic_cast< T2 * >( from ); 193 168 } 194 169 195 170 template< class Exception, typename Arg > 196 171 void inline assert_throw( bool pred, Arg arg ) { 197 172 if (pred) throw Exception( arg ); 198 173 } 199 174 200 175 template< typename T > 201 176 struct is_null_pointer { 202 177 bool operator()( const T *ptr ){ return ( ptr == 0 ); } 203 178 }; 204 179 205 180 template< class InputIterator, class OutputIterator, class Predicate > 206 void filter(InputIterator begin, InputIterator end, OutputIterator out, Predicate pred) 207 { 208 while ( begin++ != end ) 209 if ( pred(*begin) ) *out++ = *begin; 210 211 return; 181 void filter(InputIterator begin, InputIterator end, OutputIterator out, Predicate pred) { 182 while ( begin++ != end ) 183 if ( pred(*begin) ) *out++ = *begin; 184 185 return; 212 186 } 213 187 214 188 template< class InputIterator1, class InputIterator2, class OutputIterator > 215 189 void zip( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out ) { 216 217 190 while ( b1 != e1 && b2 != e2 ) 191 *out++ = std::pair<typename InputIterator1::value_type, typename InputIterator2::value_type>(*b1++, *b2++); 218 192 } 219 193 220 194 template< class InputIterator1, class InputIterator2, class OutputIterator, class BinFunction > 221 195 void zipWith( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out, BinFunction func ) { 222 while ( b1 != e1 && b2 != e2 ) 223 *out++ = func(*b1++, *b2++); 224 } 225 226 #endif /* #ifndef COMMON_UTILITY_H */ 227 228 /* 229 Local Variables: 230 mode: c++ 231 End: 232 */ 196 while ( b1 != e1 && b2 != e2 ) 197 *out++ = func(*b1++, *b2++); 198 } 199 200 #endif // _UTILITY_H 201 233 202 // Local Variables: // 234 203 // tab-width: 4 // -
translator/GenPoly/Box.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // Box.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:31:41 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: Box.cc,v 1.20 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #include <set> … … 48 42 49 43 namespace GenPoly { 50 namespace { 51 const std::list<Label> noLabels; 52 53 class Pass1 : public PolyMutator { 54 public: 55 Pass1(); 56 virtual Expression *mutate( ApplicationExpr *appExpr ); 57 virtual Expression *mutate( AddressExpr *addrExpr ); 58 virtual Expression *mutate( UntypedExpr *expr ); 59 virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ); 60 virtual TypeDecl *mutate( TypeDecl *typeDecl ); 61 virtual Expression *mutate( CommaExpr *commaExpr ); 62 virtual Expression *mutate( ConditionalExpr *condExpr ); 63 virtual Statement *mutate(ReturnStmt *catchStmt); 64 virtual Type *mutate( PointerType *pointerType ); 65 virtual Type *mutate( FunctionType *pointerType ); 66 67 virtual void doBeginScope(); 68 virtual void doEndScope(); 69 private: 70 void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 71 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ); 72 Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ); 73 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 74 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); 75 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 76 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 77 void findAssignOps( const std::list< TypeDecl *> &forall ); 78 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 79 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 80 Expression *handleIntrinsics( ApplicationExpr *appExpr ); 81 ObjectDecl *makeTemporary( Type *type ); 82 83 std::map< std::string, DeclarationWithType *> assignOps; 84 typedef std::map< std::string, FunctionDecl *> AdapterMap; 85 std::stack< AdapterMap > adapters; 86 DeclarationWithType *retval; 87 bool useRetval; 88 UniqueName tempNamer; 89 }; 90 91 class Pass2 : public PolyMutator { 92 public: 93 Pass2(); 94 template< typename DeclClass > 95 DeclClass *handleDecl( DeclClass *decl, Type *type ); 96 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 97 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ); 98 virtual TypeDecl *mutate( TypeDecl *typeDecl ); 99 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ); 100 virtual Type *mutate( PointerType *pointerType ); 101 virtual Type *mutate( FunctionType *funcType ); 102 private: 103 void addAdapters( FunctionType *functionType ); 104 105 std::map< UniqueId, std::string > adapterName; 106 }; 107 108 class Pass3 : public PolyMutator { 109 public: 110 template< typename DeclClass > 111 DeclClass *handleDecl( DeclClass *decl, Type *type ); 112 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 113 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ); 114 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ); 115 virtual TypeDecl *mutate( TypeDecl *objectDecl ); 116 virtual Statement *mutate( DeclStmt *declStmt ); 117 virtual Type *mutate( PointerType *pointerType ); 118 virtual Type *mutate( FunctionType *funcType ); 119 private: 120 }; 121 122 } // anonymous namespace 123 124 void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) { 125 for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 126 if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) { 127 (*i)->print( os ); 128 os << std::endl; 129 } // if 130 } // for 131 } 132 133 void box( std::list< Declaration *>& translationUnit ) { 134 Pass1 pass1; 135 Pass2 pass2; 136 Pass3 pass3; 137 mutateAll( translationUnit, pass1 ); 138 mutateAll( translationUnit, pass2 ); 139 mutateAll( translationUnit, pass3 ); 140 } 141 142 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 143 144 namespace { 145 std::string makeAdapterName( const std::string &mangleName ) { 146 return "_adapter" + mangleName; 44 namespace { 45 const std::list<Label> noLabels; 46 47 class Pass1 : public PolyMutator { 48 public: 49 Pass1(); 50 virtual Expression *mutate( ApplicationExpr *appExpr ); 51 virtual Expression *mutate( AddressExpr *addrExpr ); 52 virtual Expression *mutate( UntypedExpr *expr ); 53 virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ); 54 virtual TypeDecl *mutate( TypeDecl *typeDecl ); 55 virtual Expression *mutate( CommaExpr *commaExpr ); 56 virtual Expression *mutate( ConditionalExpr *condExpr ); 57 virtual Statement *mutate(ReturnStmt *catchStmt); 58 virtual Type *mutate( PointerType *pointerType ); 59 virtual Type *mutate( FunctionType *pointerType ); 60 61 virtual void doBeginScope(); 62 virtual void doEndScope(); 63 private: 64 void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 65 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ); 66 Expression *addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ); 67 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 68 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); 69 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 70 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 71 void findAssignOps( const std::list< TypeDecl *> &forall ); 72 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 73 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 74 Expression *handleIntrinsics( ApplicationExpr *appExpr ); 75 ObjectDecl *makeTemporary( Type *type ); 76 77 std::map< std::string, DeclarationWithType *> assignOps; 78 typedef std::map< std::string, FunctionDecl *> AdapterMap; 79 std::stack< AdapterMap > adapters; 80 DeclarationWithType *retval; 81 bool useRetval; 82 UniqueName tempNamer; 83 }; 84 85 class Pass2 : public PolyMutator { 86 public: 87 Pass2(); 88 template< typename DeclClass > 89 DeclClass *handleDecl( DeclClass *decl, Type *type ); 90 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 91 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ); 92 virtual TypeDecl *mutate( TypeDecl *typeDecl ); 93 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ); 94 virtual Type *mutate( PointerType *pointerType ); 95 virtual Type *mutate( FunctionType *funcType ); 96 private: 97 void addAdapters( FunctionType *functionType ); 98 99 std::map< UniqueId, std::string > adapterName; 100 }; 101 102 class Pass3 : public PolyMutator { 103 public: 104 template< typename DeclClass > 105 DeclClass *handleDecl( DeclClass *decl, Type *type ); 106 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ); 107 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ); 108 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ); 109 virtual TypeDecl *mutate( TypeDecl *objectDecl ); 110 virtual Statement *mutate( DeclStmt *declStmt ); 111 virtual Type *mutate( PointerType *pointerType ); 112 virtual Type *mutate( FunctionType *funcType ); 113 private: 114 }; 115 116 } // anonymous namespace 117 118 void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) { 119 for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 120 if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) { 121 (*i)->print( os ); 122 os << std::endl; 123 } // if 124 } // for 147 125 } 148 126 149 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) { 150 bool doTransform = false; 151 if ( ! function->get_returnVals().empty() ) { 152 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) { 153 154 // figure out if the return type is specified by a type parameter 155 for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) { 156 if ( (*tyVar)->get_name() == typeInst->get_name() ) { 157 doTransform = true; 158 name = typeInst->get_name(); 159 break; 160 } // if 161 } // for 162 if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) { 163 doTransform = true; 164 } // if 165 } // if 166 } // if 167 return doTransform; 127 void box( std::list< Declaration *>& translationUnit ) { 128 Pass1 pass1; 129 Pass2 pass2; 130 Pass3 pass3; 131 mutateAll( translationUnit, pass1 ); 132 mutateAll( translationUnit, pass2 ); 133 mutateAll( translationUnit, pass3 ); 168 134 } 169 135 170 bool isPolyRet( FunctionType *function, std::string &name ) { 171 TyVarMap dummyTyVars; 172 return isPolyRet( function, name, dummyTyVars ); 173 } 174 175 Pass1::Pass1() 176 : useRetval( false ), tempNamer( "_temp" ) { 177 } 178 179 bool checkAssignment( DeclarationWithType *decl, std::string &name ) { 180 if ( decl->get_name() == "?=?" ) { 181 if ( PointerType *ptrType = dynamic_cast< PointerType *>( decl->get_type() ) ) { 182 if ( FunctionType *funType = dynamic_cast< FunctionType *>( ptrType->get_base() ) ) { 183 if ( funType->get_parameters().size() == 2 ) { 184 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 185 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 186 name = typeInst->get_name(); 187 return true; 188 } // if 189 } // if 190 } // if 191 } // if 192 } // if 193 } // if 194 return false; 195 } 196 197 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) { 198 assignOps.clear(); 199 for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 200 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 201 std::string typeName; 202 if ( checkAssignment( *assert, typeName ) ) { 203 assignOps[ typeName ] = *assert; 204 } // if 205 } // for 206 } // for 207 } 208 209 DeclarationWithType * 210 Pass1::mutate( FunctionDecl *functionDecl ) { 211 if ( functionDecl->get_statements() ) { 212 TyVarMap oldtyVars = scopeTyVars; 213 DeclarationWithType *oldRetval = retval; 214 bool oldUseRetval = useRetval; 215 216 retval = 0; 217 std::string typeName; 218 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 219 retval = functionDecl->get_functionType()->get_returnVals().front(); 220 221 // give names to unnamed return values 222 if ( retval->get_name() == "" ) { 223 retval->set_name( "_retparm" ); 224 retval->set_linkage( LinkageSpec::C ); 225 } // if 226 } // if 227 228 scopeTyVars.clear(); 136 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 137 138 namespace { 139 std::string makeAdapterName( const std::string &mangleName ) { 140 return "_adapter" + mangleName; 141 } 142 143 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) { 144 bool doTransform = false; 145 if ( ! function->get_returnVals().empty() ) { 146 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) { 147 148 // figure out if the return type is specified by a type parameter 149 for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) { 150 if ( (*tyVar)->get_name() == typeInst->get_name() ) { 151 doTransform = true; 152 name = typeInst->get_name(); 153 break; 154 } // if 155 } // for 156 if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) { 157 doTransform = true; 158 } // if 159 } // if 160 } // if 161 return doTransform; 162 } 163 164 bool isPolyRet( FunctionType *function, std::string &name ) { 165 TyVarMap dummyTyVars; 166 return isPolyRet( function, name, dummyTyVars ); 167 } 168 169 Pass1::Pass1() 170 : useRetval( false ), tempNamer( "_temp" ) { 171 } 172 173 bool checkAssignment( DeclarationWithType *decl, std::string &name ) { 174 if ( decl->get_name() == "?=?" ) { 175 if ( PointerType *ptrType = dynamic_cast< PointerType *>( decl->get_type() ) ) { 176 if ( FunctionType *funType = dynamic_cast< FunctionType *>( ptrType->get_base() ) ) { 177 if ( funType->get_parameters().size() == 2 ) { 178 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 179 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 180 name = typeInst->get_name(); 181 return true; 182 } // if 183 } // if 184 } // if 185 } // if 186 } // if 187 } // if 188 return false; 189 } 190 191 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) { 192 assignOps.clear(); 193 for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 194 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 195 std::string typeName; 196 if ( checkAssignment( *assert, typeName ) ) { 197 assignOps[ typeName ] = *assert; 198 } // if 199 } // for 200 } // for 201 } 202 203 DeclarationWithType * 204 Pass1::mutate( FunctionDecl *functionDecl ) { 205 if ( functionDecl->get_statements() ) { 206 TyVarMap oldtyVars = scopeTyVars; 207 DeclarationWithType *oldRetval = retval; 208 bool oldUseRetval = useRetval; 209 210 retval = 0; 211 std::string typeName; 212 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 213 retval = functionDecl->get_functionType()->get_returnVals().front(); 214 215 // give names to unnamed return values 216 if ( retval->get_name() == "" ) { 217 retval->set_name( "_retparm" ); 218 retval->set_linkage( LinkageSpec::C ); 219 } // if 220 } // if 221 222 scopeTyVars.clear(); 229 223 /// std::cerr << "clear\n"; 230 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );231 findAssignOps( functionDecl->get_functionType()->get_forall() );232 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );233 234 scopeTyVars = oldtyVars;224 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 225 findAssignOps( functionDecl->get_functionType()->get_forall() ); 226 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 227 228 scopeTyVars = oldtyVars; 235 229 /// std::cerr << "end FunctionDecl: "; 236 230 /// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { … … 238 232 /// } 239 233 /// std::cerr << "\n"; 240 retval = oldRetval;241 useRetval = oldUseRetval;242 // doEndScope();243 244 245 }246 247 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {234 retval = oldRetval; 235 useRetval = oldUseRetval; 236 // doEndScope(); 237 } // if 238 return functionDecl; 239 } 240 241 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 248 242 /// std::cerr << "add " << typeDecl->get_name() << "\n"; 249 250 251 }252 253 Expression *Pass1::mutate( CommaExpr *commaExpr ) {254 255 256 257 258 259 260 }261 262 Expression *Pass1::mutate( ConditionalExpr *condExpr ) {263 264 265 266 267 268 269 270 271 }272 273 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {274 275 ResolvExpr::EqvClass eqvClass;276 assert( env );277 if ( tyParm->second == TypeDecl::Any ) {278 279 280 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );281 arg++;282 283 throw SemanticError( "unbound type variable in application ", appExpr );284 285 } // if286 287 }288 289 ObjectDecl *Pass1::makeTemporary( Type *type ) {290 291 292 293 }294 295 TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {296 297 if ( env ) {298 299 return isPolyType( newType, env, tyVars );300 301 } // if302 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {303 304 } else {305 306 } // if307 308 return 0;309 310 }311 312 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {313 314 assert( retval );315 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );316 arg++;317 318 ObjectDecl *newObj = makeTemporary( retType->clone() );319 Expression *paramExpr = new VariableExpr( newObj );320 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {321 322 } // if323 arg = appExpr->get_args().insert( arg, paramExpr );324 arg++;243 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 244 return Mutator::mutate( typeDecl ); 245 } 246 247 Expression *Pass1::mutate( CommaExpr *commaExpr ) { 248 bool oldUseRetval = useRetval; 249 useRetval = false; 250 commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) ); 251 useRetval = oldUseRetval; 252 commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) ); 253 return commaExpr; 254 } 255 256 Expression *Pass1::mutate( ConditionalExpr *condExpr ) { 257 bool oldUseRetval = useRetval; 258 useRetval = false; 259 condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) ); 260 useRetval = oldUseRetval; 261 condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) ); 262 condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) ); 263 return condExpr; 264 265 } 266 267 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 268 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { 269 ResolvExpr::EqvClass eqvClass; 270 assert( env ); 271 if ( tyParm->second == TypeDecl::Any ) { 272 Type *concrete = env->lookup( tyParm->first ); 273 if ( concrete ) { 274 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 275 arg++; 276 } else { 277 throw SemanticError( "unbound type variable in application ", appExpr ); 278 } // if 279 } // if 280 } // for 281 } 282 283 ObjectDecl *Pass1::makeTemporary( Type *type ) { 284 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, type, 0 ); 285 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 286 return newObj; 287 } 288 289 TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 290 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 291 if ( env ) { 292 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 293 return isPolyType( newType, env, tyVars ); 294 } // if 295 } // if 296 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 297 return typeInst; 298 } else { 299 return 0; 300 } // if 301 } else { 302 return 0; 303 } // if 304 } 305 306 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 307 if ( useRetval ) { 308 assert( retval ); 309 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 310 arg++; 311 } else { 312 ObjectDecl *newObj = makeTemporary( retType->clone() ); 313 Expression *paramExpr = new VariableExpr( newObj ); 314 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 315 paramExpr = new AddressExpr( paramExpr ); 316 } // if 317 arg = appExpr->get_args().insert( arg, paramExpr ); 318 arg++; 325 319 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 326 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );327 commaExpr->set_env( appExpr->get_env() );328 appExpr->set_env( 0 );329 return commaExpr;330 331 332 }333 334 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {335 336 337 338 339 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );340 341 342 }343 344 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {345 346 347 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );348 349 350 351 352 353 354 355 356 }357 358 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {359 320 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 321 commaExpr->set_env( appExpr->get_env() ); 322 appExpr->set_env( 0 ); 323 return commaExpr; 324 } // if 325 return appExpr; 326 } 327 328 Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) { 329 ResolvExpr::EqvClass eqvClass; 330 assert( env ); 331 Type *concrete = env->lookup( typeName ); 332 if ( concrete == 0 ) { 333 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr ); 334 } // if 335 return addRetParam( appExpr, function, concrete, arg ); 336 } 337 338 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 339 Expression *ret = appExpr; 340 if ( ! function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) { 341 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg ); 342 } // if 343 std::string mangleName = SymTab::Mangler::mangle( function ); 344 std::string adapterName = makeAdapterName( mangleName ); 345 346 appExpr->get_args().push_front( appExpr->get_function() ); 347 appExpr->set_function( new NameExpr( adapterName ) ); 348 349 return ret; 350 } 351 352 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 353 assert( ! arg->get_results().empty() ); 360 354 /// if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) { 361 362 363 364 365 366 367 368 369 } else {370 371 372 373 374 375 376 377 378 } // if379 355 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param ); 356 if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) { 357 if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) { 358 // if the argument's type is a type parameter, we don't need to box again! 359 return; 360 } else if ( arg->get_results().front()->get_isLvalue() ) { 361 // VariableExpr and MemberExpr are lvalues 362 arg = new AddressExpr( arg ); 363 } else { 364 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 ); 365 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); 366 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 367 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 368 assign->get_args().push_back( new VariableExpr( newObj ) ); 369 assign->get_args().push_back( arg ); 370 stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) ); 371 arg = new AddressExpr( new VariableExpr( newObj ) ); 372 } // if 373 } // if 380 374 /// } 381 }382 383 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {384 385 386 387 388 389 390 actual = new CastExpr( actual, newType );391 392 delete newType;393 394 }395 396 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {375 } 376 377 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) { 378 Type *newType = formal->clone(); 379 std::list< FunctionType *> functions; 380 // instead of functions needing adapters, this really ought to look for 381 // any function mentioning a polymorphic type 382 findAndReplaceFunction( newType, functions, tyVars, needsAdapter ); 383 if ( ! functions.empty() ) { 384 actual = new CastExpr( actual, newType ); 385 } else { 386 delete newType; 387 } // if 388 } 389 390 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 397 391 /// std::cout << "function is "; 398 392 /// function->print( std::cout ); 399 393 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) { 400 394 /// std::cout << "parameter is "; 401 395 /// (*param)->print( std::fcout ); 402 396 /// std::cout << std::endl << "argument is "; 403 397 /// (*arg)->print( std::cout ); 404 assert( arg != appExpr->get_args().end() );405 addCast( *arg, (*param)->get_type(), exprTyVars );406 boxParam( (*param)->get_type(), *arg, exprTyVars );407 408 }409 410 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {411 412 413 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {414 415 416 417 418 419 420 } // for421 422 }423 424 void makeRetParm( FunctionType *funcType ) {425 426 427 428 429 430 431 432 433 }434 435 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {436 437 438 439 makeRetParm( adapter );440 441 442 443 }444 445 Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) {446 447 398 assert( arg != appExpr->get_args().end() ); 399 addCast( *arg, (*param)->get_type(), exprTyVars ); 400 boxParam( (*param)->get_type(), *arg, exprTyVars ); 401 } // for 402 } 403 404 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 405 std::list< Expression *>::iterator cur = arg; 406 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 407 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 408 InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() ); 409 assert( inferParam != appExpr->get_inferParams().end() ); 410 Expression *newExpr = inferParam->second.expr->clone(); 411 addCast( newExpr, (*assert)->get_type(), tyVars ); 412 boxParam( (*assert)->get_type(), newExpr, tyVars ); 413 appExpr->get_args().insert( cur, newExpr ); 414 } // for 415 } // for 416 } 417 418 void makeRetParm( FunctionType *funcType ) { 419 DeclarationWithType *retParm = funcType->get_returnVals().front(); 420 421 // make a new parameter that is a pointer to the type of the old return value 422 retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) ); 423 funcType->get_parameters().push_front( retParm ); 424 425 // we don't need the return value any more 426 funcType->get_returnVals().clear(); 427 } 428 429 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) { 430 // actually make the adapter type 431 FunctionType *adapter = adaptee->clone(); 432 if ( ! adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 433 makeRetParm( adapter ); 434 } // if 435 adapter->get_parameters().push_front( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ) ); 436 return adapter; 437 } 438 439 Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) { 440 assert( param ); 441 assert( arg ); 448 442 /// std::cout << "arg type is "; 449 443 /// arg->get_type()->print( std::cout ); … … 452 446 /// std::cout << " tyVars are: "; 453 447 /// printTyVarMap( std::cout, tyVars ); 454 448 if ( isPolyVal( realParam->get_type(), tyVars ) ) { 455 449 /// if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 456 450 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 457 451 /// } else { 458 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );459 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );460 deref->get_results().push_back( arg->get_type()->clone() );461 return deref;452 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 453 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 454 deref->get_results().push_back( arg->get_type()->clone() ); 455 return deref; 462 456 /// } 463 } // if 464 return new VariableExpr( param ); 465 } 466 467 void addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType *>::iterator arg, std::list< DeclarationWithType *>::iterator param, std::list< DeclarationWithType *>::iterator paramEnd, std::list< DeclarationWithType *>::iterator realParam, const TyVarMap &tyVars ) { 468 UniqueName paramNamer( "_p" ); 469 for ( ; param != paramEnd; ++param, ++arg, ++realParam ) { 470 if ( (*param)->get_name() == "" ) { 471 (*param)->set_name( paramNamer.newName() ); 472 (*param)->set_linkage( LinkageSpec::C ); 473 } // if 474 adapteeApp->get_args().push_back( makeAdapterArg( *param, *arg, *realParam, tyVars ) ); 475 } // for 476 } 477 478 479 480 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { 481 FunctionType *adapterType = makeAdapterType( adaptee, tyVars ); 482 adapterType = ScrubTyVars::scrub( adapterType, tyVars ); 483 DeclarationWithType *adapteeDecl = adapterType->get_parameters().front(); 484 adapteeDecl->set_name( "_adaptee" ); 485 ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) ); 486 Statement *bodyStmt; 487 488 std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin(); 489 std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin(); 490 std::list< TypeDecl *>::iterator realTyParam = adaptee->get_forall().begin(); 491 for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) { 492 assert( tyArg != realType->get_forall().end() ); 493 std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin(); 494 std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin(); 495 std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin(); 496 for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) { 497 assert( assertArg != (*tyArg)->get_assertions().end() ); 498 adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) ); 499 } // for 500 } // for 501 502 std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin(); 503 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin(); 504 std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin(); 505 param++; // skip adaptee parameter 506 if ( realType->get_returnVals().empty() ) { 507 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 508 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 509 } else if ( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 510 if ( (*param)->get_name() == "" ) { 511 (*param)->set_name( "_ret" ); 512 (*param)->set_linkage( LinkageSpec::C ); 513 } // if 514 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 515 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 516 deref->get_args().push_back( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) ); 517 assign->get_args().push_back( deref ); 518 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 519 assign->get_args().push_back( adapteeApp ); 520 bodyStmt = new ExprStmt( noLabels, assign ); 521 } else { 522 // adapter for a function that returns a monomorphic value 523 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 524 bodyStmt = new ReturnStmt( noLabels, adapteeApp ); 525 } // if 526 CompoundStmt *adapterBody = new CompoundStmt( noLabels ); 527 adapterBody->get_kids().push_back( bodyStmt ); 528 std::string adapterName = makeAdapterName( mangleName ); 529 return new FunctionDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false ); 530 } 531 532 void Pass1::passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ) { 533 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 534 std::list< FunctionType *> functions; 535 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 536 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 537 findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter ); 538 } // for 539 } // for 540 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 541 findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter ); 542 } // for 543 std::set< std::string > adaptersDone; 544 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 545 FunctionType *realFunction = (*funType)->clone(); 546 assert( env ); 547 env->apply( realFunction ); 548 549 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 550 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 551 AdapterMap & adapters = Pass1::adapters.top(); 552 AdapterMap::iterator adapter = adapters.find( mangleName ); 553 554 if ( needsAdapter( realFunction, exprTyVars, true ) ) { 555 // the function still contains type variables, which means we are in a polymorphic 556 // context and the adapter function is a parameter - call the parameter and don't 557 // create a new adapter. 558 appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) ); 559 continue; 560 } else if ( adapter == adapters.end() ) { 561 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 562 adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) ); 563 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 564 } // if 565 assert( adapter != adapters.end() ); 566 appExpr->get_args().push_front( new VariableExpr( adapter->second ) ); 567 // appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) ); 568 adaptersDone.insert( adaptersDone.begin(), mangleName ); 569 } // if 570 } // for 571 } 572 573 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 574 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 575 return isPolyType( ptr->get_base(), env, tyVars ); 576 } else if ( env ) { 577 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 578 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 579 return isPolyPtr( newType, env, tyVars ); 580 } // if 581 } // if 582 } // if 583 return 0; 584 } 585 586 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 587 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 588 return isPolyPtr( ptr->get_base(), env, tyVars ); 589 } else if ( env ) { 590 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 591 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 592 return isPolyPtrPtr( newType, env, tyVars ); 593 } // if 594 } // if 595 } // if 596 return 0; 597 } 598 599 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) { 600 NameExpr *opExpr; 601 if ( isIncr ) { 602 opExpr = new NameExpr( "?+=?" ); 603 } else { 604 opExpr = new NameExpr( "?-=?" ); 605 } // if 606 UntypedExpr *addAssign = new UntypedExpr( opExpr ); 607 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) { 608 addAssign->get_args().push_back( address->get_arg() ); 609 } else { 610 addAssign->get_args().push_back( appExpr->get_args().front() ); 611 } // if 612 addAssign->get_args().push_back( new NameExpr( polyName ) ); 613 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 614 if ( appExpr->get_env() ) { 615 addAssign->set_env( appExpr->get_env() ); 616 appExpr->set_env( 0 ); 617 } // if 618 appExpr->get_args().clear(); 619 delete appExpr; 620 return addAssign; 621 } 622 623 Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) { 624 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->get_function() ) ) { 625 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) { 626 if ( varExpr->get_var()->get_name() == "?[?]" ) { 627 assert( ! appExpr->get_results().empty() ); 628 assert( appExpr->get_args().size() == 2 ); 629 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars ); 630 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars ); 631 assert( ! typeInst1 || ! typeInst2 ); 632 UntypedExpr *ret = 0; 633 if ( typeInst1 || typeInst2 ) { 634 ret = new UntypedExpr( new NameExpr( "?+?" ) ); 635 } // if 636 if ( typeInst1 ) { 637 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 638 multiply->get_args().push_back( appExpr->get_args().back() ); 639 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 640 ret->get_args().push_back( appExpr->get_args().front() ); 641 ret->get_args().push_back( multiply ); 642 } else if ( typeInst2 ) { 643 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 644 multiply->get_args().push_back( appExpr->get_args().front() ); 645 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) ); 646 ret->get_args().push_back( multiply ); 647 ret->get_args().push_back( appExpr->get_args().back() ); 648 } // if 649 if ( typeInst1 || typeInst2 ) { 650 ret->get_results().push_front( appExpr->get_results().front()->clone() ); 651 if ( appExpr->get_env() ) { 652 ret->set_env( appExpr->get_env() ); 457 } // if 458 return new VariableExpr( param ); 459 } 460 461 void addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType *>::iterator arg, std::list< DeclarationWithType *>::iterator param, std::list< DeclarationWithType *>::iterator paramEnd, std::list< DeclarationWithType *>::iterator realParam, const TyVarMap &tyVars ) { 462 UniqueName paramNamer( "_p" ); 463 for ( ; param != paramEnd; ++param, ++arg, ++realParam ) { 464 if ( (*param)->get_name() == "" ) { 465 (*param)->set_name( paramNamer.newName() ); 466 (*param)->set_linkage( LinkageSpec::C ); 467 } // if 468 adapteeApp->get_args().push_back( makeAdapterArg( *param, *arg, *realParam, tyVars ) ); 469 } // for 470 } 471 472 473 474 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { 475 FunctionType *adapterType = makeAdapterType( adaptee, tyVars ); 476 adapterType = ScrubTyVars::scrub( adapterType, tyVars ); 477 DeclarationWithType *adapteeDecl = adapterType->get_parameters().front(); 478 adapteeDecl->set_name( "_adaptee" ); 479 ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) ); 480 Statement *bodyStmt; 481 482 std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin(); 483 std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin(); 484 std::list< TypeDecl *>::iterator realTyParam = adaptee->get_forall().begin(); 485 for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) { 486 assert( tyArg != realType->get_forall().end() ); 487 std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin(); 488 std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin(); 489 std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin(); 490 for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) { 491 assert( assertArg != (*tyArg)->get_assertions().end() ); 492 adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) ); 493 } // for 494 } // for 495 496 std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin(); 497 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin(); 498 std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin(); 499 param++; // skip adaptee parameter 500 if ( realType->get_returnVals().empty() ) { 501 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 502 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 503 } else if ( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 504 if ( (*param)->get_name() == "" ) { 505 (*param)->set_name( "_ret" ); 506 (*param)->set_linkage( LinkageSpec::C ); 507 } // if 508 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 509 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 510 deref->get_args().push_back( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) ); 511 assign->get_args().push_back( deref ); 512 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 513 assign->get_args().push_back( adapteeApp ); 514 bodyStmt = new ExprStmt( noLabels, assign ); 515 } else { 516 // adapter for a function that returns a monomorphic value 517 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 518 bodyStmt = new ReturnStmt( noLabels, adapteeApp ); 519 } // if 520 CompoundStmt *adapterBody = new CompoundStmt( noLabels ); 521 adapterBody->get_kids().push_back( bodyStmt ); 522 std::string adapterName = makeAdapterName( mangleName ); 523 return new FunctionDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false ); 524 } 525 526 void Pass1::passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ) { 527 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 528 std::list< FunctionType *> functions; 529 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 530 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 531 findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter ); 532 } // for 533 } // for 534 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 535 findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter ); 536 } // for 537 std::set< std::string > adaptersDone; 538 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 539 FunctionType *realFunction = (*funType)->clone(); 540 assert( env ); 541 env->apply( realFunction ); 542 543 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 544 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 545 AdapterMap & adapters = Pass1::adapters.top(); 546 AdapterMap::iterator adapter = adapters.find( mangleName ); 547 548 if ( needsAdapter( realFunction, exprTyVars, true ) ) { 549 // the function still contains type variables, which means we are in a polymorphic 550 // context and the adapter function is a parameter - call the parameter and don't 551 // create a new adapter. 552 appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) ); 553 continue; 554 } else if ( adapter == adapters.end() ) { 555 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 556 adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) ); 557 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 558 } // if 559 assert( adapter != adapters.end() ); 560 appExpr->get_args().push_front( new VariableExpr( adapter->second ) ); 561 // appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) ); 562 adaptersDone.insert( adaptersDone.begin(), mangleName ); 563 } // if 564 } // for 565 } 566 567 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 568 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 569 return isPolyType( ptr->get_base(), env, tyVars ); 570 } else if ( env ) { 571 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 572 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 573 return isPolyPtr( newType, env, tyVars ); 574 } // if 575 } // if 576 } // if 577 return 0; 578 } 579 580 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 581 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 582 return isPolyPtr( ptr->get_base(), env, tyVars ); 583 } else if ( env ) { 584 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 585 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 586 return isPolyPtrPtr( newType, env, tyVars ); 587 } // if 588 } // if 589 } // if 590 return 0; 591 } 592 593 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) { 594 NameExpr *opExpr; 595 if ( isIncr ) { 596 opExpr = new NameExpr( "?+=?" ); 597 } else { 598 opExpr = new NameExpr( "?-=?" ); 599 } // if 600 UntypedExpr *addAssign = new UntypedExpr( opExpr ); 601 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) { 602 addAssign->get_args().push_back( address->get_arg() ); 603 } else { 604 addAssign->get_args().push_back( appExpr->get_args().front() ); 605 } // if 606 addAssign->get_args().push_back( new NameExpr( polyName ) ); 607 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 608 if ( appExpr->get_env() ) { 609 addAssign->set_env( appExpr->get_env() ); 653 610 appExpr->set_env( 0 ); 654 } // if 655 appExpr->get_args().clear(); 656 delete appExpr; 657 return ret; 658 } // if 659 } else if ( varExpr->get_var()->get_name() == "*?" ) { 660 assert( ! appExpr->get_results().empty() ); 661 assert( ! appExpr->get_args().empty() ); 662 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) { 663 Expression *ret = appExpr->get_args().front(); 664 delete ret->get_results().front(); 665 ret->get_results().front() = appExpr->get_results().front()->clone(); 666 if ( appExpr->get_env() ) { 667 ret->set_env( appExpr->get_env() ); 668 appExpr->set_env( 0 ); 669 } // if 670 appExpr->get_args().clear(); 671 delete appExpr; 672 return ret; 673 } // if 674 } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) { 675 assert( ! appExpr->get_results().empty() ); 676 assert( appExpr->get_args().size() == 1 ); 677 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) { 678 Type *tempType = appExpr->get_results().front()->clone(); 679 if ( env ) { 680 env->apply( tempType ); 681 } // if 682 ObjectDecl *newObj = makeTemporary( tempType ); 683 VariableExpr *tempExpr = new VariableExpr( newObj ); 684 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 685 assignExpr->get_args().push_back( tempExpr->clone() ); 686 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) { 687 assignExpr->get_args().push_back( address->get_arg()->clone() ); 688 } else { 689 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 690 } // if 691 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) ); 692 return new CommaExpr( firstComma, tempExpr ); 693 } // if 694 } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) { 695 assert( ! appExpr->get_results().empty() ); 696 assert( appExpr->get_args().size() == 1 ); 697 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) { 698 return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" ); 699 } // if 700 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 701 assert( ! appExpr->get_results().empty() ); 702 assert( appExpr->get_args().size() == 2 ); 703 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars ); 704 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars ); 705 if ( typeInst1 && typeInst2 ) { 706 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 707 divide->get_args().push_back( appExpr ); 708 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 709 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 710 if ( appExpr->get_env() ) { 711 divide->set_env( appExpr->get_env() ); 712 appExpr->set_env( 0 ); 713 } // if 714 return divide; 715 } else if ( typeInst1 ) { 716 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 717 multiply->get_args().push_back( appExpr->get_args().back() ); 718 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 719 appExpr->get_args().back() = multiply; 720 } else if ( typeInst2 ) { 721 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 722 multiply->get_args().push_back( appExpr->get_args().front() ); 723 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) ); 724 appExpr->get_args().front() = multiply; 725 } // if 726 } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) { 727 assert( ! appExpr->get_results().empty() ); 728 assert( appExpr->get_args().size() == 2 ); 729 TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ); 730 if ( typeInst ) { 731 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 732 multiply->get_args().push_back( appExpr->get_args().back() ); 733 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) ); 734 appExpr->get_args().back() = multiply; 735 } // if 736 } // if 737 return appExpr; 738 } // if 739 } // if 740 return 0; 741 } 742 743 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 611 } // if 612 appExpr->get_args().clear(); 613 delete appExpr; 614 return addAssign; 615 } 616 617 Expression *Pass1::handleIntrinsics( ApplicationExpr *appExpr ) { 618 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->get_function() ) ) { 619 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) { 620 if ( varExpr->get_var()->get_name() == "?[?]" ) { 621 assert( ! appExpr->get_results().empty() ); 622 assert( appExpr->get_args().size() == 2 ); 623 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars ); 624 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars ); 625 assert( ! typeInst1 || ! typeInst2 ); 626 UntypedExpr *ret = 0; 627 if ( typeInst1 || typeInst2 ) { 628 ret = new UntypedExpr( new NameExpr( "?+?" ) ); 629 } // if 630 if ( typeInst1 ) { 631 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 632 multiply->get_args().push_back( appExpr->get_args().back() ); 633 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 634 ret->get_args().push_back( appExpr->get_args().front() ); 635 ret->get_args().push_back( multiply ); 636 } else if ( typeInst2 ) { 637 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 638 multiply->get_args().push_back( appExpr->get_args().front() ); 639 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) ); 640 ret->get_args().push_back( multiply ); 641 ret->get_args().push_back( appExpr->get_args().back() ); 642 } // if 643 if ( typeInst1 || typeInst2 ) { 644 ret->get_results().push_front( appExpr->get_results().front()->clone() ); 645 if ( appExpr->get_env() ) { 646 ret->set_env( appExpr->get_env() ); 647 appExpr->set_env( 0 ); 648 } // if 649 appExpr->get_args().clear(); 650 delete appExpr; 651 return ret; 652 } // if 653 } else if ( varExpr->get_var()->get_name() == "*?" ) { 654 assert( ! appExpr->get_results().empty() ); 655 assert( ! appExpr->get_args().empty() ); 656 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) { 657 Expression *ret = appExpr->get_args().front(); 658 delete ret->get_results().front(); 659 ret->get_results().front() = appExpr->get_results().front()->clone(); 660 if ( appExpr->get_env() ) { 661 ret->set_env( appExpr->get_env() ); 662 appExpr->set_env( 0 ); 663 } // if 664 appExpr->get_args().clear(); 665 delete appExpr; 666 return ret; 667 } // if 668 } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) { 669 assert( ! appExpr->get_results().empty() ); 670 assert( appExpr->get_args().size() == 1 ); 671 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) { 672 Type *tempType = appExpr->get_results().front()->clone(); 673 if ( env ) { 674 env->apply( tempType ); 675 } // if 676 ObjectDecl *newObj = makeTemporary( tempType ); 677 VariableExpr *tempExpr = new VariableExpr( newObj ); 678 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 679 assignExpr->get_args().push_back( tempExpr->clone() ); 680 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) { 681 assignExpr->get_args().push_back( address->get_arg()->clone() ); 682 } else { 683 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 684 } // if 685 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) ); 686 return new CommaExpr( firstComma, tempExpr ); 687 } // if 688 } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) { 689 assert( ! appExpr->get_results().empty() ); 690 assert( appExpr->get_args().size() == 1 ); 691 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) { 692 return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" ); 693 } // if 694 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 695 assert( ! appExpr->get_results().empty() ); 696 assert( appExpr->get_args().size() == 2 ); 697 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars ); 698 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars ); 699 if ( typeInst1 && typeInst2 ) { 700 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 701 divide->get_args().push_back( appExpr ); 702 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 703 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 704 if ( appExpr->get_env() ) { 705 divide->set_env( appExpr->get_env() ); 706 appExpr->set_env( 0 ); 707 } // if 708 return divide; 709 } else if ( typeInst1 ) { 710 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 711 multiply->get_args().push_back( appExpr->get_args().back() ); 712 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) ); 713 appExpr->get_args().back() = multiply; 714 } else if ( typeInst2 ) { 715 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 716 multiply->get_args().push_back( appExpr->get_args().front() ); 717 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) ); 718 appExpr->get_args().front() = multiply; 719 } // if 720 } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) { 721 assert( ! appExpr->get_results().empty() ); 722 assert( appExpr->get_args().size() == 2 ); 723 TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ); 724 if ( typeInst ) { 725 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 726 multiply->get_args().push_back( appExpr->get_args().back() ); 727 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) ); 728 appExpr->get_args().back() = multiply; 729 } // if 730 } // if 731 return appExpr; 732 } // if 733 } // if 734 return 0; 735 } 736 737 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 744 738 /// std::cerr << "mutate appExpr: "; 745 739 /// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { … … 747 741 /// } 748 742 /// std::cerr << "\n"; 749 750 751 752 753 754 755 756 757 758 759 760 761 762 return newExpr;763 764 765 766 767 768 769 770 771 772 ret = addPolyRetParam( appExpr, function, typeName, arg );773 743 bool oldUseRetval = useRetval; 744 useRetval = false; 745 appExpr->get_function()->acceptMutator( *this ); 746 mutateAll( appExpr->get_args(), *this ); 747 useRetval = oldUseRetval; 748 749 assert( ! appExpr->get_function()->get_results().empty() ); 750 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 751 assert( pointer ); 752 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 753 assert( function ); 754 755 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { 756 return newExpr; 757 } // if 758 759 Expression *ret = appExpr; 760 761 std::list< Expression *>::iterator arg = appExpr->get_args().begin(); 762 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 763 764 std::string typeName; 765 if ( isPolyRet( function, typeName ) ) { 766 ret = addPolyRetParam( appExpr, function, typeName, arg ); 767 } else if ( needsAdapter( function, scopeTyVars ) ) { 774 768 /// std::cerr << "needs adapter: "; 775 769 /// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { … … 777 771 /// } 778 772 /// std::cerr << "\n"; 779 // change the application so it calls the adapter rather than the passed function 780 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); 781 } // if 782 arg = appExpr->get_args().begin(); 783 784 TyVarMap exprTyVars; 785 makeTyVarMap( function, exprTyVars ); 786 787 passTypeVars( appExpr, arg, exprTyVars ); 788 addInferredParams( appExpr, function, arg, exprTyVars ); 789 790 arg = paramBegin; 791 792 boxParams( appExpr, function, arg, exprTyVars ); 793 794 passAdapters( appExpr, function, exprTyVars ); 795 796 return ret; 797 } 798 799 Expression *Pass1::mutate( UntypedExpr *expr ) { 800 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) { 801 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 802 if ( name->get_name() == "*?" ) { 803 Expression *ret = expr->get_args().front(); 804 expr->get_args().clear(); 805 delete expr; 806 return ret->acceptMutator( *this ); 807 } // if 808 } // if 809 } // if 810 return PolyMutator::mutate( expr ); 811 } 812 813 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 814 assert( ! addrExpr->get_arg()->get_results().empty() ); 815 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 816 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) { 817 Expression *ret = addrExpr->get_arg(); 818 delete ret->get_results().front(); 819 ret->get_results().front() = addrExpr->get_results().front()->clone(); 820 addrExpr->set_arg( 0 ); 821 delete addrExpr; 822 return ret; 823 } else { 824 return addrExpr; 825 } // if 826 } 827 828 Statement * 829 Pass1::mutate(ReturnStmt *retStmt) { 830 // a cast expr on a polymorphic return value is either redundant or invalid 831 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 832 retStmt->set_expr( castExpr->get_arg() ); 833 retStmt->get_expr()->set_env( castExpr->get_env() ); 834 castExpr->set_env( 0 ); 835 castExpr->set_arg( 0 ); 836 delete castExpr; 837 } 838 if ( retval && retStmt->get_expr() ) { 839 assert( ! retStmt->get_expr()->get_results().empty() ); 840 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 773 // change the application so it calls the adapter rather than the passed function 774 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); 775 } // if 776 arg = appExpr->get_args().begin(); 777 778 TyVarMap exprTyVars; 779 makeTyVarMap( function, exprTyVars ); 780 781 passTypeVars( appExpr, arg, exprTyVars ); 782 addInferredParams( appExpr, function, arg, exprTyVars ); 783 784 arg = paramBegin; 785 786 boxParams( appExpr, function, arg, exprTyVars ); 787 788 passAdapters( appExpr, function, exprTyVars ); 789 790 return ret; 791 } 792 793 Expression *Pass1::mutate( UntypedExpr *expr ) { 794 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) { 795 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 796 if ( name->get_name() == "*?" ) { 797 Expression *ret = expr->get_args().front(); 798 expr->get_args().clear(); 799 delete expr; 800 return ret->acceptMutator( *this ); 801 } // if 802 } // if 803 } // if 804 return PolyMutator::mutate( expr ); 805 } 806 807 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 808 assert( ! addrExpr->get_arg()->get_results().empty() ); 809 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 810 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) { 811 Expression *ret = addrExpr->get_arg(); 812 delete ret->get_results().front(); 813 ret->get_results().front() = addrExpr->get_results().front()->clone(); 814 addrExpr->set_arg( 0 ); 815 delete addrExpr; 816 return ret; 817 } else { 818 return addrExpr; 819 } // if 820 } 821 822 Statement * Pass1::mutate(ReturnStmt *retStmt) { 823 // a cast expr on a polymorphic return value is either redundant or invalid 824 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 825 retStmt->set_expr( castExpr->get_arg() ); 826 retStmt->get_expr()->set_env( castExpr->get_env() ); 827 castExpr->set_env( 0 ); 828 castExpr->set_arg( 0 ); 829 delete castExpr; 830 } 831 if ( retval && retStmt->get_expr() ) { 832 assert( ! retStmt->get_expr()->get_results().empty() ); 833 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 841 834 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 842 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 843 assert( typeInst ); 844 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 845 if ( assignIter == assignOps.end() ) { 846 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 847 } // if 848 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 849 Expression *retParm = new NameExpr( retval->get_name() ); 850 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 851 assignExpr->get_args().push_back( retParm ); 852 assignExpr->get_args().push_back( retStmt->get_expr() ); 853 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 854 } else { 855 useRetval = true; 856 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 857 useRetval = false; 858 } // if 859 retStmt->set_expr( 0 ); 860 } else { 861 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 862 } // if 863 return retStmt; 864 } 865 866 Type * 867 Pass1::mutate( PointerType *pointerType ) { 868 TyVarMap oldtyVars = scopeTyVars; 869 makeTyVarMap( pointerType, scopeTyVars ); 870 871 Type *ret = Mutator::mutate( pointerType ); 872 873 scopeTyVars = oldtyVars; 874 return ret; 875 } 876 877 Type * 878 Pass1::mutate( FunctionType *functionType ) { 879 TyVarMap oldtyVars = scopeTyVars; 880 makeTyVarMap( functionType, scopeTyVars ); 881 882 Type *ret = Mutator::mutate( functionType ); 883 884 scopeTyVars = oldtyVars; 885 return ret; 886 } 887 888 void Pass1::doBeginScope() { 889 adapters.push(AdapterMap()); 890 } 891 892 void Pass1::doEndScope() { 893 adapters.pop(); 894 } 835 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 836 assert( typeInst ); 837 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 838 if ( assignIter == assignOps.end() ) { 839 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 840 } // if 841 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 842 Expression *retParm = new NameExpr( retval->get_name() ); 843 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 844 assignExpr->get_args().push_back( retParm ); 845 assignExpr->get_args().push_back( retStmt->get_expr() ); 846 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 847 } else { 848 useRetval = true; 849 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 850 useRetval = false; 851 } // if 852 retStmt->set_expr( 0 ); 853 } else { 854 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 855 } // if 856 return retStmt; 857 } 858 859 Type * Pass1::mutate( PointerType *pointerType ) { 860 TyVarMap oldtyVars = scopeTyVars; 861 makeTyVarMap( pointerType, scopeTyVars ); 862 863 Type *ret = Mutator::mutate( pointerType ); 864 865 scopeTyVars = oldtyVars; 866 return ret; 867 } 868 869 Type * Pass1::mutate( FunctionType *functionType ) { 870 TyVarMap oldtyVars = scopeTyVars; 871 makeTyVarMap( functionType, scopeTyVars ); 872 873 Type *ret = Mutator::mutate( functionType ); 874 875 scopeTyVars = oldtyVars; 876 return ret; 877 } 878 879 void Pass1::doBeginScope() { 880 adapters.push(AdapterMap()); 881 } 882 883 void Pass1::doEndScope() { 884 adapters.pop(); 885 } 895 886 896 887 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 897 888 898 Pass2::Pass2() {}899 900 void Pass2::addAdapters( FunctionType *functionType ) {901 902 903 904 Type *orig = (*arg)->get_type();905 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );906 (*arg)->set_type( orig );907 908 909 910 std::string mangleName = SymTab::Mangler::mangle( *funType );911 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {912 913 914 915 }916 889 Pass2::Pass2() {} 890 891 void Pass2::addAdapters( FunctionType *functionType ) { 892 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 893 std::list< FunctionType *> functions; 894 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 895 Type *orig = (*arg)->get_type(); 896 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter ); 897 (*arg)->set_type( orig ); 898 } 899 std::set< std::string > adaptersDone; 900 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 901 std::string mangleName = SymTab::Mangler::mangle( *funType ); 902 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 903 std::string adapterName = makeAdapterName( mangleName ); 904 paramList.push_front( new ObjectDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) ); 905 adaptersDone.insert( adaptersDone.begin(), mangleName ); 906 } 907 } 917 908 /// deleteAll( functions ); 918 } 919 920 template< typename DeclClass > 921 DeclClass * 922 Pass2::handleDecl( DeclClass *decl, Type *type ) { 923 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 924 925 return ret; 926 } 927 928 DeclarationWithType * 929 Pass2::mutate( FunctionDecl *functionDecl ) { 930 return handleDecl( functionDecl, functionDecl->get_functionType() ); 931 } 932 933 ObjectDecl * 934 Pass2::mutate( ObjectDecl *objectDecl ) { 935 return handleDecl( objectDecl, objectDecl->get_type() ); 936 } 937 938 TypeDecl * 939 Pass2::mutate( TypeDecl *typeDecl ) { 940 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 941 if ( typeDecl->get_base() ) { 942 return handleDecl( typeDecl, typeDecl->get_base() ); 943 } else { 944 return Mutator::mutate( typeDecl ); 945 } 946 } 947 948 TypedefDecl * 949 Pass2::mutate( TypedefDecl *typedefDecl ) { 950 return handleDecl( typedefDecl, typedefDecl->get_base() ); 951 } 952 953 Type * 954 Pass2::mutate( PointerType *pointerType ) { 955 TyVarMap oldtyVars = scopeTyVars; 956 makeTyVarMap( pointerType, scopeTyVars ); 957 958 Type *ret = Mutator::mutate( pointerType ); 959 960 scopeTyVars = oldtyVars; 961 return ret; 962 } 963 964 Type *Pass2::mutate( FunctionType *funcType ) { 965 TyVarMap oldtyVars = scopeTyVars; 966 makeTyVarMap( funcType, scopeTyVars ); 967 968 std::string typeName; 969 if ( isPolyRet( funcType, typeName ) ) { 970 DeclarationWithType *ret = funcType->get_returnVals().front(); 971 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) ); 972 funcType->get_parameters().push_front( ret ); 973 funcType->get_returnVals().pop_front(); 974 } 975 976 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 977 std::list< DeclarationWithType *> inferredParams; 978 ObjectDecl *newObj = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 909 } 910 911 template< typename DeclClass > 912 DeclClass * Pass2::handleDecl( DeclClass *decl, Type *type ) { 913 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 914 915 return ret; 916 } 917 918 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) { 919 return handleDecl( functionDecl, functionDecl->get_functionType() ); 920 } 921 922 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) { 923 return handleDecl( objectDecl, objectDecl->get_type() ); 924 } 925 926 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) { 927 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 928 if ( typeDecl->get_base() ) { 929 return handleDecl( typeDecl, typeDecl->get_base() ); 930 } else { 931 return Mutator::mutate( typeDecl ); 932 } 933 } 934 935 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) { 936 return handleDecl( typedefDecl, typedefDecl->get_base() ); 937 } 938 939 Type * Pass2::mutate( PointerType *pointerType ) { 940 TyVarMap oldtyVars = scopeTyVars; 941 makeTyVarMap( pointerType, scopeTyVars ); 942 943 Type *ret = Mutator::mutate( pointerType ); 944 945 scopeTyVars = oldtyVars; 946 return ret; 947 } 948 949 Type *Pass2::mutate( FunctionType *funcType ) { 950 TyVarMap oldtyVars = scopeTyVars; 951 makeTyVarMap( funcType, scopeTyVars ); 952 953 std::string typeName; 954 if ( isPolyRet( funcType, typeName ) ) { 955 DeclarationWithType *ret = funcType->get_returnVals().front(); 956 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) ); 957 funcType->get_parameters().push_front( ret ); 958 funcType->get_returnVals().pop_front(); 959 } 960 961 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 962 std::list< DeclarationWithType *> inferredParams; 963 ObjectDecl *newObj = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 979 964 /// ObjectDecl *newFunPtr = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 980 981 ObjectDecl *thisParm;982 if ( (*tyParm)->get_kind() == TypeDecl::Any ) {983 984 985 986 987 }988 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {965 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 966 ObjectDecl *thisParm; 967 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 968 thisParm = newObj->clone(); 969 thisParm->set_name( (*tyParm)->get_name() ); 970 last = funcType->get_parameters().insert( last, thisParm ); 971 ++last; 972 } 973 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 989 974 /// *assert = (*assert)->acceptMutator( *this ); 990 991 }992 (*tyParm)->get_assertions().clear();993 994 995 996 997 998 999 1000 1001 1002 }975 inferredParams.push_back( *assert ); 976 } 977 (*tyParm)->get_assertions().clear(); 978 } 979 delete newObj; 980 funcType->get_parameters().splice( last, inferredParams ); 981 addAdapters( funcType ); 982 mutateAll( funcType->get_returnVals(), *this ); 983 mutateAll( funcType->get_parameters(), *this ); 984 985 scopeTyVars = oldtyVars; 986 return funcType; 987 } 1003 988 1004 989 ////////////////////////////////////////// Pass3 //////////////////////////////////////////////////// 1005 990 1006 template< typename DeclClass > 1007 DeclClass * 1008 Pass3::handleDecl( DeclClass *decl, Type *type ) { 1009 TyVarMap oldtyVars = scopeTyVars; 1010 makeTyVarMap( type, scopeTyVars ); 1011 1012 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1013 ScrubTyVars::scrub( decl, scopeTyVars ); 1014 1015 scopeTyVars = oldtyVars; 1016 return ret; 1017 } 1018 1019 ObjectDecl * 1020 Pass3::mutate( ObjectDecl *objectDecl ) { 1021 return handleDecl( objectDecl, objectDecl->get_type() ); 1022 } 1023 1024 DeclarationWithType * 1025 Pass3::mutate( FunctionDecl *functionDecl ) { 1026 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1027 } 1028 1029 TypedefDecl * 1030 Pass3::mutate( TypedefDecl *typedefDecl ) { 1031 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1032 } 1033 1034 TypeDecl * 1035 Pass3::mutate( TypeDecl *typeDecl ) { 991 template< typename DeclClass > 992 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) { 993 TyVarMap oldtyVars = scopeTyVars; 994 makeTyVarMap( type, scopeTyVars ); 995 996 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 997 ScrubTyVars::scrub( decl, scopeTyVars ); 998 999 scopeTyVars = oldtyVars; 1000 return ret; 1001 } 1002 1003 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) { 1004 return handleDecl( objectDecl, objectDecl->get_type() ); 1005 } 1006 1007 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) { 1008 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1009 } 1010 1011 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) { 1012 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1013 } 1014 1015 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1036 1016 /// Initializer *init = 0; 1037 1017 /// std::list< Expression *> designators; … … 1042 1022 /// return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1043 1023 1044 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1045 return Mutator::mutate( typeDecl ); 1046 } 1047 1048 Type * 1049 Pass3::mutate( PointerType *pointerType ) { 1050 TyVarMap oldtyVars = scopeTyVars; 1051 makeTyVarMap( pointerType, scopeTyVars ); 1052 1053 Type *ret = Mutator::mutate( pointerType ); 1054 1055 scopeTyVars = oldtyVars; 1056 return ret; 1057 } 1058 1059 Type * 1060 Pass3::mutate( FunctionType *functionType ) { 1061 TyVarMap oldtyVars = scopeTyVars; 1062 makeTyVarMap( functionType, scopeTyVars ); 1063 1064 Type *ret = Mutator::mutate( functionType ); 1065 1066 scopeTyVars = oldtyVars; 1067 return ret; 1068 } 1069 1070 Statement *Pass3::mutate( DeclStmt *declStmt ) { 1071 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1072 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) { 1073 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1074 assert( typeInst ); 1075 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1076 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) ); 1077 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 1078 assign->get_args().push_back( new VariableExpr( objectDecl ) ); 1079 assign->get_args().push_back( alloc ); 1080 stmtsToAddAfter.push_back( new ExprStmt( noLabels, assign ) ); 1081 } 1082 } 1083 return Mutator::mutate( declStmt ); 1084 } 1085 1086 } // anonymous namespace 1087 1024 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1025 return Mutator::mutate( typeDecl ); 1026 } 1027 1028 Type * Pass3::mutate( PointerType *pointerType ) { 1029 TyVarMap oldtyVars = scopeTyVars; 1030 makeTyVarMap( pointerType, scopeTyVars ); 1031 1032 Type *ret = Mutator::mutate( pointerType ); 1033 1034 scopeTyVars = oldtyVars; 1035 return ret; 1036 } 1037 1038 Type * Pass3::mutate( FunctionType *functionType ) { 1039 TyVarMap oldtyVars = scopeTyVars; 1040 makeTyVarMap( functionType, scopeTyVars ); 1041 1042 Type *ret = Mutator::mutate( functionType ); 1043 1044 scopeTyVars = oldtyVars; 1045 return ret; 1046 } 1047 1048 Statement *Pass3::mutate( DeclStmt *declStmt ) { 1049 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1050 if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) { 1051 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1052 assert( typeInst ); 1053 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1054 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) ); 1055 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 1056 assign->get_args().push_back( new VariableExpr( objectDecl ) ); 1057 assign->get_args().push_back( alloc ); 1058 stmtsToAddAfter.push_back( new ExprStmt( noLabels, assign ) ); 1059 } 1060 } 1061 return Mutator::mutate( declStmt ); 1062 } 1063 } // anonymous namespace 1088 1064 } // namespace GenPoly 1065 1089 1066 // Local Variables: // 1090 1067 // tab-width: 4 // -
translator/GenPoly/Box.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // Box.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:32:33 2015 13 // Update Count : 2 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: Box.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 #ifndef GENPOLY_BOX_H23 #define GENPOLY_BOX_H16 #ifndef _BOX_H 17 #define _BOX_H 24 18 25 19 #include <list> 26 27 20 #include "SynTree/SynTree.h" 28 21 29 22 namespace GenPoly { 30 31 void box( std::list< Declaration* >& translationUnit ); 32 23 void box( std::list< Declaration* >& translationUnit ); 33 24 } // namespace GenPoly 34 25 35 #endif /* #ifndef GENPOLY_BOX_H */ 26 #endif // _BOX_H 27 36 28 // Local Variables: // 37 29 // tab-width: 4 // -
translator/GenPoly/CopyParams.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // CopyParams.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:33:31 2015 13 // Update Count : 1 14 14 // 15 15 16 #include <set> 16 17 #include <map> … … 24 25 #include "UniqueName.h" 25 26 27 namespace GenPoly { 28 class CopyParams : public Visitor { 29 public: 30 CopyParams(); 31 32 virtual void visit( FunctionDecl *funcDecl ); 33 virtual void visit( AddressExpr *addrExpr ); 26 34 27 namespace GenPoly { 28 class CopyParams : public Visitor { 29 public: 30 CopyParams(); 31 32 virtual void visit( FunctionDecl *funcDecl ); 33 virtual void visit( AddressExpr *addrExpr ); 35 private: 36 std::set< UniqueId > modVars; 37 UniqueName namer; 38 }; 34 39 35 private: 36 std::set< UniqueId > modVars;37 UniqueName namer;38 }; 40 void copyParams( std::list< Declaration* > &translationUnit ) { 41 CopyParams copier; 42 acceptAll( translationUnit, copier ); 43 } 39 44 40 void copyParams( std::list< Declaration* > &translationUnit ) { 41 CopyParams copier; 42 acceptAll( translationUnit, copier ); 43 } 45 CopyParams::CopyParams() : namer( "_cp" ) {} 44 46 45 CopyParams::CopyParams() : namer( "_cp" ) {} 47 static const std::list< Label > noLabels; 46 48 47 static const std::list< Label > noLabels; 49 void CopyParams::visit( FunctionDecl *funcDecl ) { 50 if ( funcDecl->get_statements() ) { 51 funcDecl->get_statements()->accept( *this ); 52 53 if ( ! modVars.empty() ) { 54 std::map< std::string, DeclarationWithType* > assignOps; 55 // assume the assignment operator is the first assert param after any "type" parameter 56 for ( std::list< TypeDecl* >::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) { 57 if ( (*tyVar)->get_kind() == TypeDecl::Any ) { 58 assert( !(*tyVar)->get_assertions().empty() ); 59 assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front(); 60 } // if 61 } // for 62 for ( std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin(); param != funcDecl->get_functionType()->get_parameters().end(); ++param ) { 63 std::set< UniqueId >::const_iterator var = modVars.find( (*param)->get_uniqueId() ); 64 if ( var != modVars.end() ) { 65 TypeInstType *typeInst = dynamic_cast< TypeInstType* >( (*param)->get_type() ); 66 assert( typeInst ); 67 std::map< std::string, DeclarationWithType* >::const_iterator assignOp = assignOps.find( typeInst->get_name() ); 68 if ( assignOp != assignOps.end() ) { 69 DeclarationWithType *oldParam = *param; 70 *param = (*param)->clone(); 71 (*param)->set_mangleName( namer.newName( (*param)->get_mangleName() ) ); 72 ApplicationExpr *assign = new ApplicationExpr( new VariableExpr( assignOp->second ) ); 73 assign->get_args().push_back( new VariableExpr( oldParam ) ); 74 assign->get_args().push_back( new VariableExpr( *param ) ); 75 funcDecl->get_statements()->get_kids().push_front( new ExprStmt( noLabels, assign ) ); 76 funcDecl->get_statements()->get_kids().push_front( new DeclStmt( noLabels, oldParam ) ); 77 } // if 78 modVars.erase( var ); 79 } // if 80 } // for 81 } // if 82 } // if 83 } 48 84 49 void CopyParams::visit( FunctionDecl *funcDecl ) { 50 if ( funcDecl->get_statements() ) { 51 funcDecl->get_statements()->accept( *this ); 52 53 if ( ! modVars.empty() ) { 54 std::map< std::string, DeclarationWithType* > assignOps; 55 // assume the assignment operator is the first assert param after any "type" parameter 56 for ( std::list< TypeDecl* >::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) { 57 if ( (*tyVar)->get_kind() == TypeDecl::Any ) { 58 assert( !(*tyVar)->get_assertions().empty() ); 59 assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front(); 60 } // if 61 } // for 62 for ( std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin(); param != funcDecl->get_functionType()->get_parameters().end(); ++param ) { 63 std::set< UniqueId >::const_iterator var = modVars.find( (*param)->get_uniqueId() ); 64 if ( var != modVars.end() ) { 65 TypeInstType *typeInst = dynamic_cast< TypeInstType* >( (*param)->get_type() ); 66 assert( typeInst ); 67 std::map< std::string, DeclarationWithType* >::const_iterator assignOp = assignOps.find( typeInst->get_name() ); 68 if ( assignOp != assignOps.end() ) { 69 DeclarationWithType *oldParam = *param; 70 *param = (*param)->clone(); 71 (*param)->set_mangleName( namer.newName( (*param)->get_mangleName() ) ); 72 ApplicationExpr *assign = new ApplicationExpr( new VariableExpr( assignOp->second ) ); 73 assign->get_args().push_back( new VariableExpr( oldParam ) ); 74 assign->get_args().push_back( new VariableExpr( *param ) ); 75 funcDecl->get_statements()->get_kids().push_front( new ExprStmt( noLabels, assign ) ); 76 funcDecl->get_statements()->get_kids().push_front( new DeclStmt( noLabels, oldParam ) ); 85 // this test is insufficient because it is possible for values to be modified by being passed to other polymorphic 86 // routines (e.g., assignment operators) without having their addresses explicitly taken. Some thought is needed to 87 // make sure that all of the correct cases are identified where copies are necessary. 88 // 89 // As a temporary measure, for correctness at the expense of performance, ignore the modVars list entirely and copy 90 // every parameter of TypeInstType* when visiting the FunctionDecl. 91 void CopyParams::visit( AddressExpr *addrExpr ) { 92 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( addrExpr->get_arg() ) ) { 93 if ( dynamic_cast< TypeInstType* >( varExpr->get_var()->get_type() ) ) { 94 modVars.insert( varExpr->get_var()->get_uniqueId() ); 77 95 } // if 78 modVars.erase( var ); 79 } // if 80 } // for 81 } // if 82 } // if 83 } 96 } // if 97 } 98 } // namespace GenPoly 84 99 85 // this test is insufficient because it is possible for values to be modified by being passed to other polymorphic86 // routines (e.g., assignment operators) without having their addresses explicitly taken. Some thought is needed to87 // make sure that all of the correct cases are identified where copies are necessary.88 //89 // As a temporary measure, for correctness at the expense of performance, ignore the modVars list entirely and copy90 // every parameter of TypeInstType* when visiting the FunctionDecl.91 void CopyParams::visit( AddressExpr *addrExpr ) {92 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( addrExpr->get_arg() ) ) {93 if ( dynamic_cast< TypeInstType* >( varExpr->get_var()->get_type() ) ) {94 modVars.insert( varExpr->get_var()->get_uniqueId() );95 } // if96 } // if97 }98 } // namespace GenPoly99 100 // Local Variables: // 100 101 // tab-width: 4 // -
translator/GenPoly/CopyParams.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // CopyParams.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:34:25 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: CopyParams.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 #ifndef GENPOLY_COPYPARAMS_H23 #define GENPOLY_COPYPARAMS_H16 #ifndef _COPYPARAMS_H 17 #define _COPYPARAMS_H 24 18 25 19 #include "SynTree/SynTree.h" 26 20 27 21 namespace GenPoly { 28 29 void copyParams( std::list< Declaration* > &translationUnit ); 30 22 void copyParams( std::list< Declaration* > &translationUnit ); 31 23 } // namespace GenPoly 32 24 33 #endif /* #ifndef GENPOLY_COPYPARAMS_H */ 25 #endif // _COPYPARAMS_H 26 34 27 // Local Variables: // 35 28 // tab-width: 4 // -
translator/GenPoly/FindFunction.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // FindFunction.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:35:48 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: FindFunction.cc,v 1.5 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #include "FindFunction.h" … … 26 20 27 21 namespace GenPoly { 22 class FindFunction : public Mutator { 23 public: 24 FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ); 25 26 virtual Type *mutate( FunctionType *functionType ); 27 virtual Type *mutate( PointerType *pointerType ); 28 private: 29 void handleForall( const std::list< TypeDecl* > &forall ); 28 30 29 class FindFunction : public Mutator 30 { 31 public: 32 FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ); 33 34 virtual Type *mutate( FunctionType *functionType ); 35 virtual Type *mutate( PointerType *pointerType ); 36 37 private: 38 void handleForall( const std::list< TypeDecl* > &forall ); 31 std::list< FunctionType* > &functions; 32 TyVarMap tyVars; 33 bool replaceMode; 34 FindFunctionPredicate predicate; 35 }; 39 36 40 std::list< FunctionType* > &functions; 41 TyVarMap tyVars; 42 bool replaceMode; 43 FindFunctionPredicate predicate; 44 }; 37 void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 38 FindFunction finder( functions, tyVars, false, predicate ); 39 type->acceptMutator( finder ); 40 } 45 41 46 void 47 findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) 48 { 49 FindFunction finder( functions, tyVars, false, predicate ); 50 type->acceptMutator( finder ); 51 } 42 void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) { 43 FindFunction finder( functions, tyVars, true, predicate ); 44 type = type->acceptMutator( finder ); 45 } 52 46 53 void 54 findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ) 55 { 56 FindFunction finder( functions, tyVars, true, predicate ); 57 type = type->acceptMutator( finder ); 58 } 47 FindFunction::FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ) 48 : functions( functions ), tyVars( tyVars ), replaceMode( replaceMode ), predicate( predicate ) { 49 } 59 50 60 FindFunction::FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate ) 61 : functions( functions ), tyVars( tyVars ), replaceMode( replaceMode ), predicate( predicate ) 62 { 63 } 51 void FindFunction::handleForall( const std::list< TypeDecl* > &forall ) { 52 for ( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 53 TyVarMap::iterator var = tyVars.find( (*i)->get_name() ); 54 if ( var != tyVars.end() ) { 55 tyVars.erase( var ); 56 } // if 57 } // for 58 } 64 59 65 void 66 FindFunction::handleForall( const std::list< TypeDecl* > &forall ) 67 { 68 for ( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 69 TyVarMap::iterator var = tyVars.find( (*i)->get_name() ); 70 if ( var != tyVars.end() ) { 71 tyVars.erase( var ); 72 } 73 } 74 } 60 Type * FindFunction::mutate( FunctionType *functionType ) { 61 TyVarMap oldTyVars = tyVars; 62 handleForall( functionType->get_forall() ); 63 mutateAll( functionType->get_returnVals(), *this ); 64 Type *ret = functionType; 65 if ( predicate( functionType, tyVars ) ) { 66 functions.push_back( functionType ); 67 if ( replaceMode ) { 68 ret = new FunctionType( Type::Qualifiers(), true ); 69 } // if 70 } // if 71 tyVars = oldTyVars; 72 return ret; 73 } 75 74 76 Type* 77 FindFunction::mutate( FunctionType *functionType ) 78 { 79 TyVarMap oldTyVars = tyVars; 80 handleForall( functionType->get_forall() ); 81 mutateAll( functionType->get_returnVals(), *this ); 82 Type *ret = functionType; 83 if ( predicate( functionType, tyVars ) ) { 84 functions.push_back( functionType ); 85 if ( replaceMode ) { 86 ret = new FunctionType( Type::Qualifiers(), true ); 87 } 88 } 89 tyVars = oldTyVars; 90 return ret; 91 } 75 Type * FindFunction::mutate( PointerType *pointerType ) { 76 TyVarMap oldTyVars = tyVars; 77 handleForall( pointerType->get_forall() ); 78 Type *ret = Mutator::mutate( pointerType ); 79 tyVars = oldTyVars; 80 return ret; 81 } 82 } // namespace GenPoly 92 83 93 Type *94 FindFunction::mutate( PointerType *pointerType )95 {96 TyVarMap oldTyVars = tyVars;97 handleForall( pointerType->get_forall() );98 Type *ret = Mutator::mutate( pointerType );99 tyVars = oldTyVars;100 return ret;101 }102 103 } // namespace GenPoly104 84 // Local Variables: // 105 85 // tab-width: 4 // -
translator/GenPoly/FindFunction.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // FindFunction.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:36:35 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: FindFunction.h,v 1.4 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #ifndef FINDFUNCTION_H … … 27 21 28 22 namespace GenPoly { 23 typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& ); 29 24 30 typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& ); 31 32 void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 33 void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 34 25 void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 26 void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 35 27 } // namespace GenPoly 36 28 37 #endif /* #ifndef FINDFUNCTION_H */ 29 #endif // FINDFUNCTION_H 30 38 31 // Local Variables: // 39 32 // tab-width: 4 // -
translator/GenPoly/GenPoly.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // GenPoly.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:37:46 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: GenPoly.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #include "GenPoly.h" … … 27 21 28 22 namespace GenPoly { 23 // interface functions 24 bool isPolyVal( Type *type, const TyVarMap &tyVars ) { 25 return isPolyVal( type, tyVars, false ); 26 } 29 27 30 // interface functions 31 bool isPolyVal( Type *type, const TyVarMap &tyVars ) { 32 return isPolyVal( type, tyVars, false ); 33 } 28 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { 29 return needsAdapter( adaptee, tyVars, false ); 30 } 34 31 35 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { 36 return needsAdapter( adaptee, tyVars, false ); 37 } 32 bool isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars ) { 33 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) { 34 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 35 return true; 36 } // if 37 return considerAllTyVars; 38 } // if 39 return false; 40 } 38 41 39 bool 40 isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars ) 41 { 42 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) { 43 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 44 return true; 45 } 46 return considerAllTyVars; 47 } 48 return false; 49 } 42 // A function needs an adapter if it returns a polymorphic value or if any of its 43 // parameters have polymorphic type 44 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars ) { 45 bool needsAdapter = false; 46 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars, considerAllTyVars ) ) { 47 needsAdapter = true; 48 } // if 49 for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); ! needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) { 50 if ( isPolyVal( (*innerArg)->get_type(), tyVars, considerAllTyVars ) ) { 51 needsAdapter = true; 52 } // if 53 } // for 54 return needsAdapter; 55 } 50 56 51 // A function needs an adapter if it returns a polymorphic value or if any of its 52 // parameters have polymorphic type 53 bool 54 needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars ) 55 { 56 bool needsAdapter = false; 57 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars, considerAllTyVars ) ) { 58 needsAdapter = true; 59 } 60 for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); ! needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) { 61 if ( isPolyVal( (*innerArg)->get_type(), tyVars, considerAllTyVars ) ) { 62 needsAdapter = true; 63 } 64 } 65 66 return needsAdapter; 67 } 57 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { 58 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) { 59 os << i->first << " (" << i->second << ") "; 60 } // for 61 os << std::endl; 62 } 63 } // namespace GenPoly 68 64 69 void70 printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap )71 {72 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {73 os << i->first << " (" << i->second << ") ";74 }75 os << std::endl;76 }77 78 } // namespace GenPoly79 65 // Local Variables: // 80 66 // tab-width: 4 // -
translator/GenPoly/GenPoly.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // GenPoly.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:38:34 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: GenPoly.h,v 1.4 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #ifndef GENPOLY_H … … 29 23 30 24 namespace GenPoly { 25 typedef std::map< std::string, TypeDecl::Kind > TyVarMap; 31 26 32 typedef std::map< std::string, TypeDecl::Kind > TyVarMap; 27 // considerAllTyVars allows ignoring the contents of the TyVarMap parameter, for the situations where 28 // it is important only that a TypeInstType node exists. 33 29 34 // considerAllTyVars allows ignoring the contents of the TyVarMap parameter, for the situations where 35 // it is important only that a TypeInstType node exists. 36 37 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr ); 38 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars ); 39 bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars ); 40 bool isPolyVal( Type *type, const TyVarMap &tyVars ); 41 bool isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars ); 42 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 43 30 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr ); 31 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars, bool considerAllTyVars ); 32 bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars ); 33 bool isPolyVal( Type *type, const TyVarMap &tyVars ); 34 bool isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars ); 35 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 44 36 } // namespace GenPoly 45 37 46 #endif 38 #endif // GENPOLY_H 39 47 40 // Local Variables: // 48 41 // tab-width: 4 // -
translator/GenPoly/Lvalue.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // Lvalue.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:41:33 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: Lvalue.cc,v 1.5 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #include <cassert> … … 37 31 #include "utility.h" 38 32 33 namespace GenPoly { 34 namespace { 35 const std::list<Label> noLabels; 39 36 40 namespace GenPoly { 37 class Pass1 : public Mutator { 38 public: 39 Pass1(); 40 41 virtual Expression *mutate( ApplicationExpr *appExpr ); 42 virtual Statement *mutate( ReturnStmt *appExpr ); 43 virtual DeclarationWithType *mutate( FunctionDecl *funDecl ); 44 private: 45 DeclarationWithType* retval; 46 }; 41 47 42 namespace { 48 class Pass2 : public Visitor { 49 public: 50 virtual void visit( FunctionType *funType ); 51 private: 52 }; 53 } // namespace 43 54 44 const std::list<Label> noLabels; 55 void convertLvalue( std::list< Declaration* >& translationUnit ) { 56 Pass1 p1; 57 Pass2 p2; 58 mutateAll( translationUnit, p1 ); 59 acceptAll( translationUnit, p2 ); 60 } 45 61 46 class Pass1 : public Mutator 47 { 48 public: 49 Pass1(); 62 namespace { 63 bool isLvalueRet( FunctionType *function ) { 64 if ( ! function->get_returnVals().empty() ) { 65 return function->get_returnVals().front()->get_type()->get_isLvalue(); 66 } else { 67 return false; 68 } // if 69 } 70 71 bool isIntrinsicApp( ApplicationExpr *appExpr ) { 72 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) { 73 return varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic; 74 } else { 75 return false; 76 } // if 77 } 78 79 Pass1::Pass1() { 80 } 81 82 DeclarationWithType * Pass1::mutate( FunctionDecl *funcDecl ) { 83 if ( funcDecl->get_statements() ) { 84 DeclarationWithType* oldRetval = retval; 85 retval = 0; 86 if ( ! LinkageSpec::isBuiltin( funcDecl->get_linkage() ) && isLvalueRet( funcDecl->get_functionType() ) ) { 87 retval = funcDecl->get_functionType()->get_returnVals().front(); 88 } 89 // fix expressions and return statements in this function 90 funcDecl->set_statements( funcDecl->get_statements()->acceptMutator( *this ) ); 91 retval = oldRetval; 92 } // if 93 return funcDecl; 94 } 95 96 Expression * Pass1::mutate( ApplicationExpr *appExpr ) { 97 appExpr->get_function()->acceptMutator( *this ); 98 mutateAll( appExpr->get_args(), *this ); 50 99 51 virtual Expression *mutate( ApplicationExpr *appExpr ); 52 virtual Statement *mutate( ReturnStmt *appExpr ); 53 virtual DeclarationWithType *mutate( FunctionDecl *funDecl ); 100 assert( ! appExpr->get_function()->get_results().empty() ); 54 101 55 private: 56 DeclarationWithType* retval; 57 }; 102 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 103 assert( pointer ); 104 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 105 assert( function ); 58 106 59 class Pass2 : public Visitor 60 { 61 public: 62 virtual void visit( FunctionType *funType ); 107 std::string typeName; 108 if ( isLvalueRet( function ) && ! isIntrinsicApp( appExpr ) ) { 109 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 110 deref->get_results().push_back( appExpr->get_results().front() ); 111 appExpr->get_results().front() = new PointerType( Type::Qualifiers(), deref->get_results().front()->clone() ); 112 deref->get_args().push_back( appExpr ); 113 return deref; 114 } else { 115 return appExpr; 116 } // if 117 } 63 118 64 private: 65 }; 119 Statement * Pass1::mutate(ReturnStmt *retStmt) { 120 if ( retval && retStmt->get_expr() ) { 121 assert( ! retStmt->get_expr()->get_results().empty() ); 122 while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) { 123 retStmt->set_expr( castExpr->get_arg() ); 124 retStmt->get_expr()->set_env( castExpr->get_env() ); 125 castExpr->set_env( 0 ); 126 castExpr->set_arg( 0 ); 127 delete castExpr; 128 } // while 129 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 130 retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) ); 131 } else { 132 throw SemanticError( "Attempt to return non-lvalue from an lvalue-qualified function" ); 133 } // if 134 } // if 135 return retStmt; 136 } 66 137 67 } // namespace 138 void Pass2::visit( FunctionType *funType ) { 139 std::string typeName; 140 if ( isLvalueRet( funType ) ) { 141 DeclarationWithType *retParm = funType->get_returnVals().front(); 68 142 69 void 70 convertLvalue( std::list< Declaration* >& translationUnit ) 71 { 72 Pass1 p1;73 Pass2 p2;74 mutateAll( translationUnit, p1 ); 75 acceptAll( translationUnit, p2 ); 76 } 143 // make a new parameter that is a pointer to the type of the old return value 144 retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) ); 145 } // if 146 147 Visitor::visit( funType ); 148 } 149 } // namespace 150 } // namespace GenPoly 77 151 78 namespace {79 80 bool81 isLvalueRet( FunctionType *function )82 {83 if ( ! function->get_returnVals().empty() ) {84 return function->get_returnVals().front()->get_type()->get_isLvalue();85 } else {86 return false;87 }88 }89 90 bool91 isIntrinsicApp( ApplicationExpr *appExpr )92 {93 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) {94 return varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic;95 } else {96 return false;97 }98 }99 100 Pass1::Pass1()101 {102 }103 104 DeclarationWithType*105 Pass1::mutate( FunctionDecl *funcDecl )106 {107 if ( funcDecl->get_statements() ) {108 DeclarationWithType* oldRetval = retval;109 retval = 0;110 if ( ! LinkageSpec::isBuiltin( funcDecl->get_linkage() ) && isLvalueRet( funcDecl->get_functionType() ) ) {111 retval = funcDecl->get_functionType()->get_returnVals().front();112 }113 // fix expressions and return statements in this function114 funcDecl->set_statements( funcDecl->get_statements()->acceptMutator( *this ) );115 retval = oldRetval;116 }117 return funcDecl;118 }119 120 Expression*121 Pass1::mutate( ApplicationExpr *appExpr )122 {123 appExpr->get_function()->acceptMutator( *this );124 mutateAll( appExpr->get_args(), *this );125 126 assert( ! appExpr->get_function()->get_results().empty() );127 128 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );129 assert( pointer );130 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );131 assert( function );132 133 std::string typeName;134 if ( isLvalueRet( function ) && ! isIntrinsicApp( appExpr ) ) {135 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );136 deref->get_results().push_back( appExpr->get_results().front() );137 appExpr->get_results().front() = new PointerType( Type::Qualifiers(), deref->get_results().front()->clone() );138 deref->get_args().push_back( appExpr );139 return deref;140 } else {141 return appExpr;142 }143 }144 145 Statement*146 Pass1::mutate(ReturnStmt *retStmt)147 {148 if ( retval && retStmt->get_expr() ) {149 assert( ! retStmt->get_expr()->get_results().empty() );150 while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {151 retStmt->set_expr( castExpr->get_arg() );152 retStmt->get_expr()->set_env( castExpr->get_env() );153 castExpr->set_env( 0 );154 castExpr->set_arg( 0 );155 delete castExpr;156 }157 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {158 retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );159 } else {160 throw SemanticError( "Attempt to return non-lvalue from an lvalue-qualified function" );161 }162 }163 return retStmt;164 }165 166 void167 Pass2::visit( FunctionType *funType )168 {169 std::string typeName;170 if ( isLvalueRet( funType ) ) {171 DeclarationWithType *retParm = funType->get_returnVals().front();172 173 // make a new parameter that is a pointer to the type of the old return value174 retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );175 }176 177 Visitor::visit( funType );178 }179 180 } // namespace181 182 } // namespace GenPoly183 152 // Local Variables: // 184 153 // tab-width: 4 // -
translator/GenPoly/Lvalue.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // Lvalue.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:42:09 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: Lvalue.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 #ifndef GENPOLY_LVALUE_H23 #define GENPOLY_LVALUE_H16 #ifndef _LVALUE_H 17 #define _LVALUE_H 24 18 25 19 #include <list> … … 28 22 29 23 namespace GenPoly { 30 31 void convertLvalue( std::list< Declaration* >& translationUnit ); 32 24 void convertLvalue( std::list< Declaration* >& translationUnit ); 33 25 } // namespace GenPoly 34 26 35 #endif /* #ifndef GENPOLY_LVALUE_H */ 27 #endif // _LVALUE_H 28 36 29 // Local Variables: // 37 30 // tab-width: 4 // -
translator/GenPoly/PolyMutator.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // PolyMutator.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:45:50 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: PolyMutator.cc,v 1.7 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #include "PolyMutator.h" … … 29 23 30 24 namespace GenPoly { 25 namespace { 26 const std::list<Label> noLabels; 27 } 31 28 32 namespace { 33 const std::list<Label> noLabels; 34 } 29 PolyMutator::PolyMutator() : env( 0 ) { 30 } 35 31 36 PolyMutator::PolyMutator() 37 : env( 0 ) 38 { 39 } 32 void PolyMutator::mutateStatementList( std::list< Statement* > &statements ) { 33 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { 34 if ( ! stmtsToAddAfter.empty() ) { 35 statements.splice( i, stmtsToAddAfter ); 36 } // if 37 *i = (*i)->acceptMutator( *this ); 38 if ( ! stmtsToAdd.empty() ) { 39 statements.splice( i, stmtsToAdd ); 40 } // if 41 } // for 42 if ( ! stmtsToAddAfter.empty() ) { 43 statements.splice( statements.end(), stmtsToAddAfter ); 44 } // if 45 } 40 46 41 void 42 PolyMutator::mutateStatementList( std::list< Statement* > &statements ) 43 { 44 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { 45 if ( ! stmtsToAddAfter.empty() ) { 46 statements.splice( i, stmtsToAddAfter ); 47 } 48 *i = (*i)->acceptMutator( *this ); 49 if ( ! stmtsToAdd.empty() ) { 50 statements.splice( i, stmtsToAdd ); 51 } 52 } 53 if ( ! stmtsToAddAfter.empty() ) { 54 statements.splice( statements.end(), stmtsToAddAfter ); 55 } 56 } 47 Statement * PolyMutator::mutateStatement( Statement *stmt ) { 48 Statement *newStmt = maybeMutate( stmt, *this ); 49 if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) { 50 CompoundStmt *compound = new CompoundStmt( noLabels ); 51 compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd ); 52 compound->get_kids().push_back( newStmt ); 53 compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter ); 54 // doEndScope(); 55 return compound; 56 } else { 57 return newStmt; 58 } 59 } 57 60 58 Statement* 59 PolyMutator::mutateStatement( Statement *stmt ) 60 { 61 Statement *newStmt = maybeMutate( stmt, *this ); 62 if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) { 63 CompoundStmt *compound = new CompoundStmt( noLabels ); 64 compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd ); 65 compound->get_kids().push_back( newStmt ); 66 compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter ); 67 // doEndScope(); 68 return compound; 69 } else { 70 return newStmt; 71 } 72 } 61 Expression * PolyMutator::mutateExpression( Expression *expr ) { 62 if ( expr ) { 63 if ( expr->get_env() ) { 64 env = expr->get_env(); 65 } 66 return expr->acceptMutator( *this ); 67 } else { 68 return expr; 69 } 70 } 73 71 74 Expression* 75 PolyMutator::mutateExpression( Expression *expr ) 76 { 77 if ( expr ) { 78 if ( expr->get_env() ) { 79 env = expr->get_env(); 80 } 81 return expr->acceptMutator( *this ); 82 } else { 83 return expr; 84 } 85 } 72 CompoundStmt * PolyMutator::mutate(CompoundStmt *compoundStmt) { 73 doBeginScope(); 74 mutateStatementList( compoundStmt->get_kids() ); 75 doEndScope(); 76 return compoundStmt; 77 } 86 78 87 CompoundStmt* 88 PolyMutator::mutate(CompoundStmt *compoundStmt) 89 { 90 doBeginScope(); 91 mutateStatementList( compoundStmt->get_kids() ); 92 doEndScope(); 93 return compoundStmt; 94 } 79 Statement * PolyMutator::mutate(IfStmt *ifStmt) { 80 ifStmt->set_thenPart( mutateStatement( ifStmt->get_thenPart() ) ); 81 ifStmt->set_elsePart( mutateStatement( ifStmt->get_elsePart() ) ); 82 ifStmt->set_condition( mutateExpression( ifStmt->get_condition() ) ); 83 return ifStmt; 84 } 95 85 96 Statement* 97 PolyMutator::mutate(IfStmt *ifStmt) 98 { 99 ifStmt->set_thenPart( mutateStatement( ifStmt->get_thenPart() ) ); 100 ifStmt->set_elsePart( mutateStatement( ifStmt->get_elsePart() ) ); 101 ifStmt->set_condition( mutateExpression( ifStmt->get_condition() ) ); 102 return ifStmt; 103 } 86 Statement * PolyMutator::mutate(WhileStmt *whileStmt) { 87 whileStmt->set_body( mutateStatement( whileStmt->get_body() ) ); 88 whileStmt->set_condition( mutateExpression( whileStmt->get_condition() ) ); 89 return whileStmt; 90 } 104 91 105 Statement* 106 PolyMutator::mutate(WhileStmt *whileStmt) 107 { 108 whileStmt->set_body( mutateStatement( whileStmt->get_body() ) );109 whileStmt->set_condition( mutateExpression( whileStmt->get_condition() ) );110 return whileStmt;111 }92 Statement * PolyMutator::mutate(ForStmt *forStmt) { 93 forStmt->set_body( mutateStatement( forStmt->get_body() ) ); 94 forStmt->set_initialization( maybeMutate( forStmt->get_initialization(), *this ) ); 95 forStmt->set_condition( mutateExpression( forStmt->get_condition() ) ); 96 forStmt->set_increment( mutateExpression( forStmt->get_increment() ) ); 97 return forStmt; 98 } 112 99 113 Statement* 114 PolyMutator::mutate(ForStmt *forStmt) 115 { 116 forStmt->set_body( mutateStatement( forStmt->get_body() ) ); 117 forStmt->set_initialization( maybeMutate( forStmt->get_initialization(), *this ) ); 118 forStmt->set_condition( mutateExpression( forStmt->get_condition() ) ); 119 forStmt->set_increment( mutateExpression( forStmt->get_increment() ) ); 120 return forStmt; 121 } 100 Statement * PolyMutator::mutate(SwitchStmt *switchStmt) { 101 mutateStatementList( switchStmt->get_branches() ); 102 switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) ); 103 return switchStmt; 104 } 122 105 123 Statement* 124 PolyMutator::mutate(SwitchStmt *switchStmt) 125 { 126 mutateStatementList( switchStmt->get_branches() ); 127 switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) ); 128 return switchStmt; 129 } 106 Statement * PolyMutator::mutate(ChooseStmt *switchStmt) { 107 mutateStatementList( switchStmt->get_branches() ); 108 switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) ); 109 return switchStmt; 110 } 130 111 131 Statement* 132 PolyMutator::mutate(ChooseStmt *switchStmt) 133 { 134 mutateStatementList( switchStmt->get_branches() ); 135 switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) ); 136 return switchStmt; 137 } 112 Statement * PolyMutator::mutate(CaseStmt *caseStmt) { 113 mutateStatementList( caseStmt->get_statements() ); 114 caseStmt->set_condition( mutateExpression( caseStmt->get_condition() ) ); 115 return caseStmt; 116 } 138 117 139 Statement* 140 PolyMutator::mutate(CaseStmt *caseStmt) 141 { 142 mutateStatementList( caseStmt->get_statements() );143 caseStmt->set_condition( mutateExpression( caseStmt->get_condition() ) ); 118 Statement * PolyMutator::mutate(TryStmt *tryStmt) { 119 tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) ); 120 mutateAll( tryStmt->get_catchers(), *this ); 121 return tryStmt; 122 } 144 123 145 return caseStmt; 146 } 124 Statement * PolyMutator::mutate(CatchStmt *cathStmt) { 125 cathStmt->set_body( mutateStatement( cathStmt->get_body() ) ); 126 cathStmt->set_decl( maybeMutate( cathStmt->get_decl(), *this ) ); 127 return cathStmt; 128 } 147 129 148 Statement* 149 PolyMutator::mutate(TryStmt *tryStmt) 150 { 151 tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) ); 152 mutateAll( tryStmt->get_catchers(), *this ); 153 154 return tryStmt; 155 } 130 Statement * PolyMutator::mutate(ReturnStmt *retStmt) { 131 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 132 return retStmt; 133 } 156 134 157 Statement* 158 PolyMutator::mutate(CatchStmt *cathStmt) 159 { 160 cathStmt->set_body( mutateStatement( cathStmt->get_body() ) ); 161 cathStmt->set_decl( maybeMutate( cathStmt->get_decl(), *this ) ); 162 return cathStmt; 163 } 164 165 Statement* 166 PolyMutator::mutate(ReturnStmt *retStmt) 167 { 168 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 169 return retStmt; 170 } 171 172 Statement* 173 PolyMutator::mutate(ExprStmt *exprStmt) 174 { 175 exprStmt->set_expr( mutateExpression( exprStmt->get_expr() ) ); 176 return exprStmt; 177 } 135 Statement * PolyMutator::mutate(ExprStmt *exprStmt) { 136 exprStmt->set_expr( mutateExpression( exprStmt->get_expr() ) ); 137 return exprStmt; 138 } 178 139 179 140 180 Expression* 181 PolyMutator::mutate(UntypedExpr *untypedExpr) 182 { 183 for ( std::list< Expression* >::iterator i = untypedExpr->get_args().begin(); i != untypedExpr->get_args().end(); ++i ) { 184 *i = mutateExpression( *i ); 185 } 186 return untypedExpr; 187 } 141 Expression * PolyMutator::mutate(UntypedExpr *untypedExpr) { 142 for ( std::list< Expression* >::iterator i = untypedExpr->get_args().begin(); i != untypedExpr->get_args().end(); ++i ) { 143 *i = mutateExpression( *i ); 144 } // for 145 return untypedExpr; 146 } 188 147 189 /* static class method */ 190 void 191 PolyMutator::makeTyVarMap( Type *type, TyVarMap &tyVarMap ) 192 { 193 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) { 194 assert( *tyVar ); 195 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind(); 196 } 197 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) { 198 makeTyVarMap( pointer->get_base(), tyVarMap ); 199 } 200 } 148 /* static class method */ 149 void PolyMutator::makeTyVarMap( Type *type, TyVarMap &tyVarMap ) { 150 for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) { 151 assert( *tyVar ); 152 tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind(); 153 } 154 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) { 155 makeTyVarMap( pointer->get_base(), tyVarMap ); 156 } 157 } 158 } // namespace GenPoly 201 159 202 /* static class method */203 } // namespace GenPoly204 160 // Local Variables: // 205 161 // tab-width: 4 // -
translator/GenPoly/PolyMutator.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // PolyMutator.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:46:45 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: PolyMutator.h,v 1.8 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 #ifndef GENPOLY_POLYMUTATOR_H23 #define GENPOLY_POLYMUTATOR_H16 #ifndef _POLYMUTATOR_H 17 #define _POLYMUTATOR_H 24 18 25 19 #include <map> … … 34 28 35 29 namespace GenPoly { 30 class PolyMutator : public Mutator { 31 public: 32 PolyMutator(); 36 33 37 class PolyMutator : public Mutator 38 { 39 public: 40 PolyMutator(); 41 42 virtual CompoundStmt* mutate(CompoundStmt *compoundStmt); 43 virtual Statement* mutate(IfStmt *ifStmt); 44 virtual Statement* mutate(WhileStmt *whileStmt); 45 virtual Statement* mutate(ForStmt *forStmt); 46 virtual Statement* mutate(SwitchStmt *switchStmt); 47 virtual Statement* mutate(ChooseStmt *chooseStmt); 48 virtual Statement* mutate(CaseStmt *caseStmt); 49 virtual Statement* mutate(TryStmt *returnStmt); 50 virtual Statement* mutate(CatchStmt *catchStmt); 51 virtual Statement* mutate(ExprStmt *catchStmt); 52 virtual Statement* mutate(ReturnStmt *catchStmt); 34 virtual CompoundStmt* mutate(CompoundStmt *compoundStmt); 35 virtual Statement* mutate(IfStmt *ifStmt); 36 virtual Statement* mutate(WhileStmt *whileStmt); 37 virtual Statement* mutate(ForStmt *forStmt); 38 virtual Statement* mutate(SwitchStmt *switchStmt); 39 virtual Statement* mutate(ChooseStmt *chooseStmt); 40 virtual Statement* mutate(CaseStmt *caseStmt); 41 virtual Statement* mutate(TryStmt *returnStmt); 42 virtual Statement* mutate(CatchStmt *catchStmt); 43 virtual Statement* mutate(ExprStmt *catchStmt); 44 virtual Statement* mutate(ReturnStmt *catchStmt); 53 45 54 46 virtual Expression* mutate(UntypedExpr *untypedExpr); 55 47 56 // template method 57 virtual void doBeginScope() {} 58 virtual void doEndScope() {} 59 60 protected: 61 void mutateStatementList( std::list< Statement* > &statements ); 62 Statement* mutateStatement( Statement *stmt ); 63 Expression* mutateExpression( Expression *expr ); 64 static void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 48 // template method 49 virtual void doBeginScope() {} 50 virtual void doEndScope() {} 51 protected: 52 void mutateStatementList( std::list< Statement* > &statements ); 53 Statement* mutateStatement( Statement *stmt ); 54 Expression* mutateExpression( Expression *expr ); 55 static void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 65 56 66 TyVarMap scopeTyVars; 67 TypeSubstitution *env; 68 std::list< Statement* > stmtsToAdd; 69 std::list< Statement* > stmtsToAddAfter; 70 }; 71 57 TyVarMap scopeTyVars; 58 TypeSubstitution *env; 59 std::list< Statement* > stmtsToAdd; 60 std::list< Statement* > stmtsToAddAfter; 61 }; 72 62 } // namespace 73 63 74 #endif /* #ifndef GENPOLY_POLYMUTATOR_H */ 64 #endif // _POLYMUTATOR_H 65 75 66 // Local Variables: // 76 67 // tab-width: 4 // -
translator/GenPoly/ScrubTyVars.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // ScrubTyVars.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:47:31 2015 13 // Update Count : 1 14 14 // 15 15 16 #include "GenPoly.h" 16 17 #include "ScrubTyVars.h" … … 20 21 #include "SynTree/Expression.h" 21 22 22 23 23 namespace GenPoly { 24 24 Type * ScrubTyVars::mutate( TypeInstType *typeInst ) { 25 TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() );26 if ( doAll || tyVar != tyVars.end() ) {27 28 29 30 {31 32 33 34 }35 36 delete typeInst;37 return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );38 }39 }40 return typeInst;25 TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() ); 26 if ( doAll || tyVar != tyVars.end() ) { 27 switch ( tyVar->second ) { 28 case TypeDecl::Any: 29 case TypeDecl::Dtype: 30 { 31 PointerType *ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) ); 32 delete typeInst; 33 return ret; 34 } 35 case TypeDecl::Ftype: 36 delete typeInst; 37 return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ); 38 } // switch 39 } // if 40 return typeInst; 41 41 } 42 42 43 43 Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) { 44 // sizeof( T ) => T parameter, which is the size of T45 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {46 47 48 } else {49 50 }44 // sizeof( T ) => T parameter, which is the size of T 45 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) { 46 Expression *expr = new NameExpr( typeInst->get_name() ); 47 return expr; 48 } else { 49 return Mutator::mutate( szeof ); 50 } // if 51 51 } 52 52 53 53 Type * ScrubTyVars::mutate( PointerType *pointer ) { 54 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) {55 56 Type *ret = mutate( typeInst );57 ret->get_qualifiers() += pointer->get_qualifiers();58 pointer->set_base( 0 );59 delete pointer;60 return ret;61 }62 }63 return Mutator::mutate( pointer );54 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) { 55 if ( doAll || tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 56 Type *ret = mutate( typeInst ); 57 ret->get_qualifiers() += pointer->get_qualifiers(); 58 pointer->set_base( 0 ); 59 delete pointer; 60 return ret; 61 } // if 62 } // if 63 return Mutator::mutate( pointer ); 64 64 } 65 65 } // namespace GenPoly 66 66 67 // Local Variables: // 67 68 // tab-width: 4 // -
translator/GenPoly/ScrubTyVars.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // ScrubTyVars.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:48:14 2015 13 // Update Count : 1 14 14 // 15 #ifndef GENPOLY_SCRUBTYVARS_H 16 #define GENPOLY_SCRUBTYVARS_H 15 16 #ifndef _SCRUBTYVARS_H 17 #define _SCRUBTYVARS_H 17 18 18 19 #include "GenPoly.h" … … 22 23 23 24 namespace GenPoly { 24 25 26 ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}25 class ScrubTyVars : public Mutator { 26 public: 27 ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {} 27 28 29 template< typename SynTreeClass > 30 static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars ); 31 template< typename SynTreeClass > 32 static SynTreeClass *scrub( SynTreeClass *target ); 33 34 virtual Type* mutate( TypeInstType *typeInst ); 35 Expression* mutate( SizeofExpr *szeof ); 36 virtual Type* mutate( PointerType *pointer ); 37 private: 38 bool doAll; 39 const TyVarMap &tyVars; 40 }; 41 42 /* static class method */ 28 43 template< typename SynTreeClass > 29 static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars ); 44 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars ) { 45 ScrubTyVars scrubber( false, tyVars ); 46 return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) ); 47 } 48 49 /* static class method */ 30 50 template< typename SynTreeClass > 31 static SynTreeClass *scrub( SynTreeClass *target ); 32 33 virtual Type* mutate( TypeInstType *typeInst ); 34 Expression* mutate( SizeofExpr *szeof ); 35 virtual Type* mutate( PointerType *pointer ); 36 private: 37 bool doAll; 38 const TyVarMap &tyVars; 39 }; 40 41 /* static class method */ 42 template< typename SynTreeClass > 43 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars ) { 44 ScrubTyVars scrubber( false, tyVars ); 45 return static_cast< SynTreeClass * >( target->acceptMutator( scrubber ) ); 46 } 47 48 /* static class method */ 49 template< typename SynTreeClass > 50 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target ) { 51 TyVarMap tyVars; 52 ScrubTyVars scrubber( true, tyVars ); 53 return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) ); 54 } 51 SynTreeClass * ScrubTyVars::scrub( SynTreeClass *target ) { 52 TyVarMap tyVars; 53 ScrubTyVars scrubber( true, tyVars ); 54 return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) ); 55 } 55 56 } // namespace GenPoly 56 57 57 #endif // GENPOLY_SCRUBTYVARS_H 58 #endif // _SCRUBTYVARS_H 59 58 60 // Local Variables: // 59 61 // tab-width: 4 // -
translator/GenPoly/Specialize.cc
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc --7 // Specialize.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:55:09 2015 13 // Update Count : 4 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: Specialize.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 16 #include <cassert> … … 35 29 #include "utility.h" 36 30 31 namespace GenPoly { 32 const std::list<Label> noLabels; 37 33 38 namespace GenPoly { 34 class Specialize : public PolyMutator { 35 public: 36 Specialize( std::string paramPrefix = "_p" ); 39 37 40 const std::list<Label> noLabels; 38 virtual Expression * mutate( ApplicationExpr *applicationExpr ); 39 virtual Expression * mutate( AddressExpr *castExpr ); 40 virtual Expression * mutate( CastExpr *castExpr ); 41 virtual Expression * mutate( LogicalExpr *logicalExpr ); 42 virtual Expression * mutate( ConditionalExpr *conditionalExpr ); 43 virtual Expression * mutate( CommaExpr *commaExpr ); 41 44 42 class Specialize : public PolyMutator 43 { 44 public: 45 Specialize( std::string paramPrefix = "_p" ); 46 47 virtual Expression* mutate(ApplicationExpr *applicationExpr); 48 virtual Expression* mutate(AddressExpr *castExpr); 49 virtual Expression* mutate(CastExpr *castExpr); 50 virtual Expression* mutate(LogicalExpr *logicalExpr); 51 virtual Expression* mutate(ConditionalExpr *conditionalExpr); 52 virtual Expression* mutate(CommaExpr *commaExpr); 45 private: 46 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 47 void handleExplicitParams( ApplicationExpr *appExpr ); 53 48 54 private: 55 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 56 void handleExplicitParams( ApplicationExpr *appExpr ); 57 58 UniqueName thunkNamer; 59 std::string paramPrefix; 60 }; 49 UniqueName thunkNamer; 50 std::string paramPrefix; 51 }; 61 52 62 void 63 convertSpecializations( std::list< Declaration* >& translationUnit ) 64 { 65 Specialize specializer; 66 mutateAll( translationUnit, specializer ); 67 } 53 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 54 Specialize specializer; 55 mutateAll( translationUnit, specializer ); 56 } 68 57 69 Specialize::Specialize( std::string paramPrefix ) 70 : thunkNamer( "_thunk" ), paramPrefix( paramPrefix ) 71 { 72 } 58 Specialize::Specialize( std::string paramPrefix ) 59 : thunkNamer( "_thunk" ), paramPrefix( paramPrefix ) { 60 } 73 61 74 bool 75 needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) 76 { 77 if ( env ) { 78 using namespace ResolvExpr; 79 OpenVarSet openVars, closedVars; 80 AssertionSet need, have; 81 findOpenVars( formalType, openVars, closedVars, need, have, false ); 82 findOpenVars( actualType, openVars, closedVars, need, have, true ); 83 for ( OpenVarSet::const_iterator openVar = openVars.begin(); openVar != openVars.end(); ++openVar ) { 84 Type *boundType = env->lookup( openVar->first ); 85 if ( ! boundType ) continue; 86 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) { 87 if ( closedVars.find( typeInst->get_name() ) == closedVars.end() ) { 88 return true; 89 } 90 } else { 91 return true; 92 } 93 } 94 return false; 95 } else { 96 return false; 97 } 98 } 62 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 63 if ( env ) { 64 using namespace ResolvExpr; 65 OpenVarSet openVars, closedVars; 66 AssertionSet need, have; 67 findOpenVars( formalType, openVars, closedVars, need, have, false ); 68 findOpenVars( actualType, openVars, closedVars, need, have, true ); 69 for ( OpenVarSet::const_iterator openVar = openVars.begin(); openVar != openVars.end(); ++openVar ) { 70 Type *boundType = env->lookup( openVar->first ); 71 if ( ! boundType ) continue; 72 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) { 73 if ( closedVars.find( typeInst->get_name() ) == closedVars.end() ) { 74 return true; 75 } // if 76 } else { 77 return true; 78 } // if 79 } // for 80 return false; 81 } else { 82 return false; 83 } // if 84 } 99 85 100 Expression* 101 Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) 102 { 103 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 104 PointerType *ptrType; 105 FunctionType *funType; 106 if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) { 107 FunctionType *newType = funType->clone(); 108 if ( env ) { 109 TypeSubstitution newEnv( *env ); 110 // it is important to replace only occurrences of type variables that occur free in the 111 // thunk's type 112 newEnv.applyFree( newType ); 113 } 114 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false ); 115 thunkFunc->fixUniqueId(); 116 117 UniqueName paramNamer( paramPrefix ); 118 ApplicationExpr *appExpr = new ApplicationExpr( actual ); 119 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) { 120 (*param)->set_name( paramNamer.newName() ); 121 appExpr->get_args().push_back( new VariableExpr( *param ) ); 122 } 123 appExpr->set_env( maybeClone( env ) ); 124 if ( inferParams ) { 125 appExpr->get_inferParams() = *inferParams; 126 } 127 128 // handle any specializations that may still be present 129 std::string oldParamPrefix = paramPrefix; 130 paramPrefix += "p"; 131 std::list< Statement* > oldStmts; 132 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 133 handleExplicitParams( appExpr ); 134 paramPrefix = oldParamPrefix; 135 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 136 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 137 138 Statement *appStmt; 139 if ( funType->get_returnVals().empty() ) { 140 appStmt = new ExprStmt( noLabels, appExpr ); 141 } else { 142 appStmt = new ReturnStmt( noLabels, appExpr ); 143 } 144 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 145 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 146 return new AddressExpr( new VariableExpr( thunkFunc ) ); 147 } else { 148 return actual; 149 } 150 } else { 151 return actual; 152 } 153 } 86 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 87 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 88 PointerType *ptrType; 89 FunctionType *funType; 90 if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) { 91 FunctionType *newType = funType->clone(); 92 if ( env ) { 93 TypeSubstitution newEnv( *env ); 94 // it is important to replace only occurrences of type variables that occur free in the 95 // thunk's type 96 newEnv.applyFree( newType ); 97 } // if 98 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false ); 99 thunkFunc->fixUniqueId(); 154 100 155 void 156 Specialize::handleExplicitParams( ApplicationExpr *appExpr ) 157 { 158 // create thunks for the explicit parameters 159 assert( ! appExpr->get_function()->get_results().empty() ); 160 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 161 assert( pointer ); 162 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 163 std::list< DeclarationWithType* >::iterator formal; 164 std::list< Expression* >::iterator actual; 165 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 166 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() ); 167 } 168 } 101 UniqueName paramNamer( paramPrefix ); 102 ApplicationExpr *appExpr = new ApplicationExpr( actual ); 103 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) { 104 (*param )->set_name( paramNamer.newName() ); 105 appExpr->get_args().push_back( new VariableExpr( *param ) ); 106 } // for 107 appExpr->set_env( maybeClone( env ) ); 108 if ( inferParams ) { 109 appExpr->get_inferParams() = *inferParams; 110 } // if 169 111 170 Expression* 171 Specialize::mutate(ApplicationExpr *appExpr) 172 { 173 appExpr->get_function()->acceptMutator( *this ); 174 mutateAll( appExpr->get_args(), *this ); 175 176 // create thunks for the inferred parameters 177 for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) { 178 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() ); 179 } 180 181 handleExplicitParams(appExpr); 182 183 return appExpr; 184 } 112 // handle any specializations that may still be present 113 std::string oldParamPrefix = paramPrefix; 114 paramPrefix += "p"; 115 std::list< Statement* > oldStmts; 116 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 117 handleExplicitParams( appExpr ); 118 paramPrefix = oldParamPrefix; 119 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 120 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 185 121 186 Expression* 187 Specialize::mutate(AddressExpr *addrExpr) 188 { 189 addrExpr->get_arg()->acceptMutator( *this ); 190 addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) ); 191 return addrExpr; 192 } 122 Statement *appStmt; 123 if ( funType->get_returnVals().empty() ) { 124 appStmt = new ExprStmt( noLabels, appExpr ); 125 } else { 126 appStmt = new ReturnStmt( noLabels, appExpr ); 127 } // if 128 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 129 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 130 return new AddressExpr( new VariableExpr( thunkFunc ) ); 131 } else { 132 return actual; 133 } // if 134 } else { 135 return actual; 136 } // if 137 } 193 138 194 Expression* 195 Specialize::mutate(CastExpr *castExpr) 196 { 197 castExpr->get_arg()->acceptMutator( *this ); 198 castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) ); 199 return castExpr; 200 } 139 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 140 // create thunks for the explicit parameters 141 assert( ! appExpr->get_function()->get_results().empty() ); 142 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() ); 143 assert( pointer ); 144 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ); 145 std::list< DeclarationWithType* >::iterator formal; 146 std::list< Expression* >::iterator actual; 147 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 148 *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() ); 149 } 150 } 201 151 202 Expression* 203 Specialize::mutate(LogicalExpr *logicalExpr) 204 { 205 return logicalExpr; 206 } 152 Expression * Specialize::mutate( ApplicationExpr *appExpr ) { 153 appExpr->get_function()->acceptMutator( *this ); 154 mutateAll( appExpr->get_args(), *this ); 207 155 208 Expression* 209 Specialize::mutate(ConditionalExpr *condExpr) 210 { 211 return condExpr; 212 } 156 // create thunks for the inferred parameters 157 for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) { 158 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() ); 159 } 213 160 214 Expression* 215 Specialize::mutate(CommaExpr *commaExpr) 216 { 217 return commaExpr; 218 } 161 handleExplicitParams( appExpr ); 219 162 163 return appExpr; 164 } 165 166 Expression * Specialize::mutate( AddressExpr *addrExpr ) { 167 addrExpr->get_arg()->acceptMutator( *this ); 168 addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) ); 169 return addrExpr; 170 } 171 172 Expression * Specialize::mutate( CastExpr *castExpr ) { 173 castExpr->get_arg()->acceptMutator( *this ); 174 castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) ); 175 return castExpr; 176 } 177 178 Expression * Specialize::mutate( LogicalExpr *logicalExpr ) { 179 return logicalExpr; 180 } 181 182 Expression * Specialize::mutate( ConditionalExpr *condExpr ) { 183 return condExpr; 184 } 185 186 Expression * Specialize::mutate( CommaExpr *commaExpr ) { 187 return commaExpr; 188 } 220 189 } // namespace GenPoly 190 221 191 // Local Variables: // 222 192 // tab-width: 4 // -
translator/GenPoly/Specialize.h
r51587aa r01aeade 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // XXX.cc--7 // Specialize.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:53:58 2015 13 // Update Count : 1 14 14 // 15 /*16 * This file is part of the Cforall project17 *18 * $Id: Specialize.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $19 *20 */21 15 22 #ifndef GENPOLY_SPECIALIZE_H23 #define GENPOLY_SPECIALIZE_H16 #ifndef _SPECIALIZE_H 17 #define _SPECIALIZE_H 24 18 25 19 #include <list> … … 28 22 29 23 namespace GenPoly { 30 31 void convertSpecializations( std::list< Declaration* >& translationUnit ); 32 24 void convertSpecializations( std::list< Declaration* >& translationUnit ); 33 25 } // namespace GenPoly 34 26 35 #endif /* #ifndef GENPOLY_SPECIALIZE_H */ 27 #endif // _SPECIALIZE_H 28 36 29 // Local Variables: // 37 30 // tab-width: 4 //
Note: See TracChangeset
for help on using the changeset viewer.