Changeset 90152a4 for src/SynTree/TypeSubstitution.cc
- Timestamp:
- Aug 27, 2018, 4:40:34 PM (7 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SynTree/TypeSubstitution.cc
rf9feab8 r90152a4 106 106 } 107 107 108 namespace { 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 122 TypeSubstitution * 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 108 132 void TypeSubstitution::normalize() { 133 PassVisitor<Substituter> sub( *this, true ); 109 134 do { 110 sub Count = 0;111 freeOnly = true;135 sub.pass.subCount = 0; 136 sub.pass.freeOnly = true; 112 137 for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { 113 i->second = i->second->acceptMutator( *this);138 i->second = i->second->acceptMutator( sub ); 114 139 } 115 } while ( sub Count );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 143 Type * TypeSubstitution::Substituter::postmutate( TypeInstType *inst ) { 144 BoundVarsType::const_iterator bound = boundVars.find( inst->name ); 120 145 if ( bound != boundVars.end() ) return inst; 121 146 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() ) { 124 149 return inst; 125 150 } 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; 129 160 subCount++; 130 Type * newtype = i->second->clone();161 Type * newtype = i->second->clone(); 131 162 newtype->get_qualifiers() |= inst->get_qualifiers(); 132 163 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 169 Expression * TypeSubstitution::Substituter::postmutate( NameExpr * nameExpr ) { 170 VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name ); 171 if ( i == sub.varEnv.end() ) { 140 172 return nameExpr; 141 173 } else { … … 146 178 } 147 179 148 template< typename TypeClass > 149 Type *TypeSubstitution::handleType( TypeClass *type ) { 150 ValueGuard<BoundVarsType> oldBoundVars( boundVars ); 180 void TypeSubstitution::Substituter::premutate( Type * type ) { 181 GuardValue( boundVars ); 151 182 // bind type variables from forall-qualifiers 152 183 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 ); 155 186 } // for 156 187 } // if 157 Type *ret = Mutator::mutate( type );158 return ret;159 188 } 160 189 161 190 template< typename TypeClass > 162 Type *TypeSubstitution::handleAggregateType( TypeClass *type ) {163 ValueGuard<BoundVarsType> oldBoundVars( boundVars );191 void TypeSubstitution::Substituter::handleAggregateType( TypeClass * type ) { 192 GuardValue( boundVars ); 164 193 // bind type variables from forall-qualifiers 165 194 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 ); 168 197 } // for 169 198 // bind type variables from generic type instantiations 170 199 std::list< TypeDecl* > *baseParameters = type->get_baseParameters(); 171 if ( baseParameters && ! type-> get_parameters().empty() ) {200 if ( baseParameters && ! type->parameters.empty() ) { 172 201 for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) { 173 boundVars.insert( (*tyvar)-> get_name());202 boundVars.insert( (*tyvar)->name ); 174 203 } // for 175 204 } // if 176 205 } // 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 208 void TypeSubstitution::Substituter::premutate( StructInstType * aggregateUseType ) { 209 handleAggregateType( aggregateUseType ); 210 } 211 212 void TypeSubstitution::Substituter::premutate( UnionInstType *aggregateUseType ) { 213 handleAggregateType( aggregateUseType ); 231 214 } 232 215
Note:
See TracChangeset
for help on using the changeset viewer.