Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/TableGen/TGParser.h
35234 views
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
329