TGParser.h revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===- TGParser.h - Parser for TableGen Files -------------------*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class represents the Parser for tablegen files.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef TGPARSER_H
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TGPARSER_H
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "TGLexer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/Twine.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Support/SourceMgr.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/TableGen/Error.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/TableGen/Record.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace llvm {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class Record;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class RecordVal;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class RecordKeeper;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class RecTy;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Init;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct MultiClass;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SubClassReference;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SubMultiClassReference;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct LetRecord {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string Name;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<unsigned> Bits;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Init *Value;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SMLoc Loc;
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    LetRecord(const std::string &N, const std::vector<unsigned> &B, Init *V,
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)              SMLoc L)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : Name(N), Bits(B), Value(V), Loc(L) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// ForeachLoop - Record the iteration state associated with a for loop.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// This is used to instantiate items in the loop body.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ForeachLoop {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VarInit *IterVar;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ListInit *ListValue;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ForeachLoop(VarInit *IVar, ListInit *LValue)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : IterVar(IVar), ListValue(LValue) {}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TGParser {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TGLexer Lex;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::vector<LetRecord> > LetStack;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, MultiClass*> MultiClasses;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  /// Loops - Keep track of any foreach loops we are within.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ///
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<ForeachLoop> LoopVector;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoopVector Loops;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /// current value.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiClass *CurMultiClass;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Record tracker
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RecordKeeper &Records;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned AnonCounter;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A "named boolean" indicating how to parse identifiers.  Usually
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identifiers map to some existing object but in special cases
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (e.g. parsing def names) no such object exists yet because we are
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the middle of creating in.  For those situations, allow the
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parser to ignore missing object errors.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum IDParseMode {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ParseValueMode,   // We are parsing a value we expect to look up.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ParseNameMode,    // We are parsing a name of an object that does not yet
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      // exist.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ParseForeachMode  // We are parsing a foreach init.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TGParser(SourceMgr &SrcMgr, RecordKeeper &records)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : Lex(SrcMgr), CurMultiClass(nullptr), Records(records), AnonCounter(0) {}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90  /// ParseFile - Main entrypoint for parsing a tblgen file.  These parser
91  /// routines return true on error, or false on success.
92  bool ParseFile();
93
94  bool Error(SMLoc L, const Twine &Msg) const {
95    PrintError(L, Msg);
96    return true;
97  }
98  bool TokError(const Twine &Msg) const {
99    return Error(Lex.getLoc(), Msg);
100  }
101  const TGLexer::DependenciesMapTy &getDependencies() const {
102    return Lex.getDependencies();
103  }
104
105private:  // Semantic analysis methods.
106  bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV);
107  bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName,
108                const std::vector<unsigned> &BitList, Init *V);
109  bool SetValue(Record *TheRec, SMLoc Loc, const std::string &ValName,
110                const std::vector<unsigned> &BitList, Init *V) {
111    return SetValue(TheRec, Loc, StringInit::get(ValName), BitList, V);
112  }
113  bool AddSubClass(Record *Rec, SubClassReference &SubClass);
114  bool AddSubMultiClass(MultiClass *CurMC,
115                        SubMultiClassReference &SubMultiClass);
116
117  std::string GetNewAnonymousName();
118
119  // IterRecord: Map an iterator name to a value.
120  struct IterRecord {
121    VarInit *IterVar;
122    Init *IterValue;
123    IterRecord(VarInit *Var, Init *Val) : IterVar(Var), IterValue(Val) {}
124  };
125
126  // IterSet: The set of all iterator values at some point in the
127  // iteration space.
128  typedef std::vector<IterRecord> IterSet;
129
130  bool ProcessForeachDefs(Record *CurRec, SMLoc Loc);
131  bool ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals);
132
133private:  // Parser methods.
134  bool ParseObjectList(MultiClass *MC = nullptr);
135  bool ParseObject(MultiClass *MC);
136  bool ParseClass();
137  bool ParseMultiClass();
138  Record *InstantiateMulticlassDef(MultiClass &MC,
139                                   Record *DefProto,
140                                   Init *&DefmPrefix,
141                                   SMRange DefmPrefixRange);
142  bool ResolveMulticlassDefArgs(MultiClass &MC,
143                                Record *DefProto,
144                                SMLoc DefmPrefixLoc,
145                                SMLoc SubClassLoc,
146                                const std::vector<Init *> &TArgs,
147                                std::vector<Init *> &TemplateVals,
148                                bool DeleteArgs);
149  bool ResolveMulticlassDef(MultiClass &MC,
150                            Record *CurRec,
151                            Record *DefProto,
152                            SMLoc DefmPrefixLoc);
153  bool ParseDefm(MultiClass *CurMultiClass);
154  bool ParseDef(MultiClass *CurMultiClass);
155  bool ParseForeach(MultiClass *CurMultiClass);
156  bool ParseTopLevelLet(MultiClass *CurMultiClass);
157  std::vector<LetRecord> ParseLetList();
158
159  bool ParseObjectBody(Record *CurRec);
160  bool ParseBody(Record *CurRec);
161  bool ParseBodyItem(Record *CurRec);
162
163  bool ParseTemplateArgList(Record *CurRec);
164  Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs);
165  VarInit *ParseForeachDeclaration(ListInit *&ForeachListValue);
166
167  SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm);
168  SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC);
169
170  Init *ParseIDValue(Record *CurRec, const std::string &Name, SMLoc NameLoc,
171                     IDParseMode Mode = ParseValueMode);
172  Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = nullptr,
173                         IDParseMode Mode = ParseValueMode);
174  Init *ParseValue(Record *CurRec, RecTy *ItemType = nullptr,
175                   IDParseMode Mode = ParseValueMode);
176  std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = nullptr,
177                                    RecTy *EltTy = nullptr);
178  std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
179  bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
180  bool ParseOptionalBitList(std::vector<unsigned> &Ranges);
181  std::vector<unsigned> ParseRangeList();
182  bool ParseRangePiece(std::vector<unsigned> &Ranges);
183  RecTy *ParseType();
184  Init *ParseOperation(Record *CurRec);
185  RecTy *ParseOperatorType();
186  Init *ParseObjectName(MultiClass *CurMultiClass);
187  Record *ParseClassID();
188  MultiClass *ParseMultiClassID();
189  bool ApplyLetStack(Record *CurRec);
190};
191
192} // end namespace llvm
193
194#endif
195