Changes in / [faf8857:c23f807]


Ignore:
Location:
src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rfaf8857 rc23f807  
    306306
    307307                void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
     308                        // pass size/align for type variables
    308309                        for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
    309310                                ResolvExpr::EqvClass eqvClass;
     
    321322                                } // if
    322323                        } // for
     324
     325                        // add size/align for generic types to parameter list
     326                        //assert( ! appExpr->get_function()->get_results().empty() );
     327                        if ( appExpr->get_function()->get_results().empty() ) return;
     328                        FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
     329                        assert( funcType );
     330                       
     331                        std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
     332                        std::list< Expression* >::const_iterator fnArg = arg;
     333                        std::set< std::string > seenTypes; //< names for generic types we've seen
     334                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     335                                Type *parmType = (*fnParm)->get_type();
     336                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) {
     337                                        std::string sizeName = sizeofName( parmType );
     338                                        if ( seenTypes.count( sizeName ) ) continue;
     339
     340                                        assert( ! (*fnArg)->get_results().empty() );
     341                                        Type *argType = (*fnArg)->get_results().front();
     342                                        arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
     343                                        arg++;
     344                                        arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
     345                                        arg++;
     346
     347                                        seenTypes.insert( sizeName );
     348                                }
     349                        }
    323350                }
    324351
     
    971998                        TyVarMap oldtyVars = scopeTyVars;
    972999                        makeTyVarMap( funcType, scopeTyVars );
    973  
     1000
     1001                        // move polymorphic return type to parameter list
    9741002                        std::string typeName;
    9751003                        if ( isPolyRet( funcType, typeName ) ) {
     
    9791007                                funcType->get_returnVals().pop_front();
    9801008                        }
    981  
     1009
     1010                        // add size/align and assertions for type parameters to parameter list
    9821011                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    9831012                        std::list< DeclarationWithType *> inferredParams;
     
    10071036                                (*tyParm)->get_assertions().clear();
    10081037                        }
     1038
     1039                        // add size/align for generic types to parameter list
     1040                        std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
     1041                        for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
     1042                                Type *parmType = (*fnParm)->get_type();
     1043                                if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) {
     1044                                        std::string sizeName = sizeofName( parmType );
     1045                                        if ( seenTypes.count( sizeName ) ) continue;
     1046                                       
     1047                                        ObjectDecl *sizeParm, *alignParm;
     1048                                        sizeParm = newObj.clone();
     1049                                        sizeParm->set_name( sizeName );
     1050                                        last = funcType->get_parameters().insert( last, sizeParm );
     1051                                        ++last;
     1052
     1053                                        alignParm = newObj.clone();
     1054                                        alignParm->set_name( alignofName( parmType ) );
     1055                                        last = funcType->get_parameters().insert( last, alignParm );
     1056                                        ++last;
     1057
     1058                                        seenTypes.insert( sizeName );
     1059                                }
     1060                        }
     1061
     1062                        // splice assertion parameters into parameter list
    10091063                        funcType->get_parameters().splice( last, inferredParams );
    10101064                        addAdapters( funcType );
  • src/GenPoly/GenPoly.cc

    rfaf8857 rc23f807  
    6868
    6969        namespace {
    70                 /// Checks a parameter list for polymorphic parameters
     70                /// Checks a parameter list for polymorphic parameters; will substitute according to env if present
     71                bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
     72                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     73                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     74                                assert(paramType && "Aggregate parameters should be type expressions");
     75                                if ( isPolyType( paramType->get_type(), env ) ) return true;
     76                        }
     77                        return false;
     78                }
     79
     80                /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
    7181                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    7282                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     
    7888                }
    7989        }
     90
     91        Type *isPolyType( Type *type, const TypeSubstitution *env ) {
     92                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     93                        if ( env ) {
     94                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     95                                        return isPolyType( newType, env );
     96                                } // if
     97                        } // if
     98                        return type;
     99                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     100                        if ( hasPolyParams( structType->get_parameters(), env ) ) return type;
     101                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     102                        if ( hasPolyParams( unionType->get_parameters(), env ) ) return type;
     103                }
     104                return 0;
     105        }
    80106       
    81107        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    84110                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
    85111                                        return isPolyType( newType, tyVars, env );
     112                                } // if
    86113                        } // if
    87                 } // if
    88114                        if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    89115                                return type;
    90         }
     116                        }
    91117                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
    92118                        if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
     
    97123        }
    98124
     125        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
     126                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     127                        return isPolyType( ptr->get_base(), env );
     128                } else if ( env ) {
     129                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     130                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     131                                        return isPolyPtr( newType, env );
     132                                } // if
     133                        } // if
     134                } // if
     135                return 0;
     136        }
     137       
    99138        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    100139                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     
    110149        }
    111150
     151        FunctionType * getFunctionType( Type *ty ) {
     152                PointerType *ptrType;
     153                if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
     154                        return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
     155                } else {
     156                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
     157                }
     158        }
     159
    112160        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
    113161                for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
     
    118166
    119167        std::string sizeofName( Type *ty ) {
    120                 return std::string( "_sizeof_" ) + SymTab::Mangler::mangle( ty, false, false );
     168                return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );
    121169        }
    122170
    123171        std::string alignofName( Type *ty ) {
    124                 return std::string( "_alignof_" ) + SymTab::Mangler::mangle( ty, false, false );
     172                return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
    125173        }
    126174} // namespace GenPoly
  • src/GenPoly/GenPoly.h

    rfaf8857 rc23f807  
    3737
    3838        /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided
     39        Type *isPolyType( Type *type, const TypeSubstitution *env = 0 );
     40       
     41        /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    3942        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
    4043
    4144        /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided
     45        Type *isPolyPtr( Type *type, const TypeSubstitution *env = 0 );
     46       
     47        /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
    4248        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
     49
     50        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
     51        FunctionType * getFunctionType( Type *ty );
    4352
    4453        /// Prints type variable map
  • src/GenPoly/ScrubTyVars.cc

    rfaf8857 rc23f807  
    4646        Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
    4747                // sizeof( T ) => _sizeof_T parameter, which is the size of T
    48                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
    49                         Expression *expr = new NameExpr( sizeofName( typeInst ) );
     48                if ( Type *polyType = isPolyType( szeof->get_type() ) ) {
     49                        Expression *expr = new NameExpr( sizeofName( polyType ) );
    5050                        return expr;
    5151                } else {
     
    5656        Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
    5757                // alignof( T ) => _alignof_T parameter, which is the alignment of T
    58                 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( algnof->get_type() ) ) {
    59                         Expression *expr = new NameExpr( alignofName( typeInst ) );
     58                if ( Type *polyType = isPolyType( algnof->get_type() ) ) {
     59                        Expression *expr = new NameExpr( alignofName( polyType ) );
    6060                        return expr;
    6161                } else {
  • src/GenPoly/Specialize.cc

    rfaf8857 rc23f807  
    1717
    1818#include "Specialize.h"
     19#include "GenPoly.h"
    1920#include "PolyMutator.h"
    2021
     
    8788        }
    8889
    89         /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    90         FunctionType * getFunctionType( Type *ty ) {
    91                 PointerType *ptrType;
    92                 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
    93                         return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
    94                 } else {
    95                         return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
    96                 }
    97         }
    98 
    9990        /// Generates a thunk that calls `actual` with type `funType` and returns its address
    10091        Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
  • src/SymTab/Mangler.cc

    rfaf8857 rc23f807  
    3030
    3131namespace SymTab {
    32         Mangler::Mangler( bool mangleOverridable, bool includeQualifiers )
    33                 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), includeQualifiers(includeQualifiers) {}
     32        std::string Mangler::mangleType( Type *ty ) {
     33                Mangler mangler( false, true );
     34                maybeAccept( ty, mangler );
     35                return mangler.get_mangleName();
     36        }
     37       
     38        Mangler::Mangler( bool mangleOverridable, bool typeMode )
     39                : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ) {}
    3440               
    3541        Mangler::Mangler( const Mangler &rhs ) : mangleName() {
     
    3844                isTopLevel = rhs.isTopLevel;
    3945                mangleOverridable = rhs.mangleOverridable;
    40                 includeQualifiers = rhs.includeQualifiers;
     46                typeMode = rhs.typeMode;
    4147        }
    4248
     
    149155        void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
    150156                printQualifiers( refType );
     157
    151158                mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
    152159        }
    153160
     161        void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
     162                printQualifiers( refType );
     163
     164                std::ostringstream oldName( mangleName.str() );
     165                mangleName.clear();
     166
     167                mangleName << prefix << refType->get_name();
     168
     169                std::list< Expression* >& params = refType->get_parameters();
     170                if ( ! params.empty() ) {
     171                        mangleName << "_";
     172                        for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
     173                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     174                                assert(paramType && "Aggregate parameters should be type expressions");
     175                                maybeAccept( paramType->get_type(), *this );
     176                        }
     177                        mangleName << "_";
     178                }
     179
     180                oldName << mangleName.str().length() << mangleName.str();
     181                mangleName.str( oldName.str() );
     182        }
     183
    154184        void Mangler::visit( StructInstType *aggregateUseType ) {
    155                 mangleRef( aggregateUseType, "s" );
     185                if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
     186                else mangleRef( aggregateUseType, "s" );
    156187        }
    157188
    158189        void Mangler::visit( UnionInstType *aggregateUseType ) {
    159                 mangleRef( aggregateUseType, "u" );
     190                if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
     191                else mangleRef( aggregateUseType, "u" );
    160192        }
    161193
     
    207239        void Mangler::printQualifiers( Type *type ) {
    208240                // skip if not including qualifiers
    209                 if ( ! includeQualifiers ) return;
     241                if ( typeMode ) return;
    210242               
    211243                if ( ! type->get_forall().empty() ) {
     
    227259                                varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
    228260                                for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    229                                         Mangler sub_mangler( mangleOverridable, includeQualifiers );
     261                                        Mangler sub_mangler( mangleOverridable, typeMode );
    230262                                        sub_mangler.nextVarNum = nextVarNum;
    231263                                        sub_mangler.isTopLevel = false;
  • src/SymTab/Mangler.h

    rfaf8857 rc23f807  
    2525        class Mangler : public Visitor {
    2626          public:
     27                /// Mangle syntax tree object; primary interface to clients
    2728                template< typename SynTreeClass >
    28             static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool includeQualifiers = true ); // interface to clients
     29            static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true );
     30                /// Mangle a type name; secondary interface
     31                static std::string mangleType( Type* ty );
    2932
    3033                virtual void visit( ObjectDecl *declaration );
     
    5154                bool isTopLevel;                ///< Is the Mangler at the top level
    5255                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
    53                 bool includeQualifiers;         ///< Include type qualifiers in mangled name
     56                bool typeMode;                  ///< Produce a unique mangled name for a type
    5457 
    55                 Mangler( bool mangleOverridable, bool includeQualifiers );
     58                Mangler( bool mangleOverridable, bool typeMode );
    5659                Mangler( const Mangler & );
    5760 
    5861                void mangleDecl( DeclarationWithType *declaration );
    5962                void mangleRef( ReferenceToType *refType, std::string prefix );
     63                void mangleGenericRef( ReferenceToType *refType, std::string prefix );
    6064 
    6165                void printQualifiers( Type *type );
     
    6367
    6468        template< typename SynTreeClass >
    65         std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool includeQualifiers ) {
    66                 Mangler mangler( mangleOverridable, includeQualifiers );
     69        std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable ) {
     70                Mangler mangler( mangleOverridable, false );
    6771                maybeAccept( decl, mangler );
    6872                return mangler.get_mangleName();
Note: See TracChangeset for help on using the changeset viewer.