Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cc

    rbdf1954 r69911c11  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Nov 24 15:23:08 2015
    13 // Update Count     : 11
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Dec 15 16:11:18 2015
     13// Update Count     : 13
    1414//
    1515
    1616#include "GenPoly.h"
     17
     18#include "SymTab/Mangler.h"
     19#include "SynTree/Expression.h"
    1720#include "SynTree/Type.h"
    1821
     
    2124
    2225namespace GenPoly {
    23         // A function needs an adapter if it returns a polymorphic value or if any of its
    24         // parameters have polymorphic type
    2526        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    26                 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
     27                if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    2728                        return true;
    2829                } // if
    2930                for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
    30                         if ( isPolyVal( (*innerArg)->get_type(), tyVars ) ) {
     31                        if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
    3132                                return true;
    3233                        } // if
     
    6667        }
    6768
    68         bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
     69        namespace {
     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
     81                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     82                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     83                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     84                                assert(paramType && "Aggregate parameters should be type expressions");
     85                                if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
     86                        }
     87                        return false;
     88                }
     89        }
     90
     91        Type *isPolyType( Type *type, const TypeSubstitution *env ) {
    6992                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        }
     106       
     107        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     108                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     109                        if ( env ) {
     110                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     111                                        return isPolyType( newType, tyVars, env );
     112                                } // if
     113                        } // if
    70114                        if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    71                                 return true;
     115                                return type;
     116                        }
     117                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     118                        if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
     119                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     120                        if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type;
     121                }
     122                return 0;
     123        }
     124
     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
    72133                        } // if
    73134                } // if
    74                 return false;
     135                return 0;
     136        }
     137       
     138        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     139                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     140                        return isPolyType( ptr->get_base(), tyVars, env );
     141                } else if ( env ) {
     142                        if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
     143                                if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
     144                                        return isPolyPtr( newType, tyVars, env );
     145                                } // if
     146                        } // if
     147                } // if
     148                return 0;
    75149        }
    76150
    77         bool isPolyObj( Type *type, const TyVarMap &tyVars ) {
    78                 if ( isPolyVal( type, tyVars ) ) {
    79                         return true;
    80                 } else if ( PointerType *pt = dynamic_cast<PointerType*>( type ) ) {
    81                         return isPolyObj( pt->get_base(), tyVars );
     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
    82155                } else {
    83                         return false;
     156                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
    84157                }
    85158        }
     
    91164                os << std::endl;
    92165        }
     166
     167        std::string sizeofName( Type *ty ) {
     168                return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );
     169        }
     170
     171        std::string alignofName( Type *ty ) {
     172                return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
     173        }
    93174} // namespace GenPoly
    94175
Note: See TracChangeset for help on using the changeset viewer.