const RecVec *SetTheory::expand(Record *Set) { // Check existing entries for Set and return early. ExpandMap::iterator I = Expansions.find(Set); if (I != Expansions.end()) return &I->second; // This is the first time we see Set. Find a suitable expander. try { const std::vector<Record*> &SC = Set->getSuperClasses(); for (unsigned i = 0, e = SC.size(); i != e; ++i) { // Skip unnamed superclasses. if (!dynamic_cast<const StringInit *>(SC[i]->getNameInit())) continue; if (Expander *Exp = Expanders.lookup(SC[i]->getName())) { // This breaks recursive definitions. RecVec &EltVec = Expansions[Set]; RecSet Elts; Exp->expand(*this, Set, Elts); EltVec.assign(Elts.begin(), Elts.end()); return &EltVec; } } } catch (const std::string &Error) { throw TGError(Set->getLoc(), Error); } // Set is not expandable. return 0; }
const RecVec *SetTheory::expand(Record *Set) { // Check existing entries for Set and return early. ExpandMap::iterator I = Expansions.find(Set); if (I != Expansions.end()) return &I->second; // This is the first time we see Set. Find a suitable expander. const std::vector<Record*> &SC = Set->getSuperClasses(); for (unsigned i = 0, e = SC.size(); i != e; ++i) { // Skip unnamed superclasses. if (!dyn_cast<StringInit>(SC[i]->getNameInit())) continue; auto I = Expanders.find(SC[i]->getName()); if (I != Expanders.end()) { // This breaks recursive definitions. RecVec &EltVec = Expansions[Set]; RecSet Elts; I->second->expand(*this, Set, Elts); EltVec.assign(Elts.begin(), Elts.end()); return &EltVec; } } // Set is not expandable. return nullptr; }
void SetTheory::evaluate(Init *Expr, RecSet &Elts) { // A def in a list can be a just an element, or it may expand. if (DefInit *Def = dynamic_cast<DefInit*>(Expr)) { if (const RecVec *Result = expand(Def->getDef())) return Elts.insert(Result->begin(), Result->end()); Elts.insert(Def->getDef()); return; } // Lists simply expand. if (ListInit *LI = dynamic_cast<ListInit*>(Expr)) return evaluate(LI->begin(), LI->end(), Elts); // Anything else must be a DAG. DagInit *DagExpr = dynamic_cast<DagInit*>(Expr); if (!DagExpr) throw "Invalid set element: " + Expr->getAsString(); DefInit *OpInit = dynamic_cast<DefInit*>(DagExpr->getOperator()); if (!OpInit) throw "Bad set expression: " + Expr->getAsString(); Operator *Op = Operators.lookup(OpInit->getDef()->getName()); if (!Op) throw "Unknown set operator: " + Expr->getAsString(); Op->apply(*this, DagExpr, Elts); }
void SetTheory::evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc) { // A def in a list can be a just an element, or it may expand. if (DefInit *Def = dyn_cast<DefInit>(Expr)) { if (const RecVec *Result = expand(Def->getDef())) return Elts.insert(Result->begin(), Result->end()); Elts.insert(Def->getDef()); return; } // Lists simply expand. if (ListInit *LI = dyn_cast<ListInit>(Expr)) return evaluate(LI->begin(), LI->end(), Elts, Loc); // Anything else must be a DAG. DagInit *DagExpr = dyn_cast<DagInit>(Expr); if (!DagExpr) PrintFatalError(Loc, "Invalid set element: " + Expr->getAsString()); DefInit *OpInit = dyn_cast<DefInit>(DagExpr->getOperator()); if (!OpInit) PrintFatalError(Loc, "Bad set expression: " + Expr->getAsString()); auto I = Operators.find(OpInit->getDef()->getName()); if (I == Operators.end()) PrintFatalError(Loc, "Unknown set operator: " + Expr->getAsString()); I->second->apply(*this, DagExpr, Elts, Loc); }