Ignore:
Timestamp:
Aug 23, 2017, 6:22:07 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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:
87e08e24, cb811ac
Parents:
9f07232 (diff), bd37119 (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 plg2:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    r9f07232 rd3e4d6c  
    162162                /// Should not make use of type environment to replace types of function parameter and return values.
    163163                bool inFunctionType = false;
     164                /// Index of current member, used to recreate MemberExprs with the member from an instantiation
     165                int memberIndex = -1;
    164166                GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
    165167
     
    167169                Type* postmutate( UnionInstType *inst );
    168170
    169                 void premutate( __attribute__((unused)) FunctionType * ftype ) {
     171                // fix MemberExprs to use the member from the instantiation
     172                void premutate( MemberExpr * memberExpr );
     173                Expression * postmutate( MemberExpr * memberExpr );
     174
     175                void premutate( FunctionType * ) {
    170176                        GuardValue( inFunctionType );
    171177                        inFunctionType = true;
     
    414420        }
    415421
     422        namespace {
     423                bool isGenericType( Type * t ) {
     424                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
     425                                return ! inst->parameters.empty();
     426                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
     427                                return ! inst->parameters.empty();
     428                        }
     429                        return false;
     430                }
     431
     432                AggregateDecl * getAggr( Type * t ) {
     433                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
     434                                return inst->baseStruct;
     435                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
     436                                return inst->baseUnion;
     437                        }
     438                        assertf( false, "Non-aggregate type: %s", toString( t ).c_str() );
     439                }
     440        }
     441
     442        void GenericInstantiator::premutate( MemberExpr * memberExpr ) {
     443                GuardValue( memberIndex );
     444                memberIndex = -1;
     445                if ( isGenericType( memberExpr->aggregate->result ) ) {
     446                        // find the location of the member
     447                        AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
     448                        std::list< Declaration * > & members = aggr->members;
     449                        memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) );
     450                        assertf( memberIndex < (int)members.size(), "Could not find member %s in generic type %s", toString( memberExpr->member ).c_str(), toString( memberExpr->aggregate ).c_str() );
     451                }
     452        }
     453
     454        Expression * GenericInstantiator::postmutate( MemberExpr * memberExpr ) {
     455                if ( memberIndex != -1 ) {
     456                        // using the location from the generic type, find the member in the instantiation and rebuild the member expression
     457                        AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
     458                        assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." );
     459                        Declaration * member = *std::next( aggr->members.begin(), memberIndex );
     460                        assertf( member->name == memberExpr->member->name, "Instantiation has different member order than the generic type. %s / %s", toString( member ).c_str(), toString( memberExpr->member ).c_str() );
     461                        DeclarationWithType * field = safe_dynamic_cast< DeclarationWithType * >( member );
     462                        MemberExpr * ret = new MemberExpr( field, memberExpr->aggregate->clone() );
     463                        std::swap( ret->env, memberExpr->env );
     464                        delete memberExpr;
     465                        return ret;
     466                }
     467                return memberExpr;
     468        }
     469
    416470        void GenericInstantiator::beginScope() {
    417471                instantiations.beginScope();
Note: See TracChangeset for help on using the changeset viewer.