Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2b4daf2, 64aeca0
Parents:
3c64c668 (diff), eef8dfb (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' into park_unpark

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/TypeSubstitution.cpp

    r3c64c668 r58fe85a  
    1919namespace ast {
    2020
     21
     22// size_t TypeSubstitution::Substituter::traceId = Stats::Heap::new_stacktrace_id("TypeSubstitution");
     23
    2124TypeSubstitution::TypeSubstitution() {
    2225}
     
    3639void TypeSubstitution::initialize( const TypeSubstitution &src, TypeSubstitution &dest ) {
    3740        dest.typeEnv.clear();
    38         dest.varEnv.clear();
    3941        dest.add( src );
    4042}
     
    4446                typeEnv[ i->first ] = i->second;
    4547        } // for
    46         for ( VarEnvType::const_iterator i = other.varEnv.begin(); i != other.varEnv.end(); ++i ) {
    47                 varEnv[ i->first ] = i->second;
    48         } // for
    4948}
    5049
    51 void TypeSubstitution::add( std::string formalType, const Type *actualType ) {
    52         typeEnv[ formalType ] = actualType;
     50void TypeSubstitution::add( const TypeInstType * formalType, const Type *actualType ) {
     51        typeEnv[ *formalType ] = actualType;
    5352}
    5453
    55 void TypeSubstitution::addVar( std::string formalExpr, const Expr *actualExpr ) {
    56         varEnv[ formalExpr ] = actualExpr;
     54void TypeSubstitution::add( const TypeInstType::TypeEnvKey & key, const Type * actualType) {
     55        typeEnv[ key ] = actualType;
    5756}
    5857
    59 void TypeSubstitution::remove( std::string formalType ) {
    60         TypeEnvType::iterator i = typeEnv.find( formalType );
     58void TypeSubstitution::remove( const TypeInstType * formalType ) {
     59        TypeEnvType::iterator i = typeEnv.find( *formalType );
    6160        if ( i != typeEnv.end() ) {
    62                 typeEnv.erase( formalType );
     61                typeEnv.erase( *formalType );
    6362        } // if
    6463}
    6564
    66 const Type *TypeSubstitution::lookup( std::string formalType ) const {
    67         TypeEnvType::const_iterator i = typeEnv.find( formalType );
     65const Type *TypeSubstitution::lookup( const TypeInstType * formalType ) const {
     66        TypeEnvType::const_iterator i = typeEnv.find( *formalType );
    6867
    6968        // break on not in substitution set
     
    7271        // attempt to transitively follow TypeInstType links.
    7372        while ( const TypeInstType *actualType = i->second.as<TypeInstType>()) {
    74                 const std::string& typeName = actualType->name;
    75 
    7673                // break cycles in the transitive follow
    77                 if ( formalType == typeName ) break;
     74                if ( *formalType == *actualType ) break;
    7875
    7976                // Look for the type this maps to, returning previous mapping if none-such
    80                 i = typeEnv.find( typeName );
     77                i = typeEnv.find( *actualType );
    8178                if ( i == typeEnv.end() ) return actualType;
    8279        }
     
    8784
    8885bool TypeSubstitution::empty() const {
    89         return typeEnv.empty() && varEnv.empty();
     86        return typeEnv.empty();
    9087}
    9188
    9289namespace {
    9390        struct EnvTrimmer {
    94                 ptr<TypeSubstitution> env;
     91                const TypeSubstitution * env;
    9592                TypeSubstitution * newEnv;
    9693                EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    97                 void previsit( TypeDecl * tyDecl ) {
     94                void previsit( FunctionType * ftype ) {
    9895                        // transfer known bindings for seen type variables
    99                         if ( const Type * t = env->lookup( tyDecl->name ) ) {
    100                                 newEnv->add( tyDecl->name, t );
     96                        for (auto & formal : ftype->forall) {
     97                                if ( const Type * t = env->lookup( formal ) ) {
     98                                        newEnv->add( formal, t );
     99                                }
    101100                        }
    102101                }
     
    108107        if ( env ) {
    109108                TypeSubstitution * newEnv = new TypeSubstitution();
    110 #if TIME_TO_CONVERT_PASSES
    111109                Pass<EnvTrimmer> trimmer( env, newEnv );
    112110                expr->accept( trimmer );
    113 #else
    114                 (void)expr;
    115                 (void)env;
    116 #endif
    117111                return newEnv;
    118112        }
     
    121115
    122116void TypeSubstitution::normalize() {
    123 #if TIME_TO_CONVERT_PASSES
    124         PassVisitor<Substituter> sub( *this, true );
     117        Pass<Substituter> sub( *this, true );
    125118        do {
    126                 sub.pass.subCount = 0;
    127                 sub.pass.freeOnly = true;
     119                sub.core.subCount = 0;
     120                sub.core.freeOnly = true;
    128121                for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
    129                         i->second = i->second->acceptMutator( sub );
     122                        i->second = i->second->accept( sub );
    130123                }
    131         } while ( sub.pass.subCount );
    132 #endif
     124        } while ( sub.core.subCount );
    133125}
    134126
    135 #if TIME_TO_CONVERT_PASSES
    136 
    137 Type * TypeSubstitution::Substituter::postmutate( TypeInstType *inst ) {
    138         BoundVarsType::const_iterator bound = boundVars.find( inst->name );
     127const Type * TypeSubstitution::Substituter::postvisit( const TypeInstType *inst ) {
     128        BoundVarsType::const_iterator bound = boundVars.find( *inst );
    139129        if ( bound != boundVars.end() ) return inst;
    140130
    141         TypeEnvType::const_iterator i = sub.typeEnv.find( inst->name );
     131        TypeEnvType::const_iterator i = sub.typeEnv.find( *inst );
    142132        if ( i == sub.typeEnv.end() ) {
    143133                return inst;
     
    146136                // Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here.
    147137                // TODO: investigate preventing type variables from being bound to themselves in the first place.
    148                 if ( TypeInstType * replacement = i->second.as<TypeInstType>() ) {
    149                         if ( inst->name == replacement->name ) {
     138                if ( const TypeInstType * replacement = i->second.as<TypeInstType>() ) {
     139                        if ( *inst == *replacement ) {
    150140                                return inst;
    151141                        }
     
    153143                // std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl;
    154144                subCount++;
    155                 Type * newtype = i->second->clone();
    156                 newtype->get_qualifiers() |= inst->get_qualifiers();
    157                 delete inst;
    158                 // Note: need to recursively apply substitution to the new type because normalize does not substitute bound vars, but bound vars must be substituted when not in freeOnly mode.
    159                 return newtype->acceptMutator( *visitor );
     145                ptr<Type> newType = i->second; // force clone if needed
     146                add_qualifiers( newType, inst->qualifiers );
     147                // Note: need to recursively apply substitution to the new type because normalize does not
     148                // substitute bound vars, but bound vars must be substituted when not in freeOnly mode.
     149                newType = newType->accept( *visitor );
     150                return newType.release();
    160151        } // if
    161152}
    162153
    163 Expression * TypeSubstitution::Substituter::postmutate( NameExpr * nameExpr ) {
    164         VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name );
    165         if ( i == sub.varEnv.end() ) {
    166                 return nameExpr;
    167         } else {
    168                 subCount++;
    169                 delete nameExpr;
    170                 return i->second->clone();
    171         } // if
    172 }
    173 
    174 void TypeSubstitution::Substituter::premutate( Type * type ) {
     154void TypeSubstitution::Substituter::previsit( const FunctionType * ptype ) {
    175155        GuardValue( boundVars );
    176156        // bind type variables from forall-qualifiers
    177157        if ( freeOnly ) {
    178                 for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar ) {
    179                         boundVars.insert( (*tyvar)->name );
     158                for ( auto & tyvar : ptype->forall ) {
     159                                boundVars.insert( *tyvar );
    180160                } // for
    181161        } // if
    182162}
    183163
    184 template< typename TypeClass >
    185 void TypeSubstitution::Substituter::handleAggregateType( TypeClass * type ) {
     164/*
     165void TypeSubstitution::Substituter::handleAggregateType( const BaseInstType * type ) {
    186166        GuardValue( boundVars );
    187167        // bind type variables from forall-qualifiers
    188168        if ( freeOnly ) {
    189                 for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar ) {
    190                         boundVars.insert( (*tyvar)->name );
    191                 } // for
    192169                // bind type variables from generic type instantiations
    193                 std::list< TypeDecl* > *baseParameters = type->get_baseParameters();
    194                 if ( baseParameters && ! type->parameters.empty() ) {
    195                         for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) {
    196                                 boundVars.insert( (*tyvar)->name );
    197                         } // for
    198                 } // if
     170                if ( auto decl = type->aggr() ) {
     171                        if ( ! type->params.empty() ) {
     172                                for ( const TypeDecl * tyvar : decl->params ) {
     173                                        boundVars.insert( *tyvar );
     174                                } // for
     175                        } // if
     176                }
    199177        } // if
    200178}
    201179
    202 void TypeSubstitution::Substituter::premutate( StructInstType * aggregateUseType ) {
     180void TypeSubstitution::Substituter::previsit( const StructInstType * aggregateUseType ) {
    203181        handleAggregateType( aggregateUseType );
    204182}
    205183
    206 void TypeSubstitution::Substituter::premutate( UnionInstType *aggregateUseType ) {
     184void TypeSubstitution::Substituter::previsit( const UnionInstType *aggregateUseType ) {
    207185        handleAggregateType( aggregateUseType );
    208186}
    209 
    210 #endif
     187*/
    211188
    212189} // namespace ast
Note: See TracChangeset for help on using the changeset viewer.