xref: /freebsd/contrib/llvm-project/llvm/lib/TableGen/TGParser.h (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1 //===- TGParser.h - Parser for TableGen Files -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class represents the Parser for tablegen files.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_LIB_TABLEGEN_TGPARSER_H
14 #define LLVM_LIB_TABLEGEN_TGPARSER_H
15 
16 #include "TGLexer.h"
17 #include "llvm/TableGen/Error.h"
18 #include "llvm/TableGen/Record.h"
19 #include <map>
20 
21 namespace llvm {
22 class SourceMgr;
23 class Twine;
24 struct ForeachLoop;
25 struct MultiClass;
26 struct SubClassReference;
27 struct SubMultiClassReference;
28 
29 struct LetRecord {
30   StringInit *Name;
31   std::vector<unsigned> Bits;
32   Init *Value;
33   SMLoc Loc;
34   LetRecord(StringInit *N, ArrayRef<unsigned> B, Init *V, SMLoc L)
35       : Name(N), Bits(B), Value(V), Loc(L) {}
36 };
37 
38 /// RecordsEntry - Holds exactly one of a Record, ForeachLoop, or
39 /// AssertionInfo.
40 struct RecordsEntry {
41   std::unique_ptr<Record> Rec;
42   std::unique_ptr<ForeachLoop> Loop;
43   std::unique_ptr<Record::AssertionInfo> Assertion;
44   std::unique_ptr<Record::DumpInfo> Dump;
45 
46   void dump() const;
47 
48   RecordsEntry() = default;
49   RecordsEntry(std::unique_ptr<Record> Rec) : Rec(std::move(Rec)) {}
50   RecordsEntry(std::unique_ptr<ForeachLoop> Loop) : Loop(std::move(Loop)) {}
51   RecordsEntry(std::unique_ptr<Record::AssertionInfo> Assertion)
52       : Assertion(std::move(Assertion)) {}
53   RecordsEntry(std::unique_ptr<Record::DumpInfo> Dump)
54       : Dump(std::move(Dump)) {}
55 };
56 
57 /// ForeachLoop - Record the iteration state associated with a for loop.
58 /// This is used to instantiate items in the loop body.
59 ///
60 /// IterVar is allowed to be null, in which case no iteration variable is
61 /// defined in the loop at all. (This happens when a ForeachLoop is
62 /// constructed by desugaring an if statement.)
63 struct ForeachLoop {
64   SMLoc Loc;
65   VarInit *IterVar;
66   Init *ListValue;
67   std::vector<RecordsEntry> Entries;
68 
69   void dump() const;
70 
71   ForeachLoop(SMLoc Loc, VarInit *IVar, Init *LValue)
72       : Loc(Loc), IterVar(IVar), ListValue(LValue) {}
73 };
74 
75 struct DefsetRecord {
76   SMLoc Loc;
77   RecTy *EltTy = nullptr;
78   SmallVector<Init *, 16> Elements;
79 };
80 
81 struct MultiClass {
82   Record Rec; // Placeholder for template args and Name.
83   std::vector<RecordsEntry> Entries;
84 
85   void dump() const;
86 
87   MultiClass(StringRef Name, SMLoc Loc, RecordKeeper &Records)
88       : Rec(Name, Loc, Records, Record::RK_MultiClass) {}
89 };
90 
91 class TGVarScope {
92 public:
93   enum ScopeKind { SK_Local, SK_Record, SK_ForeachLoop, SK_MultiClass };
94 
95 private:
96   ScopeKind Kind;
97   std::unique_ptr<TGVarScope> Parent;
98   // A scope to hold variable definitions from defvar.
99   std::map<std::string, Init *, std::less<>> Vars;
100   Record *CurRec = nullptr;
101   ForeachLoop *CurLoop = nullptr;
102   MultiClass *CurMultiClass = nullptr;
103 
104 public:
105   TGVarScope(std::unique_ptr<TGVarScope> Parent)
106       : Kind(SK_Local), Parent(std::move(Parent)) {}
107   TGVarScope(std::unique_ptr<TGVarScope> Parent, Record *Rec)
108       : Kind(SK_Record), Parent(std::move(Parent)), CurRec(Rec) {}
109   TGVarScope(std::unique_ptr<TGVarScope> Parent, ForeachLoop *Loop)
110       : Kind(SK_ForeachLoop), Parent(std::move(Parent)), CurLoop(Loop) {}
111   TGVarScope(std::unique_ptr<TGVarScope> Parent, MultiClass *Multiclass)
112       : Kind(SK_MultiClass), Parent(std::move(Parent)),
113         CurMultiClass(Multiclass) {}
114 
115   std::unique_ptr<TGVarScope> extractParent() {
116     // This is expected to be called just before we are destructed, so
117     // it doesn't much matter what state we leave 'parent' in.
118     return std::move(Parent);
119   }
120 
121   Init *getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass,
122                StringInit *Name, SMRange NameLoc,
123                bool TrackReferenceLocs) const;
124 
125   bool varAlreadyDefined(StringRef Name) const {
126     // When we check whether a variable is already defined, for the purpose of
127     // reporting an error on redefinition, we don't look up to the parent
128     // scope, because it's all right to shadow an outer definition with an
129     // inner one.
130     return Vars.find(Name) != Vars.end();
131   }
132 
133   void addVar(StringRef Name, Init *I) {
134     bool Ins = Vars.insert(std::make_pair(std::string(Name), I)).second;
135     (void)Ins;
136     assert(Ins && "Local variable already exists");
137   }
138 
139   bool isOutermost() const { return Parent == nullptr; }
140 };
141 
142 class TGParser {
143   TGLexer Lex;
144   std::vector<SmallVector<LetRecord, 4>> LetStack;
145   std::map<std::string, std::unique_ptr<MultiClass>> MultiClasses;
146   std::map<std::string, RecTy *> TypeAliases;
147 
148   /// Loops - Keep track of any foreach loops we are within.
149   ///
150   std::vector<std::unique_ptr<ForeachLoop>> Loops;
151 
152   SmallVector<DefsetRecord *, 2> Defsets;
153 
154   /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
155   /// current value.
156   MultiClass *CurMultiClass;
157 
158   /// CurScope - Innermost of the current nested scopes for 'defvar' variables.
159   std::unique_ptr<TGVarScope> CurScope;
160 
161   // Record tracker
162   RecordKeeper &Records;
163 
164   // A "named boolean" indicating how to parse identifiers.  Usually
165   // identifiers map to some existing object but in special cases
166   // (e.g. parsing def names) no such object exists yet because we are
167   // in the middle of creating in.  For those situations, allow the
168   // parser to ignore missing object errors.
169   enum IDParseMode {
170     ParseValueMode,   // We are parsing a value we expect to look up.
171     ParseNameMode,    // We are parsing a name of an object that does not yet
172                       // exist.
173   };
174 
175   bool NoWarnOnUnusedTemplateArgs = false;
176   bool TrackReferenceLocs = false;
177 
178 public:
179   TGParser(SourceMgr &SM, ArrayRef<std::string> Macros, RecordKeeper &records,
180            const bool NoWarnOnUnusedTemplateArgs = false,
181            const bool TrackReferenceLocs = false)
182       : Lex(SM, Macros), CurMultiClass(nullptr), Records(records),
183         NoWarnOnUnusedTemplateArgs(NoWarnOnUnusedTemplateArgs),
184         TrackReferenceLocs(TrackReferenceLocs) {}
185 
186   /// ParseFile - Main entrypoint for parsing a tblgen file.  These parser
187   /// routines return true on error, or false on success.
188   bool ParseFile();
189 
190   bool Error(SMLoc L, const Twine &Msg) const {
191     PrintError(L, Msg);
192     return true;
193   }
194   bool TokError(const Twine &Msg) const {
195     return Error(Lex.getLoc(), Msg);
196   }
197   const TGLexer::DependenciesSetTy &getDependencies() const {
198     return Lex.getDependencies();
199   }
200 
201   TGVarScope *PushScope() {
202     CurScope = std::make_unique<TGVarScope>(std::move(CurScope));
203     // Returns a pointer to the new scope, so that the caller can pass it back
204     // to PopScope which will check by assertion that the pushes and pops
205     // match up properly.
206     return CurScope.get();
207   }
208   TGVarScope *PushScope(Record *Rec) {
209     CurScope = std::make_unique<TGVarScope>(std::move(CurScope), Rec);
210     return CurScope.get();
211   }
212   TGVarScope *PushScope(ForeachLoop *Loop) {
213     CurScope = std::make_unique<TGVarScope>(std::move(CurScope), Loop);
214     return CurScope.get();
215   }
216   TGVarScope *PushScope(MultiClass *Multiclass) {
217     CurScope = std::make_unique<TGVarScope>(std::move(CurScope), Multiclass);
218     return CurScope.get();
219   }
220   void PopScope(TGVarScope *ExpectedStackTop) {
221     assert(ExpectedStackTop == CurScope.get() &&
222            "Mismatched pushes and pops of local variable scopes");
223     CurScope = CurScope->extractParent();
224   }
225 
226 private: // Semantic analysis methods.
227   bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV);
228   /// Set the value of a RecordVal within the given record. If `OverrideDefLoc`
229   /// is set, the provided location overrides any existing location of the
230   /// RecordVal.
231   bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName,
232                 ArrayRef<unsigned> BitList, Init *V,
233                 bool AllowSelfAssignment = false, bool OverrideDefLoc = true);
234   bool AddSubClass(Record *Rec, SubClassReference &SubClass);
235   bool AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass);
236   bool AddSubMultiClass(MultiClass *CurMC,
237                         SubMultiClassReference &SubMultiClass);
238 
239   using SubstStack = SmallVector<std::pair<Init *, Init *>, 8>;
240 
241   bool addEntry(RecordsEntry E);
242   bool resolve(const ForeachLoop &Loop, SubstStack &Stack, bool Final,
243                std::vector<RecordsEntry> *Dest, SMLoc *Loc = nullptr);
244   bool resolve(const std::vector<RecordsEntry> &Source, SubstStack &Substs,
245                bool Final, std::vector<RecordsEntry> *Dest,
246                SMLoc *Loc = nullptr);
247   bool addDefOne(std::unique_ptr<Record> Rec);
248 
249   using ArgValueHandler = std::function<void(Init *, Init *)>;
250   bool resolveArguments(
251       Record *Rec, ArrayRef<ArgumentInit *> ArgValues, SMLoc Loc,
252       ArgValueHandler ArgValueHandler = [](Init *, Init *) {});
253   bool resolveArgumentsOfClass(MapResolver &R, Record *Rec,
254                                ArrayRef<ArgumentInit *> ArgValues, SMLoc Loc);
255   bool resolveArgumentsOfMultiClass(SubstStack &Substs, MultiClass *MC,
256                                     ArrayRef<ArgumentInit *> ArgValues,
257                                     Init *DefmName, SMLoc Loc);
258 
259 private:  // Parser methods.
260   bool consume(tgtok::TokKind K);
261   bool ParseObjectList(MultiClass *MC = nullptr);
262   bool ParseObject(MultiClass *MC);
263   bool ParseClass();
264   bool ParseMultiClass();
265   bool ParseDefm(MultiClass *CurMultiClass);
266   bool ParseDef(MultiClass *CurMultiClass);
267   bool ParseDefset();
268   bool ParseDeftype();
269   bool ParseDefvar(Record *CurRec = nullptr);
270   bool ParseDump(MultiClass *CurMultiClass, Record *CurRec = nullptr);
271   bool ParseForeach(MultiClass *CurMultiClass);
272   bool ParseIf(MultiClass *CurMultiClass);
273   bool ParseIfBody(MultiClass *CurMultiClass, StringRef Kind);
274   bool ParseAssert(MultiClass *CurMultiClass, Record *CurRec = nullptr);
275   bool ParseTopLevelLet(MultiClass *CurMultiClass);
276   void ParseLetList(SmallVectorImpl<LetRecord> &Result);
277 
278   bool ParseObjectBody(Record *CurRec);
279   bool ParseBody(Record *CurRec);
280   bool ParseBodyItem(Record *CurRec);
281 
282   bool ParseTemplateArgList(Record *CurRec);
283   Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
284   VarInit *ParseForeachDeclaration(Init *&ForeachListValue);
285 
286   SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
287   SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
288 
289   Init *ParseIDValue(Record *CurRec, StringInit *Name, SMRange NameLoc,
290                      IDParseMode Mode = ParseValueMode);
291   Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = nullptr,
292                          IDParseMode Mode = ParseValueMode);
293   Init *ParseValue(Record *CurRec, RecTy *ItemType = nullptr,
294                    IDParseMode Mode = ParseValueMode);
295   void ParseValueList(SmallVectorImpl<llvm::Init*> &Result,
296                       Record *CurRec, RecTy *ItemType = nullptr);
297   bool ParseTemplateArgValueList(SmallVectorImpl<llvm::ArgumentInit *> &Result,
298                                  Record *CurRec, Record *ArgsRec);
299   void ParseDagArgList(
300       SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
301       Record *CurRec);
302   bool ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges);
303   bool ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges);
304   TypedInit *ParseSliceElement(Record *CurRec);
305   TypedInit *ParseSliceElements(Record *CurRec, bool Single = false);
306   void ParseRangeList(SmallVectorImpl<unsigned> &Result);
307   bool ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
308                        TypedInit *FirstItem = nullptr);
309   RecTy *ParseType();
310   Init *ParseOperation(Record *CurRec, RecTy *ItemType);
311   Init *ParseOperationSubstr(Record *CurRec, RecTy *ItemType);
312   Init *ParseOperationFind(Record *CurRec, RecTy *ItemType);
313   Init *ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType);
314   Init *ParseOperationCond(Record *CurRec, RecTy *ItemType);
315   RecTy *ParseOperatorType();
316   Init *ParseObjectName(MultiClass *CurMultiClass);
317   Record *ParseClassID();
318   MultiClass *ParseMultiClassID();
319   bool ApplyLetStack(Record *CurRec);
320   bool ApplyLetStack(RecordsEntry &Entry);
321   bool CheckTemplateArgValues(SmallVectorImpl<llvm::ArgumentInit *> &Values,
322                               SMLoc Loc, Record *ArgsRec);
323 };
324 
325 } // end namespace llvm
326 
327 #endif
328