Changeset b21c77a for src/ResolvExpr/Unify.cc
- Timestamp:
- Jun 29, 2018, 4:14:15 PM (6 years ago)
- Branches:
- new-env
- Children:
- 184557e
- Parents:
- 97397a26 (diff), 28f3a19 (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/ResolvExpr/Unify.cc
r97397a26 rb21c77a 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:27:10 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 16 16:22:54 201713 // Update Count : 4 211 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Mon Jun 18 11:58:00 2018 13 // Update Count : 43 14 14 // 15 15 … … 122 122 } 123 123 124 bool isFtype( Type *type ) {125 if ( dynamic_cast< FunctionType* >( type ) ) {126 return true;127 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {128 return typeInst->get_isFtype();129 } // if130 return false;131 }132 133 bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {134 // remove references from other, so that type variables can only bind to value types135 other = other->stripReferences();136 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );137 assert( tyvar != openVars.end() );138 if ( ! tyVarCompatible( tyvar->second, other ) ) {139 return false;140 } // if141 if ( occurs( other, typeInst->get_name(), env ) ) {142 return false;143 } // if144 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {145 if ( curClass->type ) {146 Type *common = 0;147 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to148 Type* newType = curClass->type->clone();149 newType->get_qualifiers() = typeInst->get_qualifiers();150 if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {151 if ( common ) {152 common->get_qualifiers() = Type::Qualifiers();153 EqvClass newClass = *curClass;154 newClass.type = common;155 env.add( std::move(newClass) );156 } // if157 return true;158 } else {159 return false;160 } // if161 } else {162 EqvClass newClass = *curClass;163 newClass.type = other->clone();164 newClass.type->get_qualifiers() = Type::Qualifiers();165 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;166 env.add( std::move(newClass) );167 } // if168 } else {169 EqvClass newClass;170 newClass.vars.insert( typeInst->get_name() );171 newClass.type = other->clone();172 newClass.type->get_qualifiers() = Type::Qualifiers();173 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;174 newClass.data = data;175 env.add( newClass );176 } // if177 return true;178 }179 180 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {181 bool result = true;182 const EqvClass *class1 = env.lookup( var1->get_name() );183 const EqvClass *class2 = env.lookup( var2->get_name() );184 bool widen1 = false, widen2 = false;185 Type *type1 = nullptr, *type2 = nullptr;186 187 if ( class1 ) {188 if ( class1->type ) {189 if ( occurs( class1->type, var2->get_name(), env ) ) {190 return false;191 } // if192 type1 = class1->type->clone();193 } // if194 widen1 = widenMode.widenFirst && class1->allowWidening;195 } // if196 if ( class2 ) {197 if ( class2->type ) {198 if ( occurs( class2->type, var1->get_name(), env ) ) {199 return false;200 } // if201 type2 = class2->type->clone();202 } // if203 widen2 = widenMode.widenSecond && class2->allowWidening;204 } // if205 206 if ( type1 && type2 ) {207 // std::cerr << "has type1 && type2" << std::endl;208 WidenMode newWidenMode ( widen1, widen2 );209 Type *common = 0;210 if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {211 EqvClass newClass1 = *class1;212 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );213 newClass1.allowWidening = widen1 && widen2;214 if ( common ) {215 common->get_qualifiers() = Type::Qualifiers();216 newClass1.type = common;217 } // if218 env.add( std::move(newClass1) );219 } else {220 result = false;221 } // if222 } else if ( class1 && class2 ) {223 if ( type1 ) {224 EqvClass newClass1 = *class1;225 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );226 newClass1.allowWidening = widen1;227 env.add( std::move(newClass1) );228 } else {229 EqvClass newClass2 = *class2;230 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );231 newClass2.allowWidening = widen2;232 env.add( std::move(newClass2) );233 } // if234 } else if ( class1 ) {235 EqvClass newClass1 = *class1;236 newClass1.vars.insert( var2->get_name() );237 newClass1.allowWidening = widen1;238 env.add( std::move(newClass1) );239 } else if ( class2 ) {240 EqvClass newClass2 = *class2;241 newClass2.vars.insert( var1->get_name() );242 newClass2.allowWidening = widen2;243 env.add( std::move(newClass2) );244 } else {245 EqvClass newClass;246 newClass.vars.insert( var1->get_name() );247 newClass.vars.insert( var2->get_name() );248 newClass.allowWidening = widen1 && widen2;249 newClass.data = data;250 env.add( newClass );251 } // if252 return result;253 }254 255 124 bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 256 125 OpenVarSet closedVars; … … 290 159 291 160 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 292 result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );161 result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 293 162 } else if ( isopen1 ) { 294 result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );163 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 295 164 } else if ( isopen2 ) { // TODO: swap widenMode values in call, since type positions are flipped? 296 result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );165 result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 297 166 } else { 298 167 PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
Note: See TracChangeset
for help on using the changeset viewer.