xref: /freebsd/contrib/llvm-project/llvm/lib/TableGen/TGParser.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- TGParser.h - Parser for TableGen Files -------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This class represents the Parser for tablegen files.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TABLEGEN_TGPARSER_H
140b57cec5SDimitry Andric #define LLVM_LIB_TABLEGEN_TGPARSER_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "TGLexer.h"
170b57cec5SDimitry Andric #include "llvm/TableGen/Error.h"
180b57cec5SDimitry Andric #include "llvm/TableGen/Record.h"
190b57cec5SDimitry Andric #include <map>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace llvm {
225ffd83dbSDimitry Andric class SourceMgr;
235ffd83dbSDimitry Andric class Twine;
240b57cec5SDimitry Andric struct ForeachLoop;
250b57cec5SDimitry Andric struct MultiClass;
260b57cec5SDimitry Andric struct SubClassReference;
270b57cec5SDimitry Andric struct SubMultiClassReference;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric struct LetRecord {
300b57cec5SDimitry Andric   StringInit *Name;
310b57cec5SDimitry Andric   std::vector<unsigned> Bits;
320b57cec5SDimitry Andric   Init *Value;
330b57cec5SDimitry Andric   SMLoc Loc;
LetRecordLetRecord340b57cec5SDimitry Andric   LetRecord(StringInit *N, ArrayRef<unsigned> B, Init *V, SMLoc L)
3506c3fb27SDimitry Andric       : Name(N), Bits(B), Value(V), Loc(L) {}
360b57cec5SDimitry Andric };
370b57cec5SDimitry Andric 
38fe6060f1SDimitry Andric /// RecordsEntry - Holds exactly one of a Record, ForeachLoop, or
39fe6060f1SDimitry Andric /// AssertionInfo.
400b57cec5SDimitry Andric struct RecordsEntry {
410b57cec5SDimitry Andric   std::unique_ptr<Record> Rec;
420b57cec5SDimitry Andric   std::unique_ptr<ForeachLoop> Loop;
43fe6060f1SDimitry Andric   std::unique_ptr<Record::AssertionInfo> Assertion;
445f757f3fSDimitry Andric   std::unique_ptr<Record::DumpInfo> Dump;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   void dump() const;
470b57cec5SDimitry Andric 
4881ad6265SDimitry Andric   RecordsEntry() = default;
RecordsEntryRecordsEntry490b57cec5SDimitry Andric   RecordsEntry(std::unique_ptr<Record> Rec) : Rec(std::move(Rec)) {}
RecordsEntryRecordsEntry5006c3fb27SDimitry Andric   RecordsEntry(std::unique_ptr<ForeachLoop> Loop) : Loop(std::move(Loop)) {}
RecordsEntryRecordsEntry51fe6060f1SDimitry Andric   RecordsEntry(std::unique_ptr<Record::AssertionInfo> Assertion)
52fe6060f1SDimitry Andric       : Assertion(std::move(Assertion)) {}
RecordsEntryRecordsEntry535f757f3fSDimitry Andric   RecordsEntry(std::unique_ptr<Record::DumpInfo> Dump)
545f757f3fSDimitry Andric       : Dump(std::move(Dump)) {}
550b57cec5SDimitry Andric };
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric /// ForeachLoop - Record the iteration state associated with a for loop.
580b57cec5SDimitry Andric /// This is used to instantiate items in the loop body.
59480093f4SDimitry Andric ///
60480093f4SDimitry Andric /// IterVar is allowed to be null, in which case no iteration variable is
61480093f4SDimitry Andric /// defined in the loop at all. (This happens when a ForeachLoop is
62480093f4SDimitry Andric /// constructed by desugaring an if statement.)
630b57cec5SDimitry Andric struct ForeachLoop {
640b57cec5SDimitry Andric   SMLoc Loc;
650b57cec5SDimitry Andric   VarInit *IterVar;
660b57cec5SDimitry Andric   Init *ListValue;
670b57cec5SDimitry Andric   std::vector<RecordsEntry> Entries;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   void dump() const;
700b57cec5SDimitry Andric 
ForeachLoopForeachLoop710b57cec5SDimitry Andric   ForeachLoop(SMLoc Loc, VarInit *IVar, Init *LValue)
720b57cec5SDimitry Andric       : Loc(Loc), IterVar(IVar), ListValue(LValue) {}
730b57cec5SDimitry Andric };
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric struct DefsetRecord {
760b57cec5SDimitry Andric   SMLoc Loc;
77480093f4SDimitry Andric   RecTy *EltTy = nullptr;
780b57cec5SDimitry Andric   SmallVector<Init *, 16> Elements;
790b57cec5SDimitry Andric };
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric struct MultiClass {
820b57cec5SDimitry Andric   Record Rec; // Placeholder for template args and Name.
830b57cec5SDimitry Andric   std::vector<RecordsEntry> Entries;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   void dump() const;
860b57cec5SDimitry Andric 
MultiClassMultiClass8706c3fb27SDimitry Andric   MultiClass(StringRef Name, SMLoc Loc, RecordKeeper &Records)
885f757f3fSDimitry Andric       : Rec(Name, Loc, Records, Record::RK_MultiClass) {}
8906c3fb27SDimitry Andric };
9006c3fb27SDimitry Andric 
9106c3fb27SDimitry Andric class TGVarScope {
9206c3fb27SDimitry Andric public:
9306c3fb27SDimitry Andric   enum ScopeKind { SK_Local, SK_Record, SK_ForeachLoop, SK_MultiClass };
9406c3fb27SDimitry Andric 
9506c3fb27SDimitry Andric private:
9606c3fb27SDimitry Andric   ScopeKind Kind;
9706c3fb27SDimitry Andric   std::unique_ptr<TGVarScope> Parent;
9806c3fb27SDimitry Andric   // A scope to hold variable definitions from defvar.
9906c3fb27SDimitry Andric   std::map<std::string, Init *, std::less<>> Vars;
10006c3fb27SDimitry Andric   Record *CurRec = nullptr;
10106c3fb27SDimitry Andric   ForeachLoop *CurLoop = nullptr;
10206c3fb27SDimitry Andric   MultiClass *CurMultiClass = nullptr;
10306c3fb27SDimitry Andric 
10406c3fb27SDimitry Andric public:
TGVarScope(std::unique_ptr<TGVarScope> Parent)10506c3fb27SDimitry Andric   TGVarScope(std::unique_ptr<TGVarScope> Parent)
10606c3fb27SDimitry Andric       : Kind(SK_Local), Parent(std::move(Parent)) {}
TGVarScope(std::unique_ptr<TGVarScope> Parent,Record * Rec)10706c3fb27SDimitry Andric   TGVarScope(std::unique_ptr<TGVarScope> Parent, Record *Rec)
10806c3fb27SDimitry Andric       : Kind(SK_Record), Parent(std::move(Parent)), CurRec(Rec) {}
TGVarScope(std::unique_ptr<TGVarScope> Parent,ForeachLoop * Loop)10906c3fb27SDimitry Andric   TGVarScope(std::unique_ptr<TGVarScope> Parent, ForeachLoop *Loop)
11006c3fb27SDimitry Andric       : Kind(SK_ForeachLoop), Parent(std::move(Parent)), CurLoop(Loop) {}
TGVarScope(std::unique_ptr<TGVarScope> Parent,MultiClass * Multiclass)11106c3fb27SDimitry Andric   TGVarScope(std::unique_ptr<TGVarScope> Parent, MultiClass *Multiclass)
11206c3fb27SDimitry Andric       : Kind(SK_MultiClass), Parent(std::move(Parent)),
11306c3fb27SDimitry Andric         CurMultiClass(Multiclass) {}
11406c3fb27SDimitry Andric 
extractParent()11506c3fb27SDimitry Andric   std::unique_ptr<TGVarScope> extractParent() {
11606c3fb27SDimitry Andric     // This is expected to be called just before we are destructed, so
11706c3fb27SDimitry Andric     // it doesn't much matter what state we leave 'parent' in.
11806c3fb27SDimitry Andric     return std::move(Parent);
11906c3fb27SDimitry Andric   }
12006c3fb27SDimitry Andric 
12106c3fb27SDimitry Andric   Init *getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass,
12206c3fb27SDimitry Andric                StringInit *Name, SMRange NameLoc,
12306c3fb27SDimitry Andric                bool TrackReferenceLocs) const;
12406c3fb27SDimitry Andric 
varAlreadyDefined(StringRef Name)12506c3fb27SDimitry Andric   bool varAlreadyDefined(StringRef Name) const {
12606c3fb27SDimitry Andric     // When we check whether a variable is already defined, for the purpose of
12706c3fb27SDimitry Andric     // reporting an error on redefinition, we don't look up to the parent
12806c3fb27SDimitry Andric     // scope, because it's all right to shadow an outer definition with an
12906c3fb27SDimitry Andric     // inner one.
13006c3fb27SDimitry Andric     return Vars.find(Name) != Vars.end();
13106c3fb27SDimitry Andric   }
13206c3fb27SDimitry Andric 
addVar(StringRef Name,Init * I)13306c3fb27SDimitry Andric   void addVar(StringRef Name, Init *I) {
13406c3fb27SDimitry Andric     bool Ins = Vars.insert(std::make_pair(std::string(Name), I)).second;
13506c3fb27SDimitry Andric     (void)Ins;
13606c3fb27SDimitry Andric     assert(Ins && "Local variable already exists");
13706c3fb27SDimitry Andric   }
13806c3fb27SDimitry Andric 
isOutermost()13906c3fb27SDimitry Andric   bool isOutermost() const { return Parent == nullptr; }
1400b57cec5SDimitry Andric };
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric class TGParser {
1430b57cec5SDimitry Andric   TGLexer Lex;
1440b57cec5SDimitry Andric   std::vector<SmallVector<LetRecord, 4>> LetStack;
1450b57cec5SDimitry Andric   std::map<std::string, std::unique_ptr<MultiClass>> MultiClasses;
146*0fca6ea1SDimitry Andric   std::map<std::string, RecTy *> TypeAliases;
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   /// Loops - Keep track of any foreach loops we are within.
1490b57cec5SDimitry Andric   ///
1500b57cec5SDimitry Andric   std::vector<std::unique_ptr<ForeachLoop>> Loops;
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   SmallVector<DefsetRecord *, 2> Defsets;
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
1550b57cec5SDimitry Andric   /// current value.
1560b57cec5SDimitry Andric   MultiClass *CurMultiClass;
1570b57cec5SDimitry Andric 
15806c3fb27SDimitry Andric   /// CurScope - Innermost of the current nested scopes for 'defvar' variables.
15906c3fb27SDimitry Andric   std::unique_ptr<TGVarScope> CurScope;
160480093f4SDimitry Andric 
1610b57cec5SDimitry Andric   // Record tracker
1620b57cec5SDimitry Andric   RecordKeeper &Records;
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   // A "named boolean" indicating how to parse identifiers.  Usually
1650b57cec5SDimitry Andric   // identifiers map to some existing object but in special cases
1660b57cec5SDimitry Andric   // (e.g. parsing def names) no such object exists yet because we are
1670b57cec5SDimitry Andric   // in the middle of creating in.  For those situations, allow the
1680b57cec5SDimitry Andric   // parser to ignore missing object errors.
1690b57cec5SDimitry Andric   enum IDParseMode {
1700b57cec5SDimitry Andric     ParseValueMode,   // We are parsing a value we expect to look up.
1710b57cec5SDimitry Andric     ParseNameMode,    // We are parsing a name of an object that does not yet
1720b57cec5SDimitry Andric                       // exist.
1730b57cec5SDimitry Andric   };
1740b57cec5SDimitry Andric 
175349cc55cSDimitry Andric   bool NoWarnOnUnusedTemplateArgs = false;
176bdd1243dSDimitry Andric   bool TrackReferenceLocs = false;
177349cc55cSDimitry Andric 
1780b57cec5SDimitry Andric public:
179349cc55cSDimitry Andric   TGParser(SourceMgr &SM, ArrayRef<std::string> Macros, RecordKeeper &records,
180bdd1243dSDimitry Andric            const bool NoWarnOnUnusedTemplateArgs = false,
181bdd1243dSDimitry Andric            const bool TrackReferenceLocs = false)
Lex(SM,Macros)182349cc55cSDimitry Andric       : Lex(SM, Macros), CurMultiClass(nullptr), Records(records),
183bdd1243dSDimitry Andric         NoWarnOnUnusedTemplateArgs(NoWarnOnUnusedTemplateArgs),
184bdd1243dSDimitry Andric         TrackReferenceLocs(TrackReferenceLocs) {}
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   /// ParseFile - Main entrypoint for parsing a tblgen file.  These parser
1870b57cec5SDimitry Andric   /// routines return true on error, or false on success.
1880b57cec5SDimitry Andric   bool ParseFile();
1890b57cec5SDimitry Andric 
Error(SMLoc L,const Twine & Msg)1900b57cec5SDimitry Andric   bool Error(SMLoc L, const Twine &Msg) const {
1910b57cec5SDimitry Andric     PrintError(L, Msg);
1920b57cec5SDimitry Andric     return true;
1930b57cec5SDimitry Andric   }
TokError(const Twine & Msg)1940b57cec5SDimitry Andric   bool TokError(const Twine &Msg) const {
1950b57cec5SDimitry Andric     return Error(Lex.getLoc(), Msg);
1960b57cec5SDimitry Andric   }
getDependencies()197480093f4SDimitry Andric   const TGLexer::DependenciesSetTy &getDependencies() const {
1980b57cec5SDimitry Andric     return Lex.getDependencies();
1990b57cec5SDimitry Andric   }
2000b57cec5SDimitry Andric 
PushScope()20106c3fb27SDimitry Andric   TGVarScope *PushScope() {
20206c3fb27SDimitry Andric     CurScope = std::make_unique<TGVarScope>(std::move(CurScope));
203480093f4SDimitry Andric     // Returns a pointer to the new scope, so that the caller can pass it back
20406c3fb27SDimitry Andric     // to PopScope which will check by assertion that the pushes and pops
205480093f4SDimitry Andric     // match up properly.
20606c3fb27SDimitry Andric     return CurScope.get();
207480093f4SDimitry Andric   }
PushScope(Record * Rec)20806c3fb27SDimitry Andric   TGVarScope *PushScope(Record *Rec) {
20906c3fb27SDimitry Andric     CurScope = std::make_unique<TGVarScope>(std::move(CurScope), Rec);
21006c3fb27SDimitry Andric     return CurScope.get();
21106c3fb27SDimitry Andric   }
PushScope(ForeachLoop * Loop)21206c3fb27SDimitry Andric   TGVarScope *PushScope(ForeachLoop *Loop) {
21306c3fb27SDimitry Andric     CurScope = std::make_unique<TGVarScope>(std::move(CurScope), Loop);
21406c3fb27SDimitry Andric     return CurScope.get();
21506c3fb27SDimitry Andric   }
PushScope(MultiClass * Multiclass)21606c3fb27SDimitry Andric   TGVarScope *PushScope(MultiClass *Multiclass) {
21706c3fb27SDimitry Andric     CurScope = std::make_unique<TGVarScope>(std::move(CurScope), Multiclass);
21806c3fb27SDimitry Andric     return CurScope.get();
21906c3fb27SDimitry Andric   }
PopScope(TGVarScope * ExpectedStackTop)22006c3fb27SDimitry Andric   void PopScope(TGVarScope *ExpectedStackTop) {
22106c3fb27SDimitry Andric     assert(ExpectedStackTop == CurScope.get() &&
222480093f4SDimitry Andric            "Mismatched pushes and pops of local variable scopes");
22306c3fb27SDimitry Andric     CurScope = CurScope->extractParent();
224480093f4SDimitry Andric   }
225480093f4SDimitry Andric 
2260b57cec5SDimitry Andric private: // Semantic analysis methods.
2270b57cec5SDimitry Andric   bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV);
228bdd1243dSDimitry Andric   /// Set the value of a RecordVal within the given record. If `OverrideDefLoc`
229bdd1243dSDimitry Andric   /// is set, the provided location overrides any existing location of the
230bdd1243dSDimitry Andric   /// RecordVal.
2310b57cec5SDimitry Andric   bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName,
2320b57cec5SDimitry Andric                 ArrayRef<unsigned> BitList, Init *V,
233bdd1243dSDimitry Andric                 bool AllowSelfAssignment = false, bool OverrideDefLoc = true);
2340b57cec5SDimitry Andric   bool AddSubClass(Record *Rec, SubClassReference &SubClass);
2350b57cec5SDimitry Andric   bool AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass);
2360b57cec5SDimitry Andric   bool AddSubMultiClass(MultiClass *CurMC,
2370b57cec5SDimitry Andric                         SubMultiClassReference &SubMultiClass);
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   using SubstStack = SmallVector<std::pair<Init *, Init *>, 8>;
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric   bool addEntry(RecordsEntry E);
2420b57cec5SDimitry Andric   bool resolve(const ForeachLoop &Loop, SubstStack &Stack, bool Final,
2430b57cec5SDimitry Andric                std::vector<RecordsEntry> *Dest, SMLoc *Loc = nullptr);
2440b57cec5SDimitry Andric   bool resolve(const std::vector<RecordsEntry> &Source, SubstStack &Substs,
2450b57cec5SDimitry Andric                bool Final, std::vector<RecordsEntry> *Dest,
2460b57cec5SDimitry Andric                SMLoc *Loc = nullptr);
2470b57cec5SDimitry Andric   bool addDefOne(std::unique_ptr<Record> Rec);
2480b57cec5SDimitry Andric 
24906c3fb27SDimitry Andric   using ArgValueHandler = std::function<void(Init *, Init *)>;
25006c3fb27SDimitry Andric   bool resolveArguments(
25106c3fb27SDimitry Andric       Record *Rec, ArrayRef<ArgumentInit *> ArgValues, SMLoc Loc,
25206c3fb27SDimitry Andric       ArgValueHandler ArgValueHandler = [](Init *, Init *) {});
25306c3fb27SDimitry Andric   bool resolveArgumentsOfClass(MapResolver &R, Record *Rec,
25406c3fb27SDimitry Andric                                ArrayRef<ArgumentInit *> ArgValues, SMLoc Loc);
25506c3fb27SDimitry Andric   bool resolveArgumentsOfMultiClass(SubstStack &Substs, MultiClass *MC,
25606c3fb27SDimitry Andric                                     ArrayRef<ArgumentInit *> ArgValues,
25706c3fb27SDimitry Andric                                     Init *DefmName, SMLoc Loc);
25806c3fb27SDimitry Andric 
2590b57cec5SDimitry Andric private:  // Parser methods.
2605ffd83dbSDimitry Andric   bool consume(tgtok::TokKind K);
2610b57cec5SDimitry Andric   bool ParseObjectList(MultiClass *MC = nullptr);
2620b57cec5SDimitry Andric   bool ParseObject(MultiClass *MC);
2630b57cec5SDimitry Andric   bool ParseClass();
2640b57cec5SDimitry Andric   bool ParseMultiClass();
2650b57cec5SDimitry Andric   bool ParseDefm(MultiClass *CurMultiClass);
2660b57cec5SDimitry Andric   bool ParseDef(MultiClass *CurMultiClass);
2670b57cec5SDimitry Andric   bool ParseDefset();
268*0fca6ea1SDimitry Andric   bool ParseDeftype();
26906c3fb27SDimitry Andric   bool ParseDefvar(Record *CurRec = nullptr);
2705f757f3fSDimitry Andric   bool ParseDump(MultiClass *CurMultiClass, Record *CurRec = nullptr);
2710b57cec5SDimitry Andric   bool ParseForeach(MultiClass *CurMultiClass);
272480093f4SDimitry Andric   bool ParseIf(MultiClass *CurMultiClass);
273480093f4SDimitry Andric   bool ParseIfBody(MultiClass *CurMultiClass, StringRef Kind);
274fe6060f1SDimitry Andric   bool ParseAssert(MultiClass *CurMultiClass, Record *CurRec = nullptr);
2750b57cec5SDimitry Andric   bool ParseTopLevelLet(MultiClass *CurMultiClass);
2760b57cec5SDimitry Andric   void ParseLetList(SmallVectorImpl<LetRecord> &Result);
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric   bool ParseObjectBody(Record *CurRec);
2790b57cec5SDimitry Andric   bool ParseBody(Record *CurRec);
2800b57cec5SDimitry Andric   bool ParseBodyItem(Record *CurRec);
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   bool ParseTemplateArgList(Record *CurRec);
2830b57cec5SDimitry Andric   Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
2840b57cec5SDimitry Andric   VarInit *ParseForeachDeclaration(Init *&ForeachListValue);
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
2870b57cec5SDimitry Andric   SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
2880b57cec5SDimitry Andric 
289bdd1243dSDimitry Andric   Init *ParseIDValue(Record *CurRec, StringInit *Name, SMRange NameLoc,
2900b57cec5SDimitry Andric                      IDParseMode Mode = ParseValueMode);
2910b57cec5SDimitry Andric   Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = nullptr,
2920b57cec5SDimitry Andric                          IDParseMode Mode = ParseValueMode);
2930b57cec5SDimitry Andric   Init *ParseValue(Record *CurRec, RecTy *ItemType = nullptr,
2940b57cec5SDimitry Andric                    IDParseMode Mode = ParseValueMode);
295fe6060f1SDimitry Andric   void ParseValueList(SmallVectorImpl<llvm::Init*> &Result,
296fe6060f1SDimitry Andric                       Record *CurRec, RecTy *ItemType = nullptr);
29706c3fb27SDimitry Andric   bool ParseTemplateArgValueList(SmallVectorImpl<llvm::ArgumentInit *> &Result,
2985f757f3fSDimitry Andric                                  Record *CurRec, Record *ArgsRec);
2990b57cec5SDimitry Andric   void ParseDagArgList(
3000b57cec5SDimitry Andric       SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
3010b57cec5SDimitry Andric       Record *CurRec);
3020b57cec5SDimitry Andric   bool ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges);
3030b57cec5SDimitry Andric   bool ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges);
30406c3fb27SDimitry Andric   TypedInit *ParseSliceElement(Record *CurRec);
30506c3fb27SDimitry Andric   TypedInit *ParseSliceElements(Record *CurRec, bool Single = false);
3060b57cec5SDimitry Andric   void ParseRangeList(SmallVectorImpl<unsigned> &Result);
3070b57cec5SDimitry Andric   bool ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
3080b57cec5SDimitry Andric                        TypedInit *FirstItem = nullptr);
3090b57cec5SDimitry Andric   RecTy *ParseType();
3100b57cec5SDimitry Andric   Init *ParseOperation(Record *CurRec, RecTy *ItemType);
311e8d8bef9SDimitry Andric   Init *ParseOperationSubstr(Record *CurRec, RecTy *ItemType);
312fe6060f1SDimitry Andric   Init *ParseOperationFind(Record *CurRec, RecTy *ItemType);
313e8d8bef9SDimitry Andric   Init *ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType);
3140b57cec5SDimitry Andric   Init *ParseOperationCond(Record *CurRec, RecTy *ItemType);
3150b57cec5SDimitry Andric   RecTy *ParseOperatorType();
3160b57cec5SDimitry Andric   Init *ParseObjectName(MultiClass *CurMultiClass);
3170b57cec5SDimitry Andric   Record *ParseClassID();
3180b57cec5SDimitry Andric   MultiClass *ParseMultiClassID();
3190b57cec5SDimitry Andric   bool ApplyLetStack(Record *CurRec);
3200b57cec5SDimitry Andric   bool ApplyLetStack(RecordsEntry &Entry);
32106c3fb27SDimitry Andric   bool CheckTemplateArgValues(SmallVectorImpl<llvm::ArgumentInit *> &Values,
322fe6060f1SDimitry Andric                               SMLoc Loc, Record *ArgsRec);
3230b57cec5SDimitry Andric };
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric } // end namespace llvm
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric #endif
328