Ignore:
Timestamp:
Nov 10, 2016, 4:16:32 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
8f9cc50
Parents:
b726084
Message:

always construct polymorphic types, substitute generic type parameters when resolving initializers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    rb726084 r30b65d8  
    6666                void handlePtrType( PtrType * type );
    6767
    68           void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
    69           void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
     68          void resolveAggrInit( ReferenceToType *, InitIterator &, InitIterator & );
     69          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator &, TypeSubstitution sub );
    7070          void fallbackInit( ConstructorInit * ctorInit );
    7171
     
    397397        }
    398398
    399         void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd ) {
     399        template< typename AggrInst >
     400        TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) {
     401                std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
     402                std::list< Expression * > typeSubs = inst->get_parameters();
     403                TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
     404                return subs;
     405        }
     406
     407        ReferenceToType * isStructOrUnion( Type * type ) {
     408                if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
     409                        return sit;
     410                } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
     411                        return uit;
     412                }
     413                return nullptr;
     414        }
     415
     416        void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
    400417                DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl );
    401418                assert( dt );
    402                 initContext = dt->get_type();
     419                // need to substitute for generic types, so that casts are to concrete types
     420                initContext = dt->get_type()->clone();
     421                sub.apply( initContext );
     422
    403423                try {
    404424                        if ( init == initEnd ) return; // stop when there are no more initializers
     
    407427                } catch( SemanticError & ) {
    408428                        // need to delve deeper, if you can
    409                         if ( StructInstType * sit = dynamic_cast< StructInstType * >( dt->get_type() ) ) {
    410                                 resolveAggrInit( sit->get_baseStruct(), init, initEnd );
    411                         } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( dt->get_type() ) ) {
    412                                 resolveAggrInit( uit->get_baseUnion(), init, initEnd );
     429                        if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
     430                                resolveAggrInit( type, init, initEnd );
    413431                        } else {
    414432                                // member is not an aggregate type, so can't go any deeper
     
    420438        }
    421439
    422         void Resolver::resolveAggrInit( AggregateDecl * aggr, InitIterator & init, InitIterator & initEnd ) {
    423                 if ( StructDecl * st = dynamic_cast< StructDecl * >( aggr ) ) {
     440        void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
     441
     442                if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
     443                        TypeSubstitution sub = makeGenericSubstitutuion( sit );
     444                        StructDecl * st = sit->get_baseStruct();
    424445                        // want to resolve each initializer to the members of the struct,
    425446                        // but if there are more initializers than members we should stop
    426447                        list< Declaration * >::iterator it = st->get_members().begin();
    427448                        for ( ; it != st->get_members().end(); ++it) {
    428                                 resolveSingleAggrInit( *it, init, initEnd );
     449                                resolveSingleAggrInit( *it, init, initEnd, sub );
    429450                        }
    430                 } else if ( UnionDecl * un = dynamic_cast< UnionDecl * >( aggr ) ) {
     451                } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
     452                        TypeSubstitution sub = makeGenericSubstitutuion( sit );
     453                        UnionDecl * un = uit->get_baseUnion();
    431454                        // only resolve to the first member of a union
    432                         resolveSingleAggrInit( *un->get_members().begin(), init, initEnd );
     455                        resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
    433456                } // if
    434457        }
     
    450473                                (*iter++)->accept( *this );
    451474                        }
    452                 } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) {
    453                         resolveAggrInit( st->get_baseStruct(), iter, end );
    454                 } else if ( UnionInstType * st = dynamic_cast< UnionInstType * >( initContext ) ) {
    455                         resolveAggrInit( st->get_baseUnion(), iter, end );
     475                } else if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
     476                        resolveAggrInit( type, iter, end );
    456477                } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
    457478                        Type * base = tt->get_baseType()->get_base();
Note: See TracChangeset for help on using the changeset viewer.