|
25 | 25 | #include "llvm/Support/Compiler.h" |
26 | 26 | #include "llvm/Support/ErrorHandling.h" |
27 | 27 | #include "llvm/Support/MathExtras.h" |
| 28 | +#include "llvm/Support/Regex.h" |
28 | 29 | #include "llvm/Support/SMLoc.h" |
29 | 30 | #include "llvm/Support/raw_ostream.h" |
30 | 31 | #include "llvm/TableGen/Error.h" |
@@ -83,6 +84,7 @@ struct RecordKeeperImpl { |
83 | 84 | FoldingSet<FoldOpInit> TheFoldOpInitPool; |
84 | 85 | FoldingSet<IsAOpInit> TheIsAOpInitPool; |
85 | 86 | FoldingSet<ExistsOpInit> TheExistsOpInitPool; |
| 87 | + FoldingSet<DefinedOpInit> TheDefinedOpInitPool; |
86 | 88 | DenseMap<std::pair<const RecTy *, const Init *>, VarInit *> TheVarInitPool; |
87 | 89 | DenseMap<std::pair<const TypedInit *, unsigned>, VarBitInit *> |
88 | 90 | TheVarBitInitPool; |
@@ -2199,6 +2201,65 @@ std::string ExistsOpInit::getAsString() const { |
2199 | 2201 | .str(); |
2200 | 2202 | } |
2201 | 2203 |
|
| 2204 | +static void ProfileDefinedOpInit(FoldingSetNodeID &ID, const RecTy *Type, |
| 2205 | + const Init *Regex) { |
| 2206 | + ID.AddPointer(Type); |
| 2207 | + ID.AddPointer(Regex); |
| 2208 | +} |
| 2209 | + |
| 2210 | +const DefinedOpInit *DefinedOpInit::get(const RecTy *Type, const Init *Regex) { |
| 2211 | + FoldingSetNodeID ID; |
| 2212 | + ProfileDefinedOpInit(ID, Type, Regex); |
| 2213 | + |
| 2214 | + detail::RecordKeeperImpl &RK = Regex->getRecordKeeper().getImpl(); |
| 2215 | + void *IP = nullptr; |
| 2216 | + if (const DefinedOpInit *I = |
| 2217 | + RK.TheDefinedOpInitPool.FindNodeOrInsertPos(ID, IP)) |
| 2218 | + return I; |
| 2219 | + |
| 2220 | + DefinedOpInit *I = new (RK.Allocator) DefinedOpInit(Type, Regex); |
| 2221 | + RK.TheDefinedOpInitPool.InsertNode(I, IP); |
| 2222 | + return I; |
| 2223 | +} |
| 2224 | + |
| 2225 | +void DefinedOpInit::Profile(FoldingSetNodeID &ID) const { |
| 2226 | + ProfileDefinedOpInit(ID, Type, Regex); |
| 2227 | +} |
| 2228 | + |
| 2229 | +const Init *DefinedOpInit::Fold() const { |
| 2230 | + const auto *RegexInit = dyn_cast<StringInit>(Regex); |
| 2231 | + if (!RegexInit) |
| 2232 | + return this; |
| 2233 | + |
| 2234 | + StringRef RegexStr = RegexInit->getValue(); |
| 2235 | + llvm::Regex Matcher(RegexStr); |
| 2236 | + if (!Matcher.isValid()) |
| 2237 | + PrintFatalError(Twine("invalid regex '") + RegexStr + Twine("'")); |
| 2238 | + |
| 2239 | + const RecordKeeper &RK = Type->getRecordKeeper(); |
| 2240 | + SmallVector<Init *, 8> Selected; |
| 2241 | + for (auto &Def : RK.getAllDerivedDefinitionsIfDefined(Type->getAsString())) |
| 2242 | + if (Matcher.match(Def->getName())) |
| 2243 | + Selected.push_back(Def->getDefInit()); |
| 2244 | + |
| 2245 | + return ListInit::get(Selected, Type); |
| 2246 | +} |
| 2247 | + |
| 2248 | +const Init *DefinedOpInit::resolveReferences(Resolver &R) const { |
| 2249 | + const Init *NewRegex = Regex->resolveReferences(R); |
| 2250 | + if (Regex != NewRegex) |
| 2251 | + return get(Type, NewRegex)->Fold(); |
| 2252 | + return this; |
| 2253 | +} |
| 2254 | + |
| 2255 | +const Init *DefinedOpInit::getBit(unsigned Bit) const { |
| 2256 | + return VarBitInit::get(this, Bit); |
| 2257 | +} |
| 2258 | + |
| 2259 | +std::string DefinedOpInit::getAsString() const { |
| 2260 | + return "!defined<" + Type->getAsString() + ">(" + Regex->getAsString() + ")"; |
| 2261 | +} |
| 2262 | + |
2202 | 2263 | const RecTy *TypedInit::getFieldType(const StringInit *FieldName) const { |
2203 | 2264 | if (const auto *RecordType = dyn_cast<RecordRecTy>(getType())) { |
2204 | 2265 | for (const Record *Rec : RecordType->getClasses()) { |
|
0 commit comments