Ignore:
Timestamp:
Jan 11, 2017, 4:11:02 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
075734f
Parents:
bb82c03 (diff), d3a85240 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    rbb82c03 r2162c2c  
    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.