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