@@ -84,6 +84,7 @@ struct RecordKeeperImpl {
8484 FoldingSet<FoldOpInit> TheFoldOpInitPool;
8585 FoldingSet<IsAOpInit> TheIsAOpInitPool;
8686 FoldingSet<ExistsOpInit> TheExistsOpInitPool;
87+ FoldingSet<RecordsOpInit> TheRecordsOpInitPool;
8788 DenseMap<std::pair<const RecTy *, const Init *>, VarInit *> TheVarInitPool;
8889 DenseMap<std::pair<const TypedInit *, unsigned >, VarBitInit *>
8990 TheVarBitInitPool;
@@ -2222,6 +2223,65 @@ std::string ExistsOpInit::getAsString() const {
22222223 .str ();
22232224}
22242225
2226+ static void ProfileRecordsOpInit (FoldingSetNodeID &ID, const RecTy *Type,
2227+ const Init *Regex) {
2228+ ID.AddPointer (Type);
2229+ ID.AddPointer (Regex);
2230+ }
2231+
2232+ const RecordsOpInit *RecordsOpInit::get (const RecTy *Type, const Init *Regex) {
2233+ FoldingSetNodeID ID;
2234+ ProfileRecordsOpInit (ID, Type, Regex);
2235+
2236+ detail::RecordKeeperImpl &RK = Regex->getRecordKeeper ().getImpl ();
2237+ void *IP = nullptr ;
2238+ if (const RecordsOpInit *I =
2239+ RK.TheRecordsOpInitPool .FindNodeOrInsertPos (ID, IP))
2240+ return I;
2241+
2242+ RecordsOpInit *I = new (RK.Allocator ) RecordsOpInit (Type, Regex);
2243+ RK.TheRecordsOpInitPool .InsertNode (I, IP);
2244+ return I;
2245+ }
2246+
2247+ void RecordsOpInit::Profile (FoldingSetNodeID &ID) const {
2248+ ProfileRecordsOpInit (ID, Type, Regex);
2249+ }
2250+
2251+ const Init *RecordsOpInit::Fold () const {
2252+ const auto *RegexInit = dyn_cast<StringInit>(Regex);
2253+ if (!RegexInit)
2254+ return this ;
2255+
2256+ StringRef RegexStr = RegexInit->getValue ();
2257+ llvm::Regex Matcher (RegexStr);
2258+ if (!Matcher.isValid ())
2259+ PrintFatalError (Twine (" invalid regex '" ) + RegexStr + Twine (" '" ));
2260+
2261+ const RecordKeeper &RK = Type->getRecordKeeper ();
2262+ SmallVector<Init *, 8 > Selected;
2263+ for (auto &Def : RK.getAllDerivedDefinitionsIfDefined (Type->getAsString ()))
2264+ if (Matcher.match (Def->getName ()))
2265+ Selected.push_back (Def->getDefInit ());
2266+
2267+ return ListInit::get (Selected, Type);
2268+ }
2269+
2270+ const Init *RecordsOpInit::resolveReferences (Resolver &R) const {
2271+ const Init *NewRegex = Regex->resolveReferences (R);
2272+ if (Regex != NewRegex)
2273+ return get (Type, NewRegex)->Fold ();
2274+ return this ;
2275+ }
2276+
2277+ const Init *RecordsOpInit::getBit (unsigned Bit) const {
2278+ return VarBitInit::get (this , Bit);
2279+ }
2280+
2281+ std::string RecordsOpInit::getAsString () const {
2282+ return " !records<" + Type->getAsString () + " >(" + Regex->getAsString () + " )" ;
2283+ }
2284+
22252285const RecTy *TypedInit::getFieldType (const StringInit *FieldName) const {
22262286 if (const auto *RecordType = dyn_cast<RecordRecTy>(getType ())) {
22272287 for (const Record *Rec : RecordType->getClasses ()) {
0 commit comments