Ignore:
Timestamp:
Aug 27, 2018, 4:40:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b7c89aa
Parents:
f9feab8 (diff), 305581d (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 cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SynTree/TypeSubstitution.cc

    rf9feab8 r90152a4  
    106106}
    107107
     108namespace {
     109        struct EnvTrimmer {
     110                TypeSubstitution * env, * newEnv;
     111                EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
     112                void previsit( TypeDecl * tyDecl ) {
     113                        // transfer known bindings for seen type variables
     114                        if ( Type * t = env->lookup( tyDecl->name ) ) {
     115                                newEnv->add( tyDecl->name, t );
     116                        }
     117                }
     118        };
     119} // namespace
     120
     121/// reduce environment to just the parts that are referenced in a given expression
     122TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, TypeSubstitution * env ) {
     123        if ( env ) {
     124                TypeSubstitution * newEnv = new TypeSubstitution();
     125                PassVisitor<EnvTrimmer> trimmer( env, newEnv );
     126                expr->accept( trimmer );
     127                return newEnv;
     128        }
     129        return nullptr;
     130}
     131
    108132void TypeSubstitution::normalize() {
     133        PassVisitor<Substituter> sub( *this, true );
    109134        do {
    110                 subCount = 0;
    111                 freeOnly = true;
     135                sub.pass.subCount = 0;
     136                sub.pass.freeOnly = true;
    112137                for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
    113                         i->second = i->second->acceptMutator( *this );
     138                        i->second = i->second->acceptMutator( sub );
    114139                }
    115         } while ( subCount );
    116 }
    117 
    118 Type * TypeSubstitution::mutate( TypeInstType *inst ) {
    119         BoundVarsType::const_iterator bound = boundVars.find( inst->get_name() );
     140        } while ( sub.pass.subCount );
     141}
     142
     143Type * TypeSubstitution::Substituter::postmutate( TypeInstType *inst ) {
     144        BoundVarsType::const_iterator bound = boundVars.find( inst->name );
    120145        if ( bound != boundVars.end() ) return inst;
    121146
    122         TypeEnvType::const_iterator i = typeEnv.find( inst->get_name() );
    123         if ( i == typeEnv.end() ) {
     147        TypeEnvType::const_iterator i = sub.typeEnv.find( inst->get_name() );
     148        if ( i == sub.typeEnv.end() ) {
    124149                return inst;
    125150        } else {
    126 ///         std::cout << "found " << inst->get_name() << ", replacing with ";
    127 ///         i->second->print( std::cout );
    128 ///         std::cout << std::endl;
     151                // cut off infinite loop for the case where a type is bound to itself.
     152                // Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here.
     153                // TODO: investigate preventing type variables from being bound to themselves in the first place.
     154                if ( TypeInstType * replacement = dynamic_cast< TypeInstType * >( i->second ) ) {
     155                        if ( inst->name == replacement->name ) {
     156                                return inst;
     157                        }
     158                }
     159                // std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl;
    129160                subCount++;
    130                 Type *newtype = i->second->clone();
     161                Type * newtype = i->second->clone();
    131162                newtype->get_qualifiers() |= inst->get_qualifiers();
    132163                delete inst;
    133                 return newtype;
    134         } // if
    135 }
    136 
    137 Expression * TypeSubstitution::mutate( NameExpr *nameExpr ) {
    138         VarEnvType::const_iterator i = varEnv.find( nameExpr->get_name() );
    139         if ( i == varEnv.end() ) {
     164                // 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.
     165                return newtype->acceptMutator( *visitor );
     166        } // if
     167}
     168
     169Expression * TypeSubstitution::Substituter::postmutate( NameExpr * nameExpr ) {
     170        VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name );
     171        if ( i == sub.varEnv.end() ) {
    140172                return nameExpr;
    141173        } else {
     
    146178}
    147179
    148 template< typename TypeClass >
    149 Type *TypeSubstitution::handleType( TypeClass *type ) {
    150         ValueGuard<BoundVarsType> oldBoundVars( boundVars );
     180void TypeSubstitution::Substituter::premutate( Type * type ) {
     181        GuardValue( boundVars );
    151182        // bind type variables from forall-qualifiers
    152183        if ( freeOnly ) {
    153                 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    154                         boundVars.insert( (*tyvar )->get_name() );
     184                for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar ) {
     185                        boundVars.insert( (*tyvar)->name );
    155186                } // for
    156187        } // if
    157         Type *ret = Mutator::mutate( type );
    158         return ret;
    159188}
    160189
    161190template< typename TypeClass >
    162 Type *TypeSubstitution::handleAggregateType( TypeClass *type ) {
    163         ValueGuard<BoundVarsType> oldBoundVars( boundVars );
     191void TypeSubstitution::Substituter::handleAggregateType( TypeClass * type ) {
     192        GuardValue( boundVars );
    164193        // bind type variables from forall-qualifiers
    165194        if ( freeOnly ) {
    166                 for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
    167                         boundVars.insert( (*tyvar )->get_name() );
     195                for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar ) {
     196                        boundVars.insert( (*tyvar)->name );
    168197                } // for
    169198                // bind type variables from generic type instantiations
    170199                std::list< TypeDecl* > *baseParameters = type->get_baseParameters();
    171                 if ( baseParameters && ! type->get_parameters().empty() ) {
     200                if ( baseParameters && ! type->parameters.empty() ) {
    172201                        for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) {
    173                                 boundVars.insert( (*tyvar)->get_name() );
     202                                boundVars.insert( (*tyvar)->name );
    174203                        } // for
    175204                } // if
    176205        } // if
    177         Type *ret = Mutator::mutate( type );
    178         return ret;
    179 }
    180 
    181 Type * TypeSubstitution::mutate( VoidType *voidType ) {
    182         return handleType( voidType );
    183 }
    184 
    185 Type * TypeSubstitution::mutate( BasicType *basicType ) {
    186         return handleType( basicType );
    187 }
    188 
    189 Type * TypeSubstitution::mutate( PointerType *pointerType ) {
    190         return handleType( pointerType );
    191 }
    192 
    193 Type * TypeSubstitution::mutate( ArrayType *arrayType ) {
    194         return handleType( arrayType );
    195 }
    196 
    197 Type * TypeSubstitution::mutate( FunctionType *functionType ) {
    198         return handleType( functionType );
    199 }
    200 
    201 Type * TypeSubstitution::mutate( StructInstType *aggregateUseType ) {
    202         return handleAggregateType( aggregateUseType );
    203 }
    204 
    205 Type * TypeSubstitution::mutate( UnionInstType *aggregateUseType ) {
    206         return handleAggregateType( aggregateUseType );
    207 }
    208 
    209 Type * TypeSubstitution::mutate( EnumInstType *aggregateUseType ) {
    210         return handleType( aggregateUseType );
    211 }
    212 
    213 Type * TypeSubstitution::mutate( TraitInstType *aggregateUseType ) {
    214         return handleType( aggregateUseType );
    215 }
    216 
    217 Type * TypeSubstitution::mutate( TupleType *tupleType ) {
    218         return handleType( tupleType );
    219 }
    220 
    221 Type * TypeSubstitution::mutate( VarArgsType *varArgsType ) {
    222         return handleType( varArgsType );
    223 }
    224 
    225 Type * TypeSubstitution::mutate( ZeroType *zeroType ) {
    226         return handleType( zeroType );
    227 }
    228 
    229 Type * TypeSubstitution::mutate( OneType *oneType ) {
    230         return handleType( oneType );
     206}
     207
     208void TypeSubstitution::Substituter::premutate( StructInstType * aggregateUseType ) {
     209        handleAggregateType( aggregateUseType );
     210}
     211
     212void TypeSubstitution::Substituter::premutate( UnionInstType *aggregateUseType ) {
     213        handleAggregateType( aggregateUseType );
    231214}
    232215
Note: See TracChangeset for help on using the changeset viewer.