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