Changeset 01aeade


Ignore:
Timestamp:
May 19, 2015, 7:57:09 AM (7 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, string, with_gc
Children:
a08ba92
Parents:
51587aa
Message:

licencing: fifth groups of files

Location:
translator
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • translator/Common/CompilerError.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// CompilerError.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:20:37 2015
     13// Update Count     : 2
    1414//
     15
    1516#ifndef COMPILER_ERROR_H
    1617#define COMPILER_ERROR_H
     
    1920//#include "../config.h"
    2021
    21 class CompilerError : public std::exception
    22 {
    23 public:
    24   CompilerError();
    25   CompilerError( std::string what ) : what( what ) {}
    26   ~CompilerError() throw () {}
     22class CompilerError : public std::exception {
     23  public:
     24        CompilerError();
     25        CompilerError( std::string what ) : what( what ) {}
     26        ~CompilerError() throw () {}
    2727
    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;
    3332};
    3433
    35 #endif /* COMPILER_ERROR_H */
     34#endif // COMPILER_ERROR_H
    3635
    37 /*
    38   Local Variables:
    39   mode: c++
    40   End:
    41 */
    4236// Local Variables: //
    4337// tab-width: 4 //
  • translator/Common/SemanticError.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// SemanticError.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:21:25 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: SemanticError.cc,v 1.1 2002/04/27 19:57:10 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include <iostream>
     
    2822#include "SemanticError.h"
    2923
    30 SemanticError::SemanticError()
    31 {
     24SemanticError::SemanticError() {
    3225}
    3326
    34 SemanticError::SemanticError( std::string error )
    35 {
    36   errors.push_back( std::string( "Error: " ) + error );
     27SemanticError::SemanticError( std::string error ) {
     28        errors.push_back( std::string( "Error: " ) + error );
    3729}
    3830
    39 void
    40 SemanticError::append( SemanticError &other )
    41 {
    42   errors.splice( errors.end(), other.errors );
     31void SemanticError::append( SemanticError &other ) {
     32        errors.splice( errors.end(), other.errors );
    4333}
    4434
    45 bool
    46 SemanticError::isEmpty() const
    47 {
    48   return errors.empty();
     35bool SemanticError::isEmpty() const {
     36        return errors.empty();
    4937}
    5038
    51 void
    52 SemanticError::print( std::ostream &os )
    53 {
    54   std::copy( errors.begin(), errors.end(), std::ostream_iterator< std::string >( os, "\n" ) );
     39void SemanticError::print( std::ostream &os ) {
     40        std::copy( errors.begin(), errors.end(), std::ostream_iterator< std::string >( os, "\n" ) );
    5541}
     42
    5643// Local Variables: //
    5744// tab-width: 4 //
  • translator/Common/SemanticError.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// SemanticError.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:22:23 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: SemanticError.h,v 1.1 2002/04/27 19:57:10 rcbilson Exp $
    19  *
    20  */
    2115
    2216#ifndef SEMANTICERROR_H
     
    2923#include <iostream>
    3024
    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() {}
     25class 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() {}
    3831
    39   void append( SemanticError &other );
    40   bool isEmpty() const;
    41   void print( std::ostream &os );
     32        void append( SemanticError &other );
     33        bool isEmpty() const;
     34        void print( std::ostream &os );
    4235
    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;
    4840};
    4941
    5042template< 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() ) );
     43SemanticError::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() ) );
    5748}
    5849
    59 #endif /* SEMANTICERROR_H */
     50#endif // SEMANTICERROR_H
     51
    6052// Local Variables: //
    6153// tab-width: 4 //
  • translator/Common/UnimplementedError.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// UnimplementedError.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:23:08 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: UnimplementedError.h,v 1.1 2002/09/02 20:31:53 rcbilson Exp $
    19  *
    20  */
    2115
    22 #ifndef COMMON_UNIMPLEMENTEDERROR_H
    23 #define COMMON_UNIMPLEMENTEDERROR_H
     16#ifndef _UNIMPLEMENTEDERROR_H
     17#define _UNIMPLEMENTEDERROR_H
    2418
    2519#include <string>
    2620
    27 class UnimplementedError : public std::exception
    28 {
    29 public:
    30   UnimplementedError();
    31   UnimplementedError( std::string what ) : what( what ) {}
    32   ~UnimplementedError() throw () {}
     21class UnimplementedError : public std::exception {
     22  public:
     23        UnimplementedError();
     24        UnimplementedError( std::string what ) : what( what ) {}
     25        ~UnimplementedError() throw () {}
    3326 
    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;
    3931};
    4032
    41 #endif /* #ifndef COMMON_UNIMPLEMENTEDERROR_H */
     33#endif // _UNIMPLEMENTEDERROR_H
     34
    4235// Local Variables: //
    4336// tab-width: 4 //
  • translator/Common/UniqueName.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// UniqueName.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:23:41 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: UniqueName.cc,v 1.1 2002/04/30 03:30:14 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include <string>
     
    2519#include "UniqueName.h"
    2620
    27 UniqueName::UniqueName( const std::string &base )
    28   : base( base ), count( 0 )
    29 {
     21UniqueName::UniqueName( const std::string &base ) : base( base ), count( 0 ) {
    3022}
    3123
    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() );
     24std::string UniqueName::newName( const std::string &additional ) {
     25        std::ostrstream os;
     26        os << base << additional << count++;
     27        return std::string( os.str(), os.pcount() );
    3828}
    3929
  • translator/Common/UniqueName.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// UniqueName.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:24:20 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: UniqueName.h,v 1.1 2002/04/30 03:30:14 rcbilson Exp $
    19  *
    20  */
    2115
    2216#ifndef UNIQUENAME_H
     
    2519#include <string>
    2620
    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;
     21class 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;
    3728};
    3829
    39 #endif /* #ifndef UNIQUENAME_H */
     30#endif // UNIQUENAME_H
     31
    4032// Local Variables: //
    4133// tab-width: 4 //
  • translator/Common/utility.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// utility.h --
    88//
    99// Author           : Richard C. Bilson
    1010// 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
    2618
    2719#include <iostream>
     
    3325
    3426template< 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   }
     27static inline T * maybeClone( const T *orig ) {
     28        if ( orig ) {
     29                return orig->clone();
     30        } else {
     31                return 0;
     32        } // if
    4333}
    4434
    4535template< 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   }
     36static inline T * maybeBuild( const U *orig ) {
     37        if ( orig ) {
     38                return orig->build();
     39        } else {
     40                return 0;
     41        } // if
    5442}
    5543
    5644template< 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   }
     45void 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
    6349}
    6450
    6551template< 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   }
     52void deleteAll( Container &container ) {
     53        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
     54                delete *i;
     55        } // for
    7256}
    7357
    7458template< 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   }
     59void 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
    8567}
    8668
    8769template< 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   }
     70void 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
    9676}
    9777
    9878template< 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   }
     79void 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
     88static 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
    12197}
    12298
    12399template< class T, typename ResultType, ResultType (T::* memfunc)() >
    124 ResultType dispatch(T *pT){
    125   return (pT->*memfunc)();
     100ResultType dispatch( T *pT ) {
     101        return (pT->*memfunc)();
    126102}
    127103
    128104template < 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   }
     105std::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
    135110}
    136111
    137112template < typename T >
    138113std::list<T> flatten( std::list < std::list<T> > l) {
    139   typedef std::list <T> Ts;
    140 
    141   Ts ret;
    142 
    143   switch ( l.size() ){
    144   case 0:
    145     return ret;
    146   case 1:
    147     return l.front();
    148   default:
    149     ret = flatten(tail(l));
    150     ret.insert(ret.begin(), l.front().begin(), l.front().end());
    151     return ret;
    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
    153128}
    154129
    155130template < typename T >
    156131std::string toString ( T value ) {
    157   std::ostrstream os;
     132        std::ostrstream os;
    158133 
    159   os << value; // << std::ends;
    160   os.freeze( false );
    161 
    162   return std::string(os.str(), os.pcount());
     134        os << value; // << std::ends;
     135        os.freeze( false );
     136
     137        return std::string(os.str(), os.pcount());
    163138}
    164139
    165140template< class Constructed, typename Arg >
    166141Constructed *ctor( Arg arg ) {
    167   Constructed *c = new Constructed( arg );
    168   return c;
     142        Constructed *c = new Constructed( arg );
     143        return c;
    169144}
    170145
    171146template< class Constructed, typename Arg >
    172147Constructed ctor_noptr( Arg arg ) {
    173   return Constructed( arg );
     148        return Constructed( arg );
    174149}
    175150
    176151template< typename T >
    177152void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) {
    178   // TIter should secretly be a typename std::list< T >::iterator
    179   //   ( g++ 3.2 issues a 'is implicitly a typename' warning if I make this explicit )
    180    typename std::list< T >::iterator next = pos; advance( next, 1 );
    181 
    182    //if ( next != org.end() ) {
     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() ) {
    183158    org.erase( pos );
    184159    org.splice( next, with );
    185160    //}
    186161
    187   return;
     162        return;
    188163}
    189164
    190165template< typename T1, typename T2 >
    191166T2 *cast_ptr( T1 *from ) {
    192   return dynamic_cast< T2 * >( from );
     167        return dynamic_cast< T2 * >( from );
    193168}
    194169
    195170template< class Exception, typename Arg >
    196171void inline assert_throw( bool pred, Arg arg ) {
    197   if (pred) throw Exception( arg );
     172        if (pred) throw Exception( arg );
    198173}
    199174
    200175template< typename T >
    201176struct is_null_pointer {
    202   bool operator()( const T *ptr ){ return ( ptr == 0 ); }
     177        bool operator()( const T *ptr ){ return ( ptr == 0 ); }
    203178};
    204179
    205180template< 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;
     181void filter(InputIterator begin, InputIterator end, OutputIterator out, Predicate pred) {
     182        while ( begin++ != end )
     183                if ( pred(*begin) ) *out++ = *begin;
     184
     185        return;
    212186}
    213187
    214188template< class InputIterator1, class InputIterator2, class OutputIterator >
    215189void zip( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out ) {
    216   while ( b1 != e1 && b2 != e2 )
    217     *out++ = std::pair<typename InputIterator1::value_type, typename InputIterator2::value_type>(*b1++, *b2++);
     190        while ( b1 != e1 && b2 != e2 )
     191                *out++ = std::pair<typename InputIterator1::value_type, typename InputIterator2::value_type>(*b1++, *b2++);
    218192}
    219193
    220194template< class InputIterator1, class InputIterator2, class OutputIterator, class BinFunction >
    221195void 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
    233202// Local Variables: //
    234203// tab-width: 4 //
  • translator/GenPoly/Box.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// Box.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:31:41 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: Box.cc,v 1.20 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include <set>
     
    4842
    4943namespace 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
    147125        }
    148126
    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 );
    168134        }
    169135
    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();
    229223///     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;
    235229///     std::cerr << "end FunctionDecl: ";
    236230///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    238232///     }
    239233///     std::cerr << "\n";
    240                 retval = oldRetval;
    241                 useRetval = oldUseRetval;
    242                 // doEndScope();
    243             } // if
    244             return functionDecl;
    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 ) {
    248242///     std::cerr << "add " << typeDecl->get_name() << "\n";
    249             scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    250             return Mutator::mutate( typeDecl );
    251         }
    252 
    253         Expression *Pass1::mutate( CommaExpr *commaExpr ) {
    254             bool oldUseRetval = useRetval;
    255             useRetval = false;
    256             commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
    257             useRetval = oldUseRetval;
    258             commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
    259             return commaExpr;
    260         }
    261 
    262         Expression *Pass1::mutate( ConditionalExpr *condExpr ) {
    263             bool oldUseRetval = useRetval;
    264             useRetval = false;
    265             condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
    266             useRetval = oldUseRetval;
    267             condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
    268             condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
    269             return condExpr;
    270 
    271         }
    272 
    273         void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    274             for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    275                 ResolvExpr::EqvClass eqvClass;
    276                 assert( env );
    277                 if ( tyParm->second == TypeDecl::Any ) {
    278                     Type *concrete = env->lookup( tyParm->first );
    279                     if ( concrete ) {
    280                         arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
    281                         arg++;
    282                     } else {
    283                         throw SemanticError( "unbound type variable in application ", appExpr );
    284                     } // if
    285                 } // if
    286             } // for
    287         }
    288 
    289         ObjectDecl *Pass1::makeTemporary( Type *type ) {
    290             ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, type, 0 );
    291             stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    292             return newObj;
    293         }
    294 
    295         TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
    296             if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
    297                 if ( env ) {
    298                     if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    299                         return isPolyType( newType, env, tyVars );
    300                     } // if
    301                 } // if
    302                 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    303                     return typeInst;
    304                 } else {
    305                     return 0;
    306                 } // if
    307             } else {
    308                 return 0;
    309             } // if
    310         }
    311 
    312         Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
    313             if ( useRetval ) {
    314                 assert( retval );
    315                 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
    316                 arg++;
    317             } else {
    318                 ObjectDecl *newObj = makeTemporary( retType->clone() );
    319                 Expression *paramExpr = new VariableExpr( newObj );
    320                 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
    321                     paramExpr = new AddressExpr( paramExpr );
    322                 } // if
    323                 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++;
    325319///     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             } // if
    331             return appExpr;
    332         }
    333 
    334         Expression *Pass1::addPolyRetParam( ApplicationExpr *appExpr, FunctionType *function, std::string typeName, std::list< Expression *>::iterator &arg ) {
    335             ResolvExpr::EqvClass eqvClass;
    336             assert( env );
    337             Type *concrete = env->lookup( typeName );
    338             if ( concrete == 0 ) {
    339                 throw SemanticError( "Unbound type variable " + typeName + " in ", appExpr );
    340             } // if
    341             return addRetParam( appExpr, function, concrete, arg );
    342         }
    343 
    344         Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    345             Expression *ret = appExpr;
    346             if ( ! function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
    347                 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    348             } // if
    349             std::string mangleName = SymTab::Mangler::mangle( function );
    350             std::string adapterName = makeAdapterName( mangleName );
    351 
    352             appExpr->get_args().push_front( appExpr->get_function() );
    353             appExpr->set_function( new NameExpr( adapterName ) );
    354  
    355             return ret;
    356         }
    357 
    358         void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    359             assert( ! arg->get_results().empty() );
     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() );
    360354///   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
    361             TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
    362             if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
    363                 if ( dynamic_cast< TypeInstType *>( arg->get_results().front() ) ) {
    364                     // if the argument's type is a type parameter, we don't need to box again!
    365                     return;
    366                 } else if ( arg->get_results().front()->get_isLvalue() ) {
    367                     // VariableExpr and MemberExpr are lvalues
    368                     arg = new AddressExpr( arg );
    369                 } else {
    370                     ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 );
    371                     newObj->get_type()->get_qualifiers() = Type::Qualifiers();
    372                     stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
    373                     UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    374                     assign->get_args().push_back( new VariableExpr( newObj ) );
    375                     assign->get_args().push_back( arg );
    376                     stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
    377                     arg = new AddressExpr( new VariableExpr( newObj ) );
    378                 } // if
    379             } // if
     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
    380374///   }
    381         }
    382 
    383         void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    384             Type *newType = formal->clone();
    385             std::list< FunctionType *> functions;
    386             // instead of functions needing adapters, this really ought to look for
    387             // any function mentioning a polymorphic type
    388             findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    389             if ( ! functions.empty() ) {
    390                 actual = new CastExpr( actual, newType );
    391             } else {
    392                 delete newType;
    393             } // if
    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 ) {
    397391///   std::cout << "function is ";
    398392///   function->print( std::cout );
    399             for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
     393                        for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
    400394///     std::cout << "parameter is ";
    401395///     (*param)->print( std::fcout );
    402396///     std::cout << std::endl << "argument is ";
    403397///     (*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             } // for
    408         }
    409 
    410         void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    411             std::list< Expression *>::iterator cur = arg;
    412             for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    413                 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    414                     InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    415                     assert( inferParam != appExpr->get_inferParams().end() );
    416                     Expression *newExpr = inferParam->second.expr->clone();
    417                     addCast( newExpr, (*assert)->get_type(), tyVars );
    418                     boxParam( (*assert)->get_type(), newExpr, tyVars );
    419                     appExpr->get_args().insert( cur, newExpr );
    420                 } // for
    421             } // for
    422         }
    423 
    424         void makeRetParm( FunctionType *funcType ) {
    425             DeclarationWithType *retParm = funcType->get_returnVals().front();
    426 
    427             // make a new parameter that is a pointer to the type of the old return value
    428             retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
    429             funcType->get_parameters().push_front( retParm );
    430 
    431             // we don't need the return value any more
    432             funcType->get_returnVals().clear();
    433         }
    434 
    435         FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {
    436             // actually make the adapter type
    437             FunctionType *adapter = adaptee->clone();
    438             if ( ! adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    439                 makeRetParm( adapter );
    440             } // if
    441             adapter->get_parameters().push_front( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ) );
    442             return adapter;
    443         }
    444 
    445         Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) {
    446             assert( param );
    447             assert( arg );
     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 );
    448442///   std::cout << "arg type is ";
    449443///   arg->get_type()->print( std::cout );
     
    452446///   std::cout << " tyVars are: ";
    453447///   printTyVarMap( std::cout, tyVars );
    454             if ( isPolyVal( realParam->get_type(), tyVars ) ) {
     448                        if ( isPolyVal( realParam->get_type(), tyVars ) ) {
    455449///     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
    456450///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
    457451///     } 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;
    462456///     }
    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 *> &paramList = 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 *> &paramList = 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() );
    653610                                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 ) {
    744738///     std::cerr << "mutate appExpr: ";
    745739///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    747741///     }
    748742///     std::cerr << "\n";
    749             bool oldUseRetval = useRetval;
    750             useRetval = false;
    751             appExpr->get_function()->acceptMutator( *this );
    752             mutateAll( appExpr->get_args(), *this );
    753             useRetval = oldUseRetval;
    754  
    755             assert( ! appExpr->get_function()->get_results().empty() );
    756             PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
    757             assert( pointer );
    758             FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
    759             assert( function );
    760  
    761             if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
    762                 return newExpr;
    763             } // if
    764  
    765             Expression *ret = appExpr;
    766  
    767             std::list< Expression *>::iterator arg = appExpr->get_args().begin();
    768             std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
    769  
    770             std::string typeName;
    771             if ( isPolyRet( function, typeName ) ) {
    772                 ret = addPolyRetParam( appExpr, function, typeName, arg );
    773             } else if ( needsAdapter( function, scopeTyVars ) ) {
     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 ) ) {
    774768///     std::cerr << "needs adapter: ";
    775769///     for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
     
    777771///     }
    778772///     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() ) {
    841834///       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                }
    895886
    896887////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    897888
    898         Pass2::Pass2() {}
    899 
    900         void Pass2::addAdapters( FunctionType *functionType ) {
    901             std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
    902             std::list< FunctionType *> functions;
    903             for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
    904                 Type *orig = (*arg)->get_type();
    905                 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
    906                 (*arg)->set_type( orig );
    907             }
    908             std::set< std::string > adaptersDone;
    909             for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    910                 std::string mangleName = SymTab::Mangler::mangle( *funType );
    911                 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    912                     std::string adapterName = makeAdapterName( mangleName );
    913                     paramList.push_front( new ObjectDecl( adapterName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
    914                     adaptersDone.insert( adaptersDone.begin(), mangleName );
    915                 }
    916             }
     889                Pass2::Pass2() {}
     890
     891                void Pass2::addAdapters( FunctionType *functionType ) {
     892                        std::list< DeclarationWithType *> &paramList = 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                        }
    917908///  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 );
    979964///   ObjectDecl *newFunPtr = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    980             for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    981                 ObjectDecl *thisParm;
    982                 if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    983                     thisParm = newObj->clone();
    984                     thisParm->set_name( (*tyParm)->get_name() );
    985                     last = funcType->get_parameters().insert( last, thisParm );
    986                     ++last;
    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 ) {
    989974///      *assert = (*assert)->acceptMutator( *this );
    990                     inferredParams.push_back( *assert );
    991                 }
    992                 (*tyParm)->get_assertions().clear();
    993             }
    994             delete newObj;
    995             funcType->get_parameters().splice( last, inferredParams );
    996             addAdapters( funcType );
    997             mutateAll( funcType->get_returnVals(), *this );
    998             mutateAll( funcType->get_parameters(), *this );
    999  
    1000             scopeTyVars = oldtyVars;
    1001             return funcType;
    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                }
    1003988
    1004989////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
    1005990
    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 ) {
    10361016///   Initializer *init = 0;
    10371017///   std::list< Expression *> designators;
     
    10421022///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    10431023
    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
    10881064} // namespace GenPoly
     1065
    10891066// Local Variables: //
    10901067// tab-width: 4 //
  • translator/GenPoly/Box.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// Box.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:32:33 2015
     13// Update Count     : 2
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: Box.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    22 #ifndef GENPOLY_BOX_H
    23 #define GENPOLY_BOX_H
     16#ifndef _BOX_H
     17#define _BOX_H
    2418
    2519#include <list>
    26 
    2720#include "SynTree/SynTree.h"
    2821
    2922namespace GenPoly {
    30 
    31 void box( std::list< Declaration* >& translationUnit );
    32 
     23        void box( std::list< Declaration* >& translationUnit );
    3324} // namespace GenPoly
    3425
    35 #endif /* #ifndef GENPOLY_BOX_H */
     26#endif // _BOX_H
     27
    3628// Local Variables: //
    3729// tab-width: 4 //
  • translator/GenPoly/CopyParams.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// CopyParams.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:33:31 2015
     13// Update Count     : 1
    1414//
     15
    1516#include <set>
    1617#include <map>
     
    2425#include "UniqueName.h"
    2526
     27namespace GenPoly {
     28        class CopyParams : public Visitor {
     29          public:
     30                CopyParams();
     31 
     32                virtual void visit( FunctionDecl *funcDecl );
     33                virtual void visit( AddressExpr *addrExpr );
    2634
    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        };
    3439
    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        }
    3944
    40     void copyParams( std::list< Declaration* > &translationUnit ) {
    41         CopyParams copier;
    42         acceptAll( translationUnit, copier );
    43     }
     45        CopyParams::CopyParams() : namer( "_cp" ) {}
    4446
    45     CopyParams::CopyParams() : namer( "_cp" ) {}
     47        static const std::list< Label > noLabels;
    4648
    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        }
    4884
    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() );
    7795                        } // if
    78                         modVars.erase( var );
    79                     } // if
    80                 } // for
    81             } // if
    82         } // if
    83     }
     96                } // if
     97        }
     98} // namespace GenPoly
    8499
    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() );
    95             } // if
    96         } // if
    97     }
    98 } // namespace GenPoly
    99100// Local Variables: //
    100101// tab-width: 4 //
  • translator/GenPoly/CopyParams.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// CopyParams.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:34:25 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: CopyParams.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    22 #ifndef GENPOLY_COPYPARAMS_H
    23 #define GENPOLY_COPYPARAMS_H
     16#ifndef _COPYPARAMS_H
     17#define _COPYPARAMS_H
    2418
    2519#include "SynTree/SynTree.h"
    2620
    2721namespace GenPoly {
    28 
    29 void copyParams( std::list< Declaration* > &translationUnit );
    30 
     22        void copyParams( std::list< Declaration* > &translationUnit );
    3123} // namespace GenPoly
    3224
    33 #endif /* #ifndef GENPOLY_COPYPARAMS_H */
     25#endif // _COPYPARAMS_H
     26
    3427// Local Variables: //
    3528// tab-width: 4 //
  • translator/GenPoly/FindFunction.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// FindFunction.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:35:48 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: FindFunction.cc,v 1.5 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include "FindFunction.h"
     
    2620
    2721namespace 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 );
    2830
    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        };
    3936
    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        }
    4541
    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        }
    5246
    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        }
    5950
    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        }
    6459
    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        }
    7574
    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
    9283
    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 GenPoly
    10484// Local Variables: //
    10585// tab-width: 4 //
  • translator/GenPoly/FindFunction.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// FindFunction.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:36:35 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: FindFunction.h,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#ifndef FINDFUNCTION_H
     
    2721
    2822namespace GenPoly {
     23        typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& );
    2924
    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 );
    3527} // namespace GenPoly
    3628
    37 #endif /* #ifndef FINDFUNCTION_H */
     29#endif // FINDFUNCTION_H
     30
    3831// Local Variables: //
    3932// tab-width: 4 //
  • translator/GenPoly/GenPoly.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// GenPoly.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:37:46 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: GenPoly.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include "GenPoly.h"
     
    2721
    2822namespace GenPoly {
     23        // interface functions
     24        bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
     25                return isPolyVal( type, tyVars, false );
     26        }
    2927
    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        }
    3431
    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        }
    3841
    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        }
    5056
    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
    6864
    69 void
    70 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 GenPoly
    7965// Local Variables: //
    8066// tab-width: 4 //
  • translator/GenPoly/GenPoly.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// GenPoly.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:38:34 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: GenPoly.h,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#ifndef GENPOLY_H
     
    2923
    3024namespace GenPoly {
     25        typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
    3126
    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.
    3329
    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 );
    4436} // namespace GenPoly
    4537
    46 #endif
     38#endif // GENPOLY_H
     39
    4740// Local Variables: //
    4841// tab-width: 4 //
  • translator/GenPoly/Lvalue.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// Lvalue.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:41:33 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: Lvalue.cc,v 1.5 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include <cassert>
     
    3731#include "utility.h"
    3832
     33namespace GenPoly {
     34        namespace {
     35                const std::list<Label> noLabels;
    3936
    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                };
    4147
    42 namespace {
     48                class Pass2 : public Visitor {
     49                  public:
     50                        virtual void visit( FunctionType *funType );
     51                  private:
     52                };
     53        } // namespace
    4354
    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        }
    4561
    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 );
    5099 
    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() );
    54101
    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 );
    58106
    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                }
    63118
    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                }
    66137
    67 } // namespace
     138                void Pass2::visit( FunctionType *funType ) {
     139                        std::string typeName;
     140                        if ( isLvalueRet( funType ) ) {
     141                                DeclarationWithType *retParm = funType->get_returnVals().front();
    68142
    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
    77151
    78 namespace {
    79 
    80 bool
    81 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 bool
    91 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 function
    114     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 void
    167 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 value
    174     retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
    175   }
    176  
    177   Visitor::visit( funType );
    178 }
    179 
    180 } // namespace
    181 
    182 } // namespace GenPoly
    183152// Local Variables: //
    184153// tab-width: 4 //
  • translator/GenPoly/Lvalue.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// Lvalue.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:42:09 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: Lvalue.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    22 #ifndef GENPOLY_LVALUE_H
    23 #define GENPOLY_LVALUE_H
     16#ifndef _LVALUE_H
     17#define _LVALUE_H
    2418
    2519#include <list>
     
    2822
    2923namespace GenPoly {
    30 
    31 void convertLvalue( std::list< Declaration* >& translationUnit );
    32 
     24        void convertLvalue( std::list< Declaration* >& translationUnit );
    3325} // namespace GenPoly
    3426
    35 #endif /* #ifndef GENPOLY_LVALUE_H */
     27#endif // _LVALUE_H
     28
    3629// Local Variables: //
    3730// tab-width: 4 //
  • translator/GenPoly/PolyMutator.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// PolyMutator.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:45:50 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: PolyMutator.cc,v 1.7 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include "PolyMutator.h"
     
    2923
    3024namespace GenPoly {
     25        namespace {
     26                const std::list<Label> noLabels;
     27        }
    3128
    32 namespace {
    33 const std::list<Label> noLabels;
    34 }
     29        PolyMutator::PolyMutator() : env( 0 ) {
     30        }
    3531
    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        }
    4046
    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        }
    5760
    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        }
    7371
    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        }
    8678
    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        }
    9585
    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        }
    10491
    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        }
    11299
    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        }
    122105
    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        }
    130111
    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        }
    138117
    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        }
    144123
    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        }
    147129
    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        }
    156134
    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        }
    178139
    179140
    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        }
    188147 
    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
    201159
    202 /* static class method */
    203 } // namespace GenPoly
    204160// Local Variables: //
    205161// tab-width: 4 //
  • translator/GenPoly/PolyMutator.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// PolyMutator.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:46:45 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: PolyMutator.h,v 1.8 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    22 #ifndef GENPOLY_POLYMUTATOR_H
    23 #define GENPOLY_POLYMUTATOR_H
     16#ifndef _POLYMUTATOR_H
     17#define _POLYMUTATOR_H
    2418
    2519#include <map>
     
    3428
    3529namespace GenPoly {
     30        class PolyMutator : public Mutator {
     31          public:
     32                PolyMutator();
    3633
    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);
    5345 
    54   virtual Expression* mutate(UntypedExpr *untypedExpr);
     46                virtual Expression* mutate(UntypedExpr *untypedExpr);
    5547 
    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 );
    6556 
    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        };
    7262} // namespace
    7363
    74 #endif /* #ifndef GENPOLY_POLYMUTATOR_H */
     64#endif // _POLYMUTATOR_H
     65
    7566// Local Variables: //
    7667// tab-width: 4 //
  • translator/GenPoly/ScrubTyVars.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// ScrubTyVars.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:47:31 2015
     13// Update Count     : 1
    1414//
     15
    1516#include "GenPoly.h"
    1617#include "ScrubTyVars.h"
     
    2021#include "SynTree/Expression.h"
    2122
    22 
    2323namespace GenPoly {
    2424    Type * ScrubTyVars::mutate( TypeInstType *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             }
    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;
    4141    }
    4242
    4343    Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
    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         }
     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
    5151    }
    5252
    5353    Type * ScrubTyVars::mutate( PointerType *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             }
    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 );
    6464    }
    6565} // namespace GenPoly
     66
    6667// Local Variables: //
    6768// tab-width: 4 //
  • translator/GenPoly/ScrubTyVars.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// ScrubTyVars.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:48:14 2015
     13// Update Count     : 1
    1414//
    15 #ifndef GENPOLY_SCRUBTYVARS_H
    16 #define GENPOLY_SCRUBTYVARS_H
     15
     16#ifndef _SCRUBTYVARS_H
     17#define _SCRUBTYVARS_H
    1718
    1819#include "GenPoly.h"
     
    2223
    2324namespace GenPoly {
    24     class ScrubTyVars : public Mutator {
    25       public:
    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 ) {}
    2728 
     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 */
    2843        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 */
    3050        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        }
    5556} // namespace GenPoly
    5657
    57 #endif // GENPOLY_SCRUBTYVARS_H
     58#endif // _SCRUBTYVARS_H
     59
    5860// Local Variables: //
    5961// tab-width: 4 //
  • translator/GenPoly/Specialize.cc

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// Specialize.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:55:09 2015
     13// Update Count     : 4
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: Specialize.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    2216#include <cassert>
     
    3529#include "utility.h"
    3630
     31namespace GenPoly {
     32        const std::list<Label> noLabels;
    3733
    38 namespace GenPoly {
     34        class Specialize : public PolyMutator {
     35          public:
     36                Specialize( std::string paramPrefix = "_p" );
    3937
    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 );
    4144
    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 );
    5348
    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        };
    6152
    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        }
    6857
    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        }
    7361
    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        }
    9985
    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();
    154100
    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
    169111
    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 );
    185121
    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        }
    193138
    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        }
    201151
    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 );
    207155
    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                }
    213160
    214 Expression*
    215 Specialize::mutate(CommaExpr *commaExpr)
    216 {
    217   return commaExpr;
    218 }
     161                handleExplicitParams( appExpr );
    219162
     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        }
    220189} // namespace GenPoly
     190
    221191// Local Variables: //
    222192// tab-width: 4 //
  • translator/GenPoly/Specialize.h

    r51587aa r01aeade  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // XXX.cc --
     7// Specialize.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 19 07:53:58 2015
     13// Update Count     : 1
    1414//
    15 /*
    16  * This file is part of the Cforall project
    17  *
    18  * $Id: Specialize.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
    19  *
    20  */
    2115
    22 #ifndef GENPOLY_SPECIALIZE_H
    23 #define GENPOLY_SPECIALIZE_H
     16#ifndef _SPECIALIZE_H
     17#define _SPECIALIZE_H
    2418
    2519#include <list>
     
    2822
    2923namespace GenPoly {
    30 
    31 void convertSpecializations( std::list< Declaration* >& translationUnit );
    32 
     24        void convertSpecializations( std::list< Declaration* >& translationUnit );
    3325} // namespace GenPoly
    3426
    35 #endif /* #ifndef GENPOLY_SPECIALIZE_H */
     27#endif // _SPECIALIZE_H
     28
    3629// Local Variables: //
    3730// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.