Changeset 58fe85a for src/AST/TypeSubstitution.cpp
- Timestamp:
- Jan 7, 2021, 3:27:00 PM (5 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/TypeSubstitution.cpp
r3c64c668 r58fe85a 19 19 namespace ast { 20 20 21 22 // size_t TypeSubstitution::Substituter::traceId = Stats::Heap::new_stacktrace_id("TypeSubstitution"); 23 21 24 TypeSubstitution::TypeSubstitution() { 22 25 } … … 36 39 void TypeSubstitution::initialize( const TypeSubstitution &src, TypeSubstitution &dest ) { 37 40 dest.typeEnv.clear(); 38 dest.varEnv.clear();39 41 dest.add( src ); 40 42 } … … 44 46 typeEnv[ i->first ] = i->second; 45 47 } // for 46 for ( VarEnvType::const_iterator i = other.varEnv.begin(); i != other.varEnv.end(); ++i ) {47 varEnv[ i->first ] = i->second;48 } // for49 48 } 50 49 51 void TypeSubstitution::add( std::stringformalType, const Type *actualType ) {52 typeEnv[ formalType ] = actualType;50 void TypeSubstitution::add( const TypeInstType * formalType, const Type *actualType ) { 51 typeEnv[ *formalType ] = actualType; 53 52 } 54 53 55 void TypeSubstitution::add Var( std::string formalExpr, const Expr *actualExpr) {56 varEnv[ formalExpr ] = actualExpr;54 void TypeSubstitution::add( const TypeInstType::TypeEnvKey & key, const Type * actualType) { 55 typeEnv[ key ] = actualType; 57 56 } 58 57 59 void TypeSubstitution::remove( std::stringformalType ) {60 TypeEnvType::iterator i = typeEnv.find( formalType );58 void TypeSubstitution::remove( const TypeInstType * formalType ) { 59 TypeEnvType::iterator i = typeEnv.find( *formalType ); 61 60 if ( i != typeEnv.end() ) { 62 typeEnv.erase( formalType );61 typeEnv.erase( *formalType ); 63 62 } // if 64 63 } 65 64 66 const Type *TypeSubstitution::lookup( std::stringformalType ) const {67 TypeEnvType::const_iterator i = typeEnv.find( formalType );65 const Type *TypeSubstitution::lookup( const TypeInstType * formalType ) const { 66 TypeEnvType::const_iterator i = typeEnv.find( *formalType ); 68 67 69 68 // break on not in substitution set … … 72 71 // attempt to transitively follow TypeInstType links. 73 72 while ( const TypeInstType *actualType = i->second.as<TypeInstType>()) { 74 const std::string& typeName = actualType->name;75 76 73 // break cycles in the transitive follow 77 if ( formalType == typeName ) break;74 if ( *formalType == *actualType ) break; 78 75 79 76 // Look for the type this maps to, returning previous mapping if none-such 80 i = typeEnv.find( typeName );77 i = typeEnv.find( *actualType ); 81 78 if ( i == typeEnv.end() ) return actualType; 82 79 } … … 87 84 88 85 bool TypeSubstitution::empty() const { 89 return typeEnv.empty() && varEnv.empty();86 return typeEnv.empty(); 90 87 } 91 88 92 89 namespace { 93 90 struct EnvTrimmer { 94 ptr<TypeSubstitution>env;91 const TypeSubstitution * env; 95 92 TypeSubstitution * newEnv; 96 93 EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} 97 void previsit( TypeDecl * tyDecl) {94 void previsit( FunctionType * ftype ) { 98 95 // 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 } 101 100 } 102 101 } … … 108 107 if ( env ) { 109 108 TypeSubstitution * newEnv = new TypeSubstitution(); 110 #if TIME_TO_CONVERT_PASSES111 109 Pass<EnvTrimmer> trimmer( env, newEnv ); 112 110 expr->accept( trimmer ); 113 #else114 (void)expr;115 (void)env;116 #endif117 111 return newEnv; 118 112 } … … 121 115 122 116 void TypeSubstitution::normalize() { 123 #if TIME_TO_CONVERT_PASSES 124 PassVisitor<Substituter> sub( *this, true ); 117 Pass<Substituter> sub( *this, true ); 125 118 do { 126 sub. pass.subCount = 0;127 sub. pass.freeOnly = true;119 sub.core.subCount = 0; 120 sub.core.freeOnly = true; 128 121 for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { 129 i->second = i->second->accept Mutator( sub );122 i->second = i->second->accept( sub ); 130 123 } 131 } while ( sub.pass.subCount ); 132 #endif 124 } while ( sub.core.subCount ); 133 125 } 134 126 135 #if TIME_TO_CONVERT_PASSES 136 137 Type * TypeSubstitution::Substituter::postmutate( TypeInstType *inst ) { 138 BoundVarsType::const_iterator bound = boundVars.find( inst->name ); 127 const Type * TypeSubstitution::Substituter::postvisit( const TypeInstType *inst ) { 128 BoundVarsType::const_iterator bound = boundVars.find( *inst ); 139 129 if ( bound != boundVars.end() ) return inst; 140 130 141 TypeEnvType::const_iterator i = sub.typeEnv.find( inst->name);131 TypeEnvType::const_iterator i = sub.typeEnv.find( *inst ); 142 132 if ( i == sub.typeEnv.end() ) { 143 133 return inst; … … 146 136 // Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here. 147 137 // 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 ) { 150 140 return inst; 151 141 } … … 153 143 // std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl; 154 144 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(); 160 151 } // if 161 152 } 162 153 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 ) { 154 void TypeSubstitution::Substituter::previsit( const FunctionType * ptype ) { 175 155 GuardValue( boundVars ); 176 156 // bind type variables from forall-qualifiers 177 157 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 ); 180 160 } // for 181 161 } // if 182 162 } 183 163 184 template< typename TypeClass > 185 void TypeSubstitution::Substituter::handleAggregateType( TypeClass* type ) {164 /* 165 void TypeSubstitution::Substituter::handleAggregateType( const BaseInstType * type ) { 186 166 GuardValue( boundVars ); 187 167 // bind type variables from forall-qualifiers 188 168 if ( freeOnly ) { 189 for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar ) {190 boundVars.insert( (*tyvar)->name );191 } // for192 169 // 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 } 199 177 } // if 200 178 } 201 179 202 void TypeSubstitution::Substituter::pre mutate(StructInstType * aggregateUseType ) {180 void TypeSubstitution::Substituter::previsit( const StructInstType * aggregateUseType ) { 203 181 handleAggregateType( aggregateUseType ); 204 182 } 205 183 206 void TypeSubstitution::Substituter::pre mutate(UnionInstType *aggregateUseType ) {184 void TypeSubstitution::Substituter::previsit( const UnionInstType *aggregateUseType ) { 207 185 handleAggregateType( aggregateUseType ); 208 186 } 209 210 #endif 187 */ 211 188 212 189 } // namespace ast
Note:
See TracChangeset
for help on using the changeset viewer.