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