- Timestamp:
- Jun 28, 2019, 1:29:52 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 417117e
- Parents:
- 7d0881c
- Location:
- src/AST
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/AST/TypeSubstitution.cpp ¶
r7d0881c r55b6476 92 92 namespace { 93 93 struct EnvTrimmer { 94 ptr<TypeSubstitution>env;94 const TypeSubstitution * env; 95 95 TypeSubstitution * newEnv; 96 96 EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} … … 108 108 if ( env ) { 109 109 TypeSubstitution * newEnv = new TypeSubstitution(); 110 #if TIME_TO_CONVERT_PASSES111 110 Pass<EnvTrimmer> trimmer( env, newEnv ); 112 111 expr->accept( trimmer ); 113 #else114 (void)expr;115 (void)env;116 #endif117 112 return newEnv; 118 113 } … … 121 116 122 117 void TypeSubstitution::normalize() { 123 #if TIME_TO_CONVERT_PASSES 124 PassVisitor<Substituter> sub( *this, true ); 118 Pass<Substituter> sub( *this, true ); 125 119 do { 126 120 sub.pass.subCount = 0; 127 121 sub.pass.freeOnly = true; 128 122 for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { 129 i->second = i->second->accept Mutator( sub );123 i->second = i->second->accept( sub ); 130 124 } 131 125 } while ( sub.pass.subCount ); 132 #endif 133 } 134 135 #if TIME_TO_CONVERT_PASSES 136 137 Type * TypeSubstitution::Substituter::postmutate( TypeInstType *inst ) { 126 } 127 128 const Type * TypeSubstitution::Substituter::postvisit( const TypeInstType *inst ) { 138 129 BoundVarsType::const_iterator bound = boundVars.find( inst->name ); 139 130 if ( bound != boundVars.end() ) return inst; … … 146 137 // Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here. 147 138 // TODO: investigate preventing type variables from being bound to themselves in the first place. 148 if ( TypeInstType * replacement = i->second.as<TypeInstType>() ) {139 if ( const TypeInstType * replacement = i->second.as<TypeInstType>() ) { 149 140 if ( inst->name == replacement->name ) { 150 141 return inst; … … 153 144 // std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl; 154 145 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 ); 160 } // if 161 } 162 163 Expression * TypeSubstitution::Substituter::postmutate( NameExpr * nameExpr ) { 146 ptr<Type> newType = i->second; // force clone if needed 147 add_qualifiers( newType, inst->qualifiers ); 148 // Note: need to recursively apply substitution to the new type because normalize does not 149 // substitute bound vars, but bound vars must be substituted when not in freeOnly mode. 150 newType = newType->accept( *visitor ); 151 return newType.release(); 152 } // if 153 } 154 155 const Expr * TypeSubstitution::Substituter::postvisit( const NameExpr * nameExpr ) { 164 156 VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name ); 165 157 if ( i == sub.varEnv.end() ) { … … 168 160 subCount++; 169 161 delete nameExpr; 170 return i->second ->clone();171 } // if 172 } 173 174 void TypeSubstitution::Substituter::pre mutate( Type *type ) {162 return i->second; 163 } // if 164 } 165 166 void TypeSubstitution::Substituter::previsit( const ParameterizedType * ptype ) { 175 167 GuardValue( boundVars ); 176 168 // bind type variables from forall-qualifiers 177 169 if ( freeOnly ) { 178 for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar) {179 boundVars.insert( (*tyvar)->name );170 for ( const TypeDecl * tyvar : ptype->forall ) { 171 boundVars.insert( tyvar->name ); 180 172 } // for 181 173 } // if 182 174 } 183 175 184 template< typename TypeClass > 185 void TypeSubstitution::Substituter::handleAggregateType( TypeClass * type ) { 176 void TypeSubstitution::Substituter::handleAggregateType( const ReferenceToType * type ) { 186 177 GuardValue( boundVars ); 187 178 // bind type variables from forall-qualifiers 188 179 if ( freeOnly ) { 189 for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar) {190 boundVars.insert( (*tyvar)->name );180 for ( const TypeDecl * tyvar : type->forall ) { 181 boundVars.insert( tyvar->name ); 191 182 } // for 192 183 // 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 199 } // if 200 } 201 202 void TypeSubstitution::Substituter::premutate( StructInstType * aggregateUseType ) { 184 if ( auto decl = type->aggr() ) { 185 const std::vector<ptr<TypeDecl>> &baseParameters = decl->params; 186 if (! type->params.empty()) { 187 for ( const TypeDecl * tyvar : baseParameters ) { 188 boundVars.insert( tyvar->name ); 189 } // for 190 } // if 191 } 192 } // if 193 } 194 195 void TypeSubstitution::Substituter::previsit( const StructInstType * aggregateUseType ) { 203 196 handleAggregateType( aggregateUseType ); 204 197 } 205 198 206 void TypeSubstitution::Substituter::pre mutate(UnionInstType *aggregateUseType ) {199 void TypeSubstitution::Substituter::previsit( const UnionInstType *aggregateUseType ) { 207 200 handleAggregateType( aggregateUseType ); 208 201 } 209 210 #endif211 202 212 203 } // namespace ast -
TabularUnified src/AST/TypeSubstitution.hpp ¶
r7d0881c r55b6476 155 155 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {} 156 156 157 #if TIME_TO_CONVERT_PASSES 158 159 Type * postmutate( TypeInstType * aggregateUseType ); 160 Expression * postmutate( NameExpr * nameExpr ); 157 const Type * postvisit( const TypeInstType * aggregateUseType ); 158 const Expr * postvisit( const NameExpr * nameExpr ); 161 159 162 160 /// Records type variable bindings from forall-statements 163 void pre mutate(Type * type );161 void previsit( const ParameterizedType * type ); 164 162 /// Records type variable bindings from forall-statements and instantiations of generic types 165 template< typename TypeClass > void handleAggregateType( TypeClass * type ); 166 167 void premutate( StructInstType * aggregateUseType ); 168 void premutate( UnionInstType * aggregateUseType ); 169 170 #endif 163 void handleAggregateType( const ReferenceToType * type ); 164 165 void previsit( const StructInstType * aggregateUseType ); 166 void previsit( const UnionInstType * aggregateUseType ); 171 167 172 168 const TypeSubstitution & sub;
Note: See TracChangeset
for help on using the changeset viewer.