Changes in src/ResolvExpr/Unify.cc [00ac42e:0873d22e]
- File:
-
- 1 edited
-
src/ResolvExpr/Unify.cc (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Unify.cc
r00ac42e r0873d22e 20 20 #include <set> // for set 21 21 #include <string> // for string, operator==, operator!=, bas... 22 #include <utility> // for pair , move22 #include <utility> // for pair 23 23 24 24 #include "Common/PassVisitor.h" // for PassVisitor … … 166 166 return false; 167 167 } // if 168 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) { 169 if ( curClass->type ) { 168 EqvClass curClass; 169 if ( env.lookup( typeInst->get_name(), curClass ) ) { 170 if ( curClass.type ) { 170 171 Type *common = 0; 171 172 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to 172 std::unique_ptr< Type > newType( curClass ->type->clone() );173 std::unique_ptr< Type > newType( curClass.type->clone() ); 173 174 newType->get_qualifiers() = typeInst->get_qualifiers(); 174 if ( unifyInexact( newType.get(), 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 ) ) { 175 176 if ( common ) { 176 177 common->get_qualifiers() = Type::Qualifiers(); 177 env.add( EqvClass{ *curClass, common } ); 178 delete curClass.type; 179 curClass.type = common; 180 env.add( curClass ); 178 181 } // if 179 182 return true; … … 182 185 } // if 183 186 } else { 184 EqvClass newClass { *curClass, other };185 newClass.type->get_qualifiers() = Type::Qualifiers();186 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;187 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 ); 188 191 } // if 189 192 } else { … … 201 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 ) { 202 205 bool result = true; 203 const EqvClass *class1 = env.lookup( var1->get_name() );204 const EqvClass *class2 = env.lookup( var2->get_name() );206 EqvClass class1, class2; 207 bool hasClass1 = false, hasClass2 = false; 205 208 bool widen1 = false, widen2 = false; 206 Type *type1 = nullptr, *type2 = nullptr; 207 208 if ( class1 ) { 209 if ( class1->type ) { 210 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 ) ) { 211 215 return false; 212 216 } // if 213 type1 = class1->type->clone(); 214 } // if 215 widen1 = widenMode.widenFirst && class1->allowWidening; 216 } // if 217 if ( class2 ) { 218 if ( class2->type ) { 219 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 ) ) { 220 225 return false; 221 226 } // if 222 type2 = class2 ->type->clone();223 } // if 224 widen2 = widenMode.widenSecond && class2 ->allowWidening;227 type2 = class2.type->clone(); 228 } // if 229 widen2 = widenMode.widenSecond && class2.allowWidening; 225 230 } // if 226 231 … … 230 235 Type *common = 0; 231 236 if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) { 232 EqvClass newClass1 = *class1; 233 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 234 newClass1.allowWidening = widen1 && widen2; 237 class1.vars.insert( class2.vars.begin(), class2.vars.end() ); 238 class1.allowWidening = widen1 && widen2; 235 239 if ( common ) { 236 240 common->get_qualifiers() = Type::Qualifiers(); 237 delete newClass1.type;238 newClass1.type = common;241 delete class1.type; 242 class1.type = common; 239 243 } // if 240 env.add( std::move(newClass1));244 env.add( class1 ); 241 245 } else { 242 246 result = false; 243 247 } // if 244 } else if ( class1 && class2 ) {248 } else if ( hasClass1 && hasClass2 ) { 245 249 if ( type1 ) { 246 EqvClass newClass1 = *class1; 247 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() ); 248 newClass1.allowWidening = widen1; 249 env.add( std::move(newClass1) ); 250 class1.vars.insert( class2.vars.begin(), class2.vars.end() ); 251 class1.allowWidening = widen1; 252 env.add( class1 ); 250 253 } else { 251 EqvClass newClass2 = *class2; 252 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() ); 253 newClass2.allowWidening = widen2; 254 env.add( std::move(newClass2) ); 255 } // if 256 } else if ( class1 ) { 257 EqvClass newClass1 = *class1; 258 newClass1.vars.insert( var2->get_name() ); 259 newClass1.allowWidening = widen1; 260 env.add( std::move(newClass1) ); 261 } else if ( class2 ) { 262 EqvClass newClass2 = *class2; 263 newClass2.vars.insert( var1->get_name() ); 264 newClass2.allowWidening = widen2; 265 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 ); 266 266 } else { 267 267 EqvClass newClass; … … 539 539 void premutate( TypeInstType * ) { visit_children = false; } 540 540 Type * postmutate( TypeInstType * typeInst ) { 541 if ( const EqvClass *eqvClass = tenv.lookup( typeInst->get_name() ) ) { 542 // expand ttype parameter into its actual type 543 if ( eqvClass->data.kind == TypeDecl::Ttype && eqvClass->type ) { 544 delete typeInst; 545 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 } 546 549 } 547 550 }
Note:
See TracChangeset
for help on using the changeset viewer.