Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    rbe9288a rf6582243  
    1313// Update Count     : 1
    1414//
     15
     16#include <cassert>
     17#include <list>
     18#include <unordered_map>
     19#include <utility>
     20#include <vector>
     21
    1522#include "InstantiateGeneric.h"
    1623
    17 #include <cassert>                     // for assertf, assert
    18 #include <iterator>                    // for back_inserter, inserter
    19 #include <list>                        // for list, _List_const_iterator
    20 #include <utility>                     // for move, pair
    21 #include <vector>                      // for vector
    22 
    23 #include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
    24 #include "Common/ScopedMap.h"          // for ScopedMap
    25 #include "Common/SemanticError.h"      // for SemanticError
    26 #include "Common/UniqueName.h"         // for UniqueName
    27 #include "Common/utility.h"            // for deleteAll, cloneAll
    28 #include "GenPoly.h"                   // for isPolyType, typesPolyCompatible
    29 #include "ScopedSet.h"                 // for ScopedSet, ScopedSet<>::iterator
    30 #include "ScrubTyVars.h"               // for ScrubTyVars
    31 #include "SynTree/Declaration.h"       // for StructDecl, UnionDecl, TypeDecl
    32 #include "SynTree/Expression.h"        // for TypeExpr, Expression
    33 #include "SynTree/Mutator.h"           // for mutateAll
    34 #include "SynTree/Type.h"              // for StructInstType, UnionInstType
    35 #include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
    36 #include "SynTree/Visitor.h"           // for acceptAll
     24#include "GenPoly.h"
     25#include "ScopedSet.h"
     26#include "ScrubTyVars.h"
     27
     28#include "Common/PassVisitor.h"
     29#include "Common/ScopedMap.h"
     30#include "Common/UniqueName.h"
     31#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"
    3741
    3842
     
    162166                /// Should not make use of type environment to replace types of function parameter and return values.
    163167                bool inFunctionType = false;
     168                /// Index of current member, used to recreate MemberExprs with the member from an instantiation
     169                int memberIndex = -1;
    164170                GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
    165171
     
    167173                Type* postmutate( UnionInstType *inst );
    168174
    169                 void premutate( __attribute__((unused)) FunctionType * ftype ) {
     175                // fix MemberExprs to use the member from the instantiation
     176                void premutate( MemberExpr * memberExpr );
     177                Expression * postmutate( MemberExpr * memberExpr );
     178
     179                void premutate( FunctionType * ) {
    170180                        GuardValue( inFunctionType );
    171181                        inFunctionType = true;
     
    414424        }
    415425
     426        namespace {
     427                bool isGenericType( Type * t ) {
     428                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
     429                                return ! inst->parameters.empty();
     430                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
     431                                return ! inst->parameters.empty();
     432                        }
     433                        return false;
     434                }
     435
     436                AggregateDecl * getAggr( Type * t ) {
     437                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( t ) ) {
     438                                return inst->baseStruct;
     439                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( t ) ) {
     440                                return inst->baseUnion;
     441                        }
     442                        assertf( false, "Non-aggregate type: %s", toString( t ).c_str() );
     443                }
     444        }
     445
     446        void GenericInstantiator::premutate( MemberExpr * memberExpr ) {
     447                GuardValue( memberIndex );
     448                memberIndex = -1;
     449                if ( isGenericType( memberExpr->aggregate->result ) ) {
     450                        // find the location of the member
     451                        AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
     452                        std::list< Declaration * > & members = aggr->members;
     453                        memberIndex = std::distance( members.begin(), std::find( members.begin(), members.end(), memberExpr->member ) );
     454                        assertf( memberIndex < (int)members.size(), "Could not find member %s in generic type %s", toString( memberExpr->member ).c_str(), toString( memberExpr->aggregate ).c_str() );
     455                }
     456        }
     457
     458        Expression * GenericInstantiator::postmutate( MemberExpr * memberExpr ) {
     459                if ( memberIndex != -1 ) {
     460                        // using the location from the generic type, find the member in the instantiation and rebuild the member expression
     461                        AggregateDecl * aggr = getAggr( memberExpr->aggregate->result );
     462                        assertf( memberIndex < (int)aggr->members.size(), "Instantiation somehow has fewer members than the generic type." );
     463                        Declaration * member = *std::next( aggr->members.begin(), memberIndex );
     464                        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() );
     465                        DeclarationWithType * field = safe_dynamic_cast< DeclarationWithType * >( member );
     466                        MemberExpr * ret = new MemberExpr( field, memberExpr->aggregate->clone() );
     467                        std::swap( ret->env, memberExpr->env );
     468                        delete memberExpr;
     469                        return ret;
     470                }
     471                return memberExpr;
     472        }
     473
    416474        void GenericInstantiator::beginScope() {
    417475                instantiations.beginScope();
Note: See TracChangeset for help on using the changeset viewer.