Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/InstantiateGeneric.cc

    r760ba67 rb95fe40  
    2727#include "Common/utility.h"            // for deleteAll, cloneAll
    2828#include "GenPoly.h"                   // for isPolyType, typesPolyCompatible
     29#include "ResolvExpr/typeops.h"
    2930#include "ScopedSet.h"                 // for ScopedSet, ScopedSet<>::iterator
    3031#include "ScrubTyVars.h"               // for ScrubTyVars
     
    151152                return gt;
    152153        }
     154
     155        /// Add cast to dtype-static member expressions so that type information is not lost in GenericInstantiator
     156        struct FixDtypeStatic final {
     157                Expression * postmutate( MemberExpr * memberExpr );
     158
     159                template<typename AggrInst>
     160                Expression * fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr );
     161        };
    153162
    154163        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
     
    198207
    199208        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
     209                PassVisitor<FixDtypeStatic> fixer;
    200210                PassVisitor<GenericInstantiator> instantiator;
     211
     212                mutateAll( translationUnit, fixer );
    201213                mutateAll( translationUnit, instantiator );
     214        }
     215
     216        bool isDtypeStatic( const std::list< TypeDecl* >& baseParams ) {
     217                return std::all_of( baseParams.begin(), baseParams.end(), []( TypeDecl * td ) { return ! td->isComplete(); } );
    202218        }
    203219
     
    479495        }
    480496
     497        template< typename AggrInst >
     498        Expression * FixDtypeStatic::fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ) {
     499                // need to cast dtype-static member expressions to their actual type before that type is erased.
     500                auto & baseParams = *inst->get_baseParameters();
     501                if ( isDtypeStatic( baseParams ) ) {
     502                        if ( ! ResolvExpr::typesCompatible( memberExpr->result, memberExpr->member->get_type(), SymTab::Indexer() ) ) {
     503                                // type of member and type of expression differ, so add cast to actual type
     504                                return new CastExpr( memberExpr, memberExpr->result->clone() );
     505                        }
     506                }
     507                return memberExpr;
     508        }
     509
     510        Expression * FixDtypeStatic::postmutate( MemberExpr * memberExpr ) {
     511                Type * aggrType = memberExpr->aggregate->result;
     512                if ( isGenericType( aggrType ) ) {
     513                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( aggrType ) ) {
     514                                return fixMemberExpr( inst, memberExpr );
     515                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( aggrType ) ) {
     516                                return fixMemberExpr( inst, memberExpr );
     517                        }
     518                }
     519                return memberExpr;
     520        }
     521
    481522} // namespace GenPoly
    482523
Note: See TracChangeset for help on using the changeset viewer.