Changes in src/ResolvExpr/Unify.cc [d286cf68:982f95d]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
rd286cf68 r982f95d 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:27:10 2015 11 // Last Modified By : Aaron B. Moss12 // Last Modified On : Mon Jun 18 11:58:00 201813 // Update Count : 4 311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 16 16:22:54 2017 13 // Update Count : 42 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_ptr20 19 #include <set> // for set 21 20 #include <string> // for string, operator==, operator!=, bas... … … 32 31 #include "SynTree/Visitor.h" // for Visitor 33 32 #include "Tuples/Tuples.h" // for isTtype 34 #include "TypeEnvironment.h" // for EqvClass, AssertionSet, OpenVarSet33 #include "TypeEnvironment.h" // for ClassRef, AssertionSet, OpenVarSet 35 34 #include "Unify.h" 36 35 #include "typeops.h" // for flatten, occurs, commonType … … 99 98 findOpenVars( newSecond, openVars, closedVars, needAssertions, haveAssertions, true ); 100 99 101 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 102 delete newFirst; 103 delete newSecond; 104 return result; 100 return unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 105 101 } 106 102 … … 123 119 /// newSecond->print( std::cerr ); 124 120 /// std::cerr << std::endl; 125 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 126 delete newFirst; 127 delete newSecond; 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 128 252 return result; 129 253 } … … 134 258 findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true ); 135 259 Type *commonType = 0; 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 260 return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ); 144 261 } 145 262 … … 173 290 174 291 if ( isopen1 && isopen2 && entry1->second == entry2->second ) { 175 result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );292 result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 176 293 } else if ( isopen1 ) { 177 result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );294 result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 178 295 } else if ( isopen2 ) { // TODO: swap widenMode values in call, since type positions are flipped? 179 result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widenMode, indexer );296 result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 180 297 } else { 181 298 PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); … … 335 452 336 453 template< typename Iterator, typename Func > 337 std::unique_ptr<Type>combineTypes( Iterator begin, Iterator end, Func & toType ) {454 Type* combineTypes( Iterator begin, Iterator end, Func & toType ) { 338 455 std::list< Type * > types; 339 456 for ( ; begin != end; ++begin ) { … … 341 458 flatten( toType( *begin ), back_inserter( types ) ); 342 459 } 343 return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );460 return new TupleType{ Type::Qualifiers(), types }; 344 461 } 345 462 … … 356 473 if ( isTtype1 && ! isTtype2 ) { 357 474 // combine all of the things in list2, then unify 358 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) .get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );475 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 359 476 } else if ( isTtype2 && ! isTtype1 ) { 360 477 // combine all of the things in list1, then unify 361 return unifyExact( combineTypes( list1Begin, list1End, get_type ) .get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );478 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 362 479 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 363 480 return false; … … 369 486 Type * t1 = (*list1Begin)->get_type(); 370 487 if ( Tuples::isTtype( t1 ) ) { 371 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) .get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );488 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 372 489 } else return false; 373 490 } else if ( list2Begin != list2End ) { … … 375 492 Type * t2 = (*list2Begin)->get_type(); 376 493 if ( Tuples::isTtype( t2 ) ) { 377 return unifyExact( combineTypes( list1Begin, list1End, get_type ) .get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );494 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 378 495 } else return false; 379 496 } else { … … 391 508 void premutate( TypeInstType * ) { visit_children = false; } 392 509 Type * postmutate( TypeInstType * typeInst ) { 393 if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) {510 if ( ClassRef eqvClass = tenv.lookup( typeInst->get_name() ) ) { 394 511 // expand ttype parameter into its actual type 395 if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) {396 delete typeInst;397 return eqvClass->type->clone();512 BoundType cBound = eqvClass.get_bound(); 513 if ( cBound.data.kind == TypeDecl::Ttype && cBound.type ) { 514 return cBound.type->clone(); 398 515 } 399 516 } … … 418 535 dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) ); 419 536 } 420 delete dcl;421 537 } 422 538 } … … 427 543 // flatten the parameter lists for both functions so that tuple structure 428 544 // doesn't affect unification. Must be a clone so that the types don't change. 429 std::unique_ptr<FunctionType> flatFunc( functionType->clone());430 std::unique_ptr<FunctionType> flatOther( otherFunction->clone());545 FunctionType* flatFunc = functionType->clone(); 546 FunctionType* flatOther = otherFunction->clone(); 431 547 flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env ); 432 548 flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env ); … … 569 685 if ( isTtype1 && ! isTtype2 ) { 570 686 // combine all of the things in list2, then unify 571 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) .get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );687 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 572 688 } else if ( isTtype2 && ! isTtype1 ) { 573 689 // combine all of the things in list1, then unify 574 return unifyExact( combineTypes( list1Begin, list1End, get_type ) .get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );690 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 575 691 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 576 692 return false; … … 582 698 Type * t1 = *list1Begin; 583 699 if ( Tuples::isTtype( t1 ) ) { 584 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) .get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );700 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 585 701 } else return false; 586 702 } else if ( list2Begin != list2End ) { … … 588 704 Type * t2 = *list2Begin; 589 705 if ( Tuples::isTtype( t2 ) ) { 590 return unifyExact( combineTypes( list1Begin, list1End, get_type ) .get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );706 return unifyExact( combineTypes( list1Begin, list1End, get_type ), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 591 707 } else return false; 592 708 } else { … … 597 713 void Unify::postvisit(TupleType *tupleType) { 598 714 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 599 std::unique_ptr<TupleType> flat1( tupleType->clone());600 std::unique_ptr<TupleType> flat2( otherTuple->clone());715 TupleType* flat1 = tupleType->clone(); 716 TupleType* flat2 = otherTuple->clone(); 601 717 std::list<Type *> types1, types2; 602 718 … … 605 721 flat2->acceptMutator( expander ); 606 722 607 flatten( flat1 .get(), back_inserter( types1 ) );608 flatten( flat2 .get(), back_inserter( types2 ) );723 flatten( flat1, back_inserter( types1 ) ); 724 flatten( flat2, back_inserter( types2 ) ); 609 725 610 726 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.