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