Changeset b940dc71


Ignore:
Timestamp:
Dec 21, 2016, 4:15:47 PM (5 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
53e3b4a
Parents:
626dbc10
Message:

replace type variables in InstantiateGeneric?, fix call passTypeVars so that the correct type is passed

Location:
src/GenPoly
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r626dbc10 rb940dc71  
    11271127                        makeTyVarMap( function, exprTyVars ); // xxx - should this take into account the variables already bound in scopeTyVars (i.e. remove them from exprTyVars?)
    11281128                        ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
    1129                         Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();// ?: dynRetType; // xxx - is concRetType a good name?
    1130 
     1129
     1130                        // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr
     1131                        // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int))
     1132                        // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome.
    11311133                        if ( dynRetType ) {
     1134                                Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
    11321135                                ret = addDynRetParam( appExpr, function, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
    11331136                        } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...?
     
    11421145                        arg = appExpr->get_args().begin();
    11431146
     1147                        Type *concRetType = replaceWithConcrete( appExpr, dynRetType );
    11441148                        passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)
    11451149                        addInferredParams( appExpr, function, arg, exprTyVars );
  • src/GenPoly/InstantiateGeneric.cc

    r626dbc10 rb940dc71  
    1818#include <utility>
    1919#include <vector>
     20#include <unordered_map>
    2021
    2122#include "InstantiateGeneric.h"
     
    2425#include "GenPoly.h"
    2526#include "ScopedSet.h"
     27#include "PolyMutator.h"
    2628
    2729#include "ResolvExpr/typeops.h"
     
    146148        }
    147149
     150        // collect the environments of each TypeInstType so that type variables can be replaced
     151        // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments.
     152        class EnvFinder final : public GenPoly::PolyMutator {
     153        public:
     154                virtual Type * mutate( TypeInstType * inst ) override {
     155                        if ( env ) envMap[inst] = env;
     156                        return inst;
     157                }
     158
     159                // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)?
     160                virtual Type * mutate( FunctionType * ftype ) override {
     161                        return ftype;
     162                }
     163                std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;
     164        };
     165
    148166        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    149167        class GenericInstantiator final : public DeclMutator {
     
    154172                /// Namer for concrete types
    155173                UniqueName typeNamer;
    156 
     174                /// Reference to mapping of environments
     175                const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap;
    157176        public:
    158                 GenericInstantiator() : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {}
     177                GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {}
    159178
    160179                using DeclMutator::mutate;
     
    174193                void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
    175194
     195                void replaceParametersWithConcrete( std::list< Expression* >& params );
     196                Type *replaceWithConcrete( Type *type, bool doClone );
     197
    176198                /// Strips a dtype-static aggregate decl of its type parameters, marks it as stripped
    177199                void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs );
     
    179201
    180202        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
    181                 GenericInstantiator instantiator;
     203                EnvFinder finder;
     204                mutateAll( translationUnit, finder );
     205                GenericInstantiator instantiator( finder.envMap );
    182206                instantiator.mutateDeclarationList( translationUnit );
    183207        }
     
    209233                                // can pretend that any ftype is `void (*)(void)`
    210234                                out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     235                                break;
     236                        case TypeDecl::Ttype:
     237                                assertf( false, "Ttype parameters are not currently allowed as parameters to generic types." );
    211238                                break;
    212239                        }
     
    253280        }
    254281
     282        /// xxx - more or less copied from box -- these should be merged with those somehow...
     283        void GenericInstantiator::replaceParametersWithConcrete( std::list< Expression* >& params ) {
     284                for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
     285                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     286                        assertf(paramType, "Aggregate parameters should be type expressions");
     287                        paramType->set_type( replaceWithConcrete( paramType->get_type(), false ) );
     288                }
     289        }
     290
     291        Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) {
     292                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     293                        if ( envMap.count( typeInst ) ) {
     294                                TypeSubstitution * env = envMap.at( typeInst );
     295                                Type *concrete = env->lookup( typeInst->get_name() );
     296                                if ( concrete ) {
     297                                        return concrete->clone();
     298                                }
     299                                else return typeInst->clone();
     300                        }
     301                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
     302                        if ( doClone ) {
     303                                structType = structType->clone();
     304                        }
     305                        replaceParametersWithConcrete( structType->get_parameters() );
     306                        return structType;
     307                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
     308                        if ( doClone ) {
     309                                unionType = unionType->clone();
     310                        }
     311                        replaceParametersWithConcrete( unionType->get_parameters() );
     312                        return unionType;
     313                }
     314                return type;
     315        }
     316
     317
    255318        Type* GenericInstantiator::mutate( StructInstType *inst ) {
    256319                // mutate subtypes
     
    262325                if ( inst->get_parameters().empty() ) return inst;
    263326
     327                // need to replace type variables to ensure that generic types are instantiated for the return values of polymorphic functions (in particular, for thunks, because they are not [currently] copy constructed).
     328                replaceWithConcrete( inst, false );
     329
    264330                // check for an already-instantiatiated dtype-static type
    265331                if ( dtypeStatics.find( inst->get_baseStruct() ) != dtypeStatics.end() ) {
     
    269335
    270336                // check if type can be concretely instantiated; put substitutions into typeSubs
    271                 assert( inst->get_baseParameters() && "Base struct has parameters" );
     337                assertf( inst->get_baseParameters(), "Base struct has parameters" );
    272338                std::list< TypeExpr* > typeSubs;
    273339                genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs );
Note: See TracChangeset for help on using the changeset viewer.