Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    r9ff56e7 rc7a3081  
    2222#include "InstantiateGeneric.h"
    2323
     24#include "DeclMutator.h"
    2425#include "GenPoly.h"
    2526#include "ScopedSet.h"
    2627#include "ScrubTyVars.h"
    27 
    28 #include "Common/PassVisitor.h"
     28#include "PolyMutator.h"
     29
     30#include "ResolvExpr/typeops.h"
     31
     32#include "SynTree/Declaration.h"
     33#include "SynTree/Expression.h"
     34#include "SynTree/Type.h"
     35
    2936#include "Common/ScopedMap.h"
    3037#include "Common/UniqueName.h"
    3138#include "Common/utility.h"
    32 
    33 #include "ResolvExpr/typeops.h"
    34 
    35 #include "SynTree/Declaration.h"
    36 #include "SynTree/Expression.h"
    37 #include "SynTree/Type.h"
    38 
    39 
    40 #include "InitTweak/InitTweak.h"
    41 
    4239
    4340namespace GenPoly {
     
    156153        }
    157154
     155        // collect the environments of each TypeInstType so that type variables can be replaced
     156        // 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.
     157        class EnvFinder final : public GenPoly::PolyMutator {
     158        public:
     159                using GenPoly::PolyMutator::mutate;
     160                virtual Type * mutate( TypeInstType * inst ) override {
     161                        if ( env ) envMap[inst] = env;
     162                        return inst;
     163                }
     164
     165                // 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)?
     166                virtual Type * mutate( FunctionType * ftype ) override {
     167                        return ftype;
     168                }
     169                std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;
     170        };
     171
    158172        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    159         struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
     173        class GenericInstantiator final : public DeclMutator {
    160174                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    161175                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
     
    164178                /// Namer for concrete types
    165179                UniqueName typeNamer;
    166                 /// Should not make use of type environment to replace types of function parameter and return values.
    167                 bool inFunctionType = false;
    168                 GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
    169 
    170                 Type* postmutate( StructInstType *inst );
    171                 Type* postmutate( UnionInstType *inst );
    172 
    173                 void premutate( __attribute__((unused)) FunctionType * ftype ) {
    174                         GuardValue( inFunctionType );
    175                         inFunctionType = true;
    176                 }
    177 
    178                 void beginScope();
    179                 void endScope();
     180                /// Reference to mapping of environments
     181                const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap;
     182        public:
     183                GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {}
     184
     185                using DeclMutator::mutate;
     186                virtual Type* mutate( StructInstType *inst ) override;
     187                virtual Type* mutate( UnionInstType *inst ) override;
     188
     189                virtual void doBeginScope() override;
     190                virtual void doEndScope() override;
    180191        private:
    181192                /// Wrap instantiation lookup for structs
     
    196207
    197208        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
    198                 PassVisitor<GenericInstantiator> instantiator;
    199                 mutateAll( translationUnit, instantiator );
     209                EnvFinder finder;
     210                mutateAll( translationUnit, finder );
     211                GenericInstantiator instantiator( finder.envMap );
     212                instantiator.mutateDeclarationList( translationUnit );
    200213        }
    201214
     
    293306        Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) {
    294307                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
    295                         if ( env && ! inFunctionType ) {
     308                        if ( envMap.count( typeInst ) ) {
     309                                TypeSubstitution * env = envMap.at( typeInst );
    296310                                Type *concrete = env->lookup( typeInst->get_name() );
    297311                                if ( concrete ) {
     
    317331
    318332
    319         Type* GenericInstantiator::postmutate( StructInstType *inst ) {
     333        Type* GenericInstantiator::mutate( StructInstType *inst ) {
     334                // mutate subtypes
     335                Type *mutated = Mutator::mutate( inst );
     336                inst = dynamic_cast< StructInstType* >( mutated );
     337                if ( ! inst ) return mutated;
     338
    320339                // exit early if no need for further mutation
    321340                if ( inst->get_parameters().empty() ) return inst;
     
    349368                                substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    350369                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    351                                 concDecl->acceptMutator( *visitor ); // recursively instantiate members
    352                                 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
     370                                concDecl->acceptMutator( *this ); // recursively instantiate members
     371                                DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
    353372                        }
    354373                        StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    369388        }
    370389
    371         Type* GenericInstantiator::postmutate( UnionInstType *inst ) {
     390        Type* GenericInstantiator::mutate( UnionInstType *inst ) {
     391                // mutate subtypes
     392                Type *mutated = Mutator::mutate( inst );
     393                inst = dynamic_cast< UnionInstType* >( mutated );
     394                if ( ! inst ) return mutated;
     395
    372396                // exit early if no need for further mutation
    373397                if ( inst->get_parameters().empty() ) return inst;
     
    399423                                substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    400424                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    401                                 concDecl->acceptMutator( *visitor ); // recursively instantiate members
    402                                 declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
     425                                concDecl->acceptMutator( *this ); // recursively instantiate members
     426                                DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
    403427                        }
    404428                        UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    418442        }
    419443
    420         void GenericInstantiator::beginScope() {
     444        void GenericInstantiator::doBeginScope() {
     445                DeclMutator::doBeginScope();
    421446                instantiations.beginScope();
    422447                dtypeStatics.beginScope();
    423448        }
    424449
    425         void GenericInstantiator::endScope() {
     450        void GenericInstantiator::doEndScope() {
     451                DeclMutator::doEndScope();
    426452                instantiations.endScope();
    427453                dtypeStatics.endScope();
Note: See TracChangeset for help on using the changeset viewer.