Changes in src/ResolvExpr/Unify.cc [8e18b8e:0873d22e]
- File:
-
- 1 edited
-
src/ResolvExpr/Unify.cc (modified) (22 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r8e18b8e r0873d22e 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... 21 #include <utility> // for pair , move22 #include <utility> // for pair 22 23 23 24 #include "Common/PassVisitor.h" // for PassVisitor … … 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 ); 125 bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 126 delete newFirst; 127 delete newSecond; 128 return result; 122 129 } 123 130 … … 159 166 return false; 160 167 } // if 161 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) { 162 if ( curClass->type ) { 168 EqvClass curClass; 169 if ( env.lookup( typeInst->get_name(), curClass ) ) { 170 if ( curClass.type ) { 163 171 Type *common = 0; 164 172 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to 165 Type* newType = curClass->type->clone();173 std::unique_ptr< Type > newType( curClass.type->clone() ); 166 174 newType->get_qualifiers() = typeInst->get_qualifiers(); 167 if ( unifyInexact( newType , other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {175 if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) { 168 176 if ( common ) { 169 177 common->get_qualifiers() = Type::Qualifiers(); 170 EqvClass newClass = *curClass;171 newClass.type = common;172 env.add( std::move(newClass));178 delete curClass.type; 179 curClass.type = common; 180 env.add( curClass ); 173 181 } // if 174 182 return true; … … 177 185 } // if 178 186 } else { 179 EqvClass newClass = *curClass; 180 newClass.type = other->clone(); 181 newClass.type->get_qualifiers() = Type::Qualifiers(); 182 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond; 183 env.add( std::move(newClass) ); 187 curClass.type = other->clone(); 188 curClass.type->get_qualifiers() = Type::Qualifiers(); 189 curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond; 190 env.add( curClass ); 184 191 } // if 185 192 } else { … … 197 204 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 ) { 198 205 bool result = true; 199 const EqvClass *class1 = env.lookup( var1->get_name() );200 const EqvClass *class2 = env.lookup( var2->get_name() );206 EqvClass class1, class2; 207 bool hasClass1 = false, hasClass2 = false; 201 208 bool widen1 = false, widen2 = false; 202 Type *type1 = nullptr, *type2 = nullptr; 203 204 if ( class1 ) { 205 if ( class1->type ) { 206 if ( occurs( class1->type, var2->get_name(), env ) ) { 209 Type *type1 = 0, *type2 = 0; 210 211 if ( env.lookup( var1->get_name(), class1 ) ) { 212 hasClass1 = true; 213 if ( class1.type ) { 214 if ( occurs( class1.type, var2->get_name(), env ) ) { 207 215 return false; 208 216 } // if 209 type1 = class1->type->clone(); 210 } // if 211 widen1 = widenMode.widenFirst && class1->allowWidening; 212 } // if 213 if ( class2 ) { 214 if ( class2->type ) { 215 if ( occurs( class2->type, var1->get_name(), env ) ) { 217 type1 = class1.type->clone(); 218 } // if 219 widen1 = widenMode.widenFirst && class1.allowWidening; 220 } // if 221 if ( env.lookup( var2->get_name(), class2 ) ) { 222 hasClass2 = true; 223 if ( class2.type ) { 224 if ( occurs( class2.type, var1->get_name(), env ) ) { 216 225 return false; 217 226 } // if 218 type2 = class2 ->type->clone();219 } // if 220 widen2 = widenMode.widenSecond && class2 ->allowWidening;227 type2 = class2.type->clone(); 228 } // if 229 widen2 = widenMode.widenSecond && class2.allowWidening; 221 230 } // if 222 231 … … 226 235 Type *common = 0; 227 236 if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) { 228 EqvClass newClass1 = *class1; 229 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 230 newClass1.allowWidening = widen1 && widen2; 237 class1.vars.insert( class2.vars.begin(), class2.vars.end() ); 238 class1.allowWidening = widen1 && widen2; 231 239 if ( common ) { 232 240 common->get_qualifiers() = Type::Qualifiers(); 233 newClass1.type = common; 241 delete class1.type; 242 class1.type = common; 234 243 } // if 235 env.add( std::move(newClass1));244 env.add( class1 ); 236 245 } else { 237 246 result = false; 238 247 } // if 239 } else if ( class1 && class2 ) {248 } else if ( hasClass1 && hasClass2 ) { 240 249 if ( type1 ) { 241 EqvClass newClass1 = *class1; 242 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 243 newClass1.allowWidening = widen1; 244 env.add( std::move(newClass1) ); 250 class1.vars.insert( class2.vars.begin(), class2.vars.end() ); 251 class1.allowWidening = widen1; 252 env.add( class1 ); 245 253 } else { 246 EqvClass newClass2 = *class2; 247 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() ); 248 newClass2.allowWidening = widen2; 249 env.add( std::move(newClass2) ); 250 } // if 251 } else if ( class1 ) { 252 EqvClass newClass1 = *class1; 253 newClass1.vars.insert( var2->get_name() ); 254 newClass1.allowWidening = widen1; 255 env.add( std::move(newClass1) ); 256 } else if ( class2 ) { 257 EqvClass newClass2 = *class2; 258 newClass2.vars.insert( var1->get_name() ); 259 newClass2.allowWidening = widen2; 260 env.add( std::move(newClass2) ); 254 class2.vars.insert( class1.vars.begin(), class1.vars.end() ); 255 class2.allowWidening = widen2; 256 env.add( class2 ); 257 } // if 258 } else if ( hasClass1 ) { 259 class1.vars.insert( var2->get_name() ); 260 class1.allowWidening = widen1; 261 env.add( class1 ); 262 } else if ( hasClass2 ) { 263 class2.vars.insert( var1->get_name() ); 264 class2.allowWidening = widen2; 265 env.add( class2 ); 261 266 } else { 262 267 EqvClass newClass; … … 267 272 env.add( newClass ); 268 273 } // if 274 delete type1; 275 delete type2; 269 276 return result; 270 277 } … … 275 282 findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true ); 276 283 Type *commonType = 0; 277 return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ); 284 if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) { 285 if ( commonType ) { 286 delete commonType; 287 } // if 288 return true; 289 } else { 290 return false; 291 } // if 278 292 } 279 293 … … 469 483 470 484 template< typename Iterator, typename Func > 471 Type*combineTypes( Iterator begin, Iterator end, Func & toType ) {485 std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) { 472 486 std::list< Type * > types; 473 487 for ( ; begin != end; ++begin ) { … … 475 489 flatten( toType( *begin ), back_inserter( types ) ); 476 490 } 477 return new TupleType{ Type::Qualifiers(), types };491 return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) ); 478 492 } 479 493 … … 490 504 if ( isTtype1 && ! isTtype2 ) { 491 505 // combine all of the things in list2, then unify 492 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );506 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 493 507 } else if ( isTtype2 && ! isTtype1 ) { 494 508 // combine all of the things in list1, then unify 495 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );509 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 496 510 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 497 511 return false; … … 503 517 Type * t1 = (*list1Begin)->get_type(); 504 518 if ( Tuples::isTtype( t1 ) ) { 505 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );519 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 506 520 } else return false; 507 521 } else if ( list2Begin != list2End ) { … … 509 523 Type * t2 = (*list2Begin)->get_type(); 510 524 if ( Tuples::isTtype( t2 ) ) { 511 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );525 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 512 526 } else return false; 513 527 } else { … … 525 539 void premutate( TypeInstType * ) { visit_children = false; } 526 540 Type * postmutate( TypeInstType * typeInst ) { 527 if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) { 528 // expand ttype parameter into its actual type 529 if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) { 530 return eqvClass->type->clone(); 541 EqvClass eqvClass; 542 if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) { 543 if ( eqvClass.data.kind == TypeDecl::Ttype ) { 544 // expand ttype parameter into its actual type 545 if ( eqvClass.type ) { 546 delete typeInst; 547 return eqvClass.type->clone(); 548 } 531 549 } 532 550 } … … 551 569 dst.push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::C, nullptr, t, nullptr ) ); 552 570 } 571 delete dcl; 553 572 } 554 573 } … … 559 578 // flatten the parameter lists for both functions so that tuple structure 560 579 // doesn't affect unification. Must be a clone so that the types don't change. 561 FunctionType* flatFunc = functionType->clone();562 FunctionType* flatOther = otherFunction->clone();580 std::unique_ptr<FunctionType> flatFunc( functionType->clone() ); 581 std::unique_ptr<FunctionType> flatOther( otherFunction->clone() ); 563 582 flattenList( flatFunc->get_parameters(), flatFunc->get_parameters(), env ); 564 583 flattenList( flatOther->get_parameters(), flatOther->get_parameters(), env ); … … 701 720 if ( isTtype1 && ! isTtype2 ) { 702 721 // combine all of the things in list2, then unify 703 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );722 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 704 723 } else if ( isTtype2 && ! isTtype1 ) { 705 724 // combine all of the things in list1, then unify 706 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );725 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 707 726 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 708 727 return false; … … 714 733 Type * t1 = *list1Begin; 715 734 if ( Tuples::isTtype( t1 ) ) { 716 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ) , env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );735 return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 717 736 } else return false; 718 737 } else if ( list2Begin != list2End ) { … … 720 739 Type * t2 = *list2Begin; 721 740 if ( Tuples::isTtype( t2 ) ) { 722 return unifyExact( combineTypes( list1Begin, list1End, get_type ) , t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );741 return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); 723 742 } else return false; 724 743 } else { … … 729 748 void Unify::postvisit(TupleType *tupleType) { 730 749 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 731 TupleType* flat1 = tupleType->clone();732 TupleType* flat2 = otherTuple->clone();750 std::unique_ptr<TupleType> flat1( tupleType->clone() ); 751 std::unique_ptr<TupleType> flat2( otherTuple->clone() ); 733 752 std::list<Type *> types1, types2; 734 753 … … 737 756 flat2->acceptMutator( expander ); 738 757 739 flatten( flat1 , back_inserter( types1 ) );740 flatten( flat2 , back_inserter( types2 ) );758 flatten( flat1.get(), back_inserter( types1 ) ); 759 flatten( flat2.get(), back_inserter( types2 ) ); 741 760 742 761 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.