Changes in src/ResolvExpr/Unify.cc [982f95d:d286cf68]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r982f95d rd286cf68 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 … … 17 17 #include <iterator> // for back_insert_iterator, back_inserter 18 18 #include <map> // for _Rb_tree_const_iterator, _Rb_tree_i... 19 #include <memory> // for unique_ptr 19 20 #include <set> // for set 20 21 #include <string> // for string, operator==, operator!=, bas... … … 31 32 #include "SynTree/Visitor.h" // for Visitor 32 33 #include "Tuples/Tuples.h" // for isTtype 33 #include "TypeEnvironment.h" // for ClassRef, AssertionSet, OpenVarSet34 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet 34 35 #include "Unify.h" 35 36 #include "typeops.h" // for flatten, occurs, commonType … … 98 99 findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true ); 99 100 100 return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 101 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 102 delete newFirst; 103 delete newSecond; 104 return result; 101 105 } 102 106 … … 119 123 /// newSecond->print( std::cerr ); 120 124 /// std::cerr << std::endl; 121 return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 122 } 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 } // if 130 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 types 135 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 } // if 141 if ( occurs( other, typeInst->get_name(), env ) ) { 142 return false; 143 } // if 144 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 to 148 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 } // if 157 return true; 158 } else { 159 return false; 160 } // if 161 } 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 } // if 168 } 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 } // if 177 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 } // if 192 type1 = class1->type->clone(); 193 } // if 194 widen1 = widenMode.widenFirst && class1->allowWidening; 195 } // if 196 if ( class2 ) { 197 if ( class2->type ) { 198 if ( occurs( class2->type, var1->get_name(), env ) ) { 199 return false; 200 } // if 201 type2 = class2->type->clone(); 202 } // if 203 widen2 = widenMode.widenSecond && class2->allowWidening; 204 } // if 205 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 } // if 218 env.add( std::move(newClass1) ); 219 } else { 220 result = false; 221 } // if 222 } 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 } // if 234 } 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 } // if 125 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 126 delete newFirst; 127 delete newSecond; 252 128 return result; 253 129 } … … 258 134 findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true ); 259 135 Type *commonType = 0; 260 return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ); 136 if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) { 137 if ( commonType ) { 138 delete commonType; 139 } // if 140 return true; 141 } else { 142 return false; 143 } // if 261 144 } 262 145 … … 290 173 291 174 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 292 result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );175 result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 293 176 } else if ( isopen1 ) { 294 result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );177 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 295 178 } 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 );179 result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widenMode, indexer ); 297 180 } else { 298 181 PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); … … 452 335 453 336 template< typename Iterator, typename Func > 454 Type*combineTypes( Iterator begin, Iterator end, Func & toType ) {337 std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) { 455 338 std::list< Type * > types; 456 339 for ( ; begin != end; ++begin ) { … … 458 341 flatten( toType( *begin ), back_inserter( types ) ); 459 342 } 460 return new TupleType{ Type::Qualifiers(), types };343 return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) ); 461 344 } 462 345 … … 473 356 if ( isTtype1 && ! isTtype2 ) { 474 357 // combine all of the things in list2, then unify 475 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );358 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 476 359 } else if ( isTtype2 && ! isTtype1 ) { 477 360 // combine all of the things in list1, then unify 478 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );361 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 479 362 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 480 363 return false; … … 486 369 Type * t1 = (*list1Begin)->get_type(); 487 370 if ( Tuples::isTtype( t1 ) ) { 488 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );371 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 489 372 } else return false; 490 373 } else if ( list2Begin != list2End ) { … … 492 375 Type * t2 = (*list2Begin)->get_type(); 493 376 if ( Tuples::isTtype( t2 ) ) { 494 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );377 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 495 378 } else return false; 496 379 } else { … … 508 391 void premutate( TypeInstType * ) { visit_children = false; } 509 392 Type * postmutate( TypeInstType * typeInst ) { 510 if ( ClassRefeqvClass = tenv.lookup( typeInst->get_name() ) ) {393 if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) { 511 394 // expand ttype parameter into its actual type 512 BoundType cBound = eqvClass.get_bound();513 if ( cBound.data.kind == TypeDecl::Ttype && cBound.type ) {514 return cBound.type->clone();395 if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) { 396 delete typeInst; 397 return eqvClass->type->clone(); 515 398 } 516 399 } … … 535 418 dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) ); 536 419 } 420 delete dcl; 537 421 } 538 422 } … … 543 427 // flatten the parameter lists for both functions so that tuple structure 544 428 // doesn't affect unification. Must be a clone so that the types don't change. 545 FunctionType* flatFunc = functionType->clone();546 FunctionType* flatOther = otherFunction->clone();429 std::unique_ptr<FunctionType> flatFunc( functionType->clone() ); 430 std::unique_ptr<FunctionType> flatOther( otherFunction->clone() ); 547 431 flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env ); 548 432 flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env ); … … 685 569 if ( isTtype1 && ! isTtype2 ) { 686 570 // combine all of the things in list2, then unify 687 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );571 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 688 572 } else if ( isTtype2 && ! isTtype1 ) { 689 573 // combine all of the things in list1, then unify 690 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );574 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 691 575 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 692 576 return false; … … 698 582 Type * t1 = *list1Begin; 699 583 if ( Tuples::isTtype( t1 ) ) { 700 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );584 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 701 585 } else return false; 702 586 } else if ( list2Begin != list2End ) { … … 704 588 Type * t2 = *list2Begin; 705 589 if ( Tuples::isTtype( t2 ) ) { 706 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );590 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 707 591 } else return false; 708 592 } else { … … 713 597 void Unify::postvisit(TupleType *tupleType) { 714 598 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 715 TupleType* flat1 = tupleType->clone();716 TupleType* flat2 = otherTuple->clone();599 std::unique_ptr<TupleType> flat1( tupleType->clone() ); 600 std::unique_ptr<TupleType> flat2( otherTuple->clone() ); 717 601 std::list<Type *> types1, types2; 718 602 … … 721 605 flat2->acceptMutator( expander ); 722 606 723 flatten( flat1 , back_inserter( types1 ) );724 flatten( flat2 , back_inserter( types2 ) );607 flatten( flat1.get(), back_inserter( types1 ) ); 608 flatten( flat2.get(), back_inserter( types2 ) ); 725 609 726 610 result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, indexer );
Note:
See TracChangeset
for help on using the changeset viewer.