void Constraints::substIntoEquates(ConstraintMap& in) { // Substitute the fixed types into the equates. This may generate more // fixed types ConstraintMap extra; ConstraintMap cur = in; while (cur.size()) { extra.clear(); ConstraintMap::iterator kk; for (kk = cur.begin(); kk != cur.end(); kk++) { Exp* lhs = kk->first; std::map<Exp*, LocationSet, lessExpStar>::iterator it = equates.find(lhs); if (it != equates.end()) { // Possibly new constraints that // typeof(elements in it->second) == val Exp* val = kk->second; LocationSet& ls = it->second; LocationSet::iterator ll; for (ll = ls.begin(); ll != ls.end(); ll++) { ConstraintMap::iterator ff; ff = fixed.find(*ll); if (ff != fixed.end()) { if (!unify(val, ff->second, extra)) { if (VERBOSE || DEBUG_TA) LOG << "Constraint failure: " << *ll << " constrained to be " << ((TypeVal*)val)->getType()->getCtype() << " and " << ((TypeVal*)ff->second)->getType()->getCtype() << "\n"; return; } } else extra[*ll] = val; // A new constant constraint } if (((TypeVal*)val)->getType()->isComplete()) { // We have a complete type equal to one or more variables // Remove the equate, and generate more fixed // e.g. Ta = Tb,Tc and Ta = K => Tb=K, Tc=K for (ll = ls.begin(); ll != ls.end(); ll++) { Exp* newFixed = new Binary(opEquals, *ll, // e.g. Tb val); // e.g. K extra.insert(newFixed); } equates.erase(it); } } } fixed.makeUnion(extra); cur = extra; // Take care of any "ripple effect" } // Repeat until no ripples }