diff options
Diffstat (limited to 'lib/TableGen')
-rw-r--r-- | lib/TableGen/Android.mk | 1 | ||||
-rw-r--r-- | lib/TableGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/TableGen/Main.cpp | 14 | ||||
-rw-r--r-- | lib/TableGen/Record.cpp | 10 | ||||
-rw-r--r-- | lib/TableGen/SetTheory.cpp | 323 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.cpp | 22 | ||||
-rw-r--r-- | lib/TableGen/TGLexer.h | 6 | ||||
-rw-r--r-- | lib/TableGen/TGParser.cpp | 29 | ||||
-rw-r--r-- | lib/TableGen/TGParser.h | 2 |
9 files changed, 367 insertions, 41 deletions
diff --git a/lib/TableGen/Android.mk b/lib/TableGen/Android.mk index 1f01ef7..0fd94bb 100644 --- a/lib/TableGen/Android.mk +++ b/lib/TableGen/Android.mk @@ -4,6 +4,7 @@ libtablegen_SRC_FILES := \ Error.cpp \ Main.cpp \ Record.cpp \ + SetTheory.cpp \ StringMatcher.cpp \ TableGenBackend.cpp \ TGLexer.cpp \ diff --git a/lib/TableGen/CMakeLists.txt b/lib/TableGen/CMakeLists.txt index 935d674..fb70218 100644 --- a/lib/TableGen/CMakeLists.txt +++ b/lib/TableGen/CMakeLists.txt @@ -2,6 +2,7 @@ add_llvm_library(LLVMTableGen Error.cpp Main.cpp Record.cpp + SetTheory.cpp StringMatcher.cpp TableGenBackend.cpp TGLexer.cpp diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp index 476026d..e317fbf 100644 --- a/lib/TableGen/Main.cpp +++ b/lib/TableGen/Main.cpp @@ -20,12 +20,12 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/ToolOutputFile.h" -#include "llvm/Support/system_error.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Main.h" #include "llvm/TableGen/Record.h" #include <algorithm> #include <cstdio> +#include <system_error> using namespace llvm; namespace { @@ -81,14 +81,14 @@ int TableGenMain(char *argv0, TableGenMainFn *MainFn) { RecordKeeper Records; // Parse the input file. - std::unique_ptr<MemoryBuffer> File; - if (error_code ec = - MemoryBuffer::getFileOrSTDIN(InputFilename, File)) { - errs() << "Could not open input file '" << InputFilename << "': " - << ec.message() <<"\n"; + ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = + MemoryBuffer::getFileOrSTDIN(InputFilename); + if (std::error_code EC = FileOrErr.getError()) { + errs() << "Could not open input file '" << InputFilename + << "': " << EC.message() << "\n"; return 1; } - MemoryBuffer *F = File.release(); + MemoryBuffer *F = FileOrErr.get().release(); // Tell SrcMgr about this buffer, which is what TGParser will pick up. SrcMgr.AddNewSourceBuffer(F, SMLoc()); diff --git a/lib/TableGen/Record.cpp b/lib/TableGen/Record.cpp index c553a21..f7843dc 100644 --- a/lib/TableGen/Record.cpp +++ b/lib/TableGen/Record.cpp @@ -811,20 +811,14 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { } case HEAD: { if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { - if (LHSl->getSize() == 0) { - assert(0 && "Empty list in car"); - return nullptr; - } + assert(LHSl->getSize() != 0 && "Empty list in car"); return LHSl->getElement(0); } break; } case TAIL: { if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) { - if (LHSl->getSize() == 0) { - assert(0 && "Empty list in cdr"); - return nullptr; - } + assert(LHSl->getSize() != 0 && "Empty list in cdr"); // Note the +1. We can't just pass the result of getValues() // directly. ArrayRef<Init *>::iterator begin = LHSl->getValues().begin()+1; diff --git a/lib/TableGen/SetTheory.cpp b/lib/TableGen/SetTheory.cpp new file mode 100644 index 0000000..c99c2ba --- /dev/null +++ b/lib/TableGen/SetTheory.cpp @@ -0,0 +1,323 @@ +//===- SetTheory.cpp - Generate ordered sets from DAG expressions ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the SetTheory class that computes ordered sets of +// Records from DAG expressions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Format.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/SetTheory.h" + +using namespace llvm; + +// Define the standard operators. +namespace { + +typedef SetTheory::RecSet RecSet; +typedef SetTheory::RecVec RecVec; + +// (add a, b, ...) Evaluate and union all arguments. +struct AddOp : public SetTheory::Operator { + void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts, + ArrayRef<SMLoc> Loc) override { + ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts, Loc); + } +}; + +// (sub Add, Sub, ...) Set difference. +struct SubOp : public SetTheory::Operator { + void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts, + ArrayRef<SMLoc> Loc) override { + if (Expr->arg_size() < 2) + PrintFatalError(Loc, "Set difference needs at least two arguments: " + + Expr->getAsString()); + RecSet Add, Sub; + ST.evaluate(*Expr->arg_begin(), Add, Loc); + ST.evaluate(Expr->arg_begin() + 1, Expr->arg_end(), Sub, Loc); + for (RecSet::iterator I = Add.begin(), E = Add.end(); I != E; ++I) + if (!Sub.count(*I)) + Elts.insert(*I); + } +}; + +// (and S1, S2) Set intersection. +struct AndOp : public SetTheory::Operator { + void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts, + ArrayRef<SMLoc> Loc) override { + if (Expr->arg_size() != 2) + PrintFatalError(Loc, "Set intersection requires two arguments: " + + Expr->getAsString()); + RecSet S1, S2; + ST.evaluate(Expr->arg_begin()[0], S1, Loc); + ST.evaluate(Expr->arg_begin()[1], S2, Loc); + for (RecSet::iterator I = S1.begin(), E = S1.end(); I != E; ++I) + if (S2.count(*I)) + Elts.insert(*I); + } +}; + +// SetIntBinOp - Abstract base class for (Op S, N) operators. +struct SetIntBinOp : public SetTheory::Operator { + virtual void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N, + RecSet &Elts, ArrayRef<SMLoc> Loc) = 0; + + void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts, + ArrayRef<SMLoc> Loc) override { + if (Expr->arg_size() != 2) + PrintFatalError(Loc, "Operator requires (Op Set, Int) arguments: " + + Expr->getAsString()); + RecSet Set; + ST.evaluate(Expr->arg_begin()[0], Set, Loc); + IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1]); + if (!II) + PrintFatalError(Loc, "Second argument must be an integer: " + + Expr->getAsString()); + apply2(ST, Expr, Set, II->getValue(), Elts, Loc); + } +}; + +// (shl S, N) Shift left, remove the first N elements. +struct ShlOp : public SetIntBinOp { + void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N, + RecSet &Elts, ArrayRef<SMLoc> Loc) override { + if (N < 0) + PrintFatalError(Loc, "Positive shift required: " + + Expr->getAsString()); + if (unsigned(N) < Set.size()) + Elts.insert(Set.begin() + N, Set.end()); + } +}; + +// (trunc S, N) Truncate after the first N elements. +struct TruncOp : public SetIntBinOp { + void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N, + RecSet &Elts, ArrayRef<SMLoc> Loc) override { + if (N < 0) + PrintFatalError(Loc, "Positive length required: " + + Expr->getAsString()); + if (unsigned(N) > Set.size()) + N = Set.size(); + Elts.insert(Set.begin(), Set.begin() + N); + } +}; + +// Left/right rotation. +struct RotOp : public SetIntBinOp { + const bool Reverse; + + RotOp(bool Rev) : Reverse(Rev) {} + + void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N, + RecSet &Elts, ArrayRef<SMLoc> Loc) override { + if (Reverse) + N = -N; + // N > 0 -> rotate left, N < 0 -> rotate right. + if (Set.empty()) + return; + if (N < 0) + N = Set.size() - (-N % Set.size()); + else + N %= Set.size(); + Elts.insert(Set.begin() + N, Set.end()); + Elts.insert(Set.begin(), Set.begin() + N); + } +}; + +// (decimate S, N) Pick every N'th element of S. +struct DecimateOp : public SetIntBinOp { + void apply2(SetTheory &ST, DagInit *Expr, RecSet &Set, int64_t N, + RecSet &Elts, ArrayRef<SMLoc> Loc) override { + if (N <= 0) + PrintFatalError(Loc, "Positive stride required: " + + Expr->getAsString()); + for (unsigned I = 0; I < Set.size(); I += N) + Elts.insert(Set[I]); + } +}; + +// (interleave S1, S2, ...) Interleave elements of the arguments. +struct InterleaveOp : public SetTheory::Operator { + void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts, + ArrayRef<SMLoc> Loc) override { + // Evaluate the arguments individually. + SmallVector<RecSet, 4> Args(Expr->getNumArgs()); + unsigned MaxSize = 0; + for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i) { + ST.evaluate(Expr->getArg(i), Args[i], Loc); + MaxSize = std::max(MaxSize, unsigned(Args[i].size())); + } + // Interleave arguments into Elts. + for (unsigned n = 0; n != MaxSize; ++n) + for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i) + if (n < Args[i].size()) + Elts.insert(Args[i][n]); + } +}; + +// (sequence "Format", From, To) Generate a sequence of records by name. +struct SequenceOp : public SetTheory::Operator { + void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts, + ArrayRef<SMLoc> Loc) override { + int Step = 1; + if (Expr->arg_size() > 4) + PrintFatalError(Loc, "Bad args to (sequence \"Format\", From, To): " + + Expr->getAsString()); + else if (Expr->arg_size() == 4) { + if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[3])) { + Step = II->getValue(); + } else + PrintFatalError(Loc, "Stride must be an integer: " + + Expr->getAsString()); + } + + std::string Format; + if (StringInit *SI = dyn_cast<StringInit>(Expr->arg_begin()[0])) + Format = SI->getValue(); + else + PrintFatalError(Loc, "Format must be a string: " + Expr->getAsString()); + + int64_t From, To; + if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[1])) + From = II->getValue(); + else + PrintFatalError(Loc, "From must be an integer: " + Expr->getAsString()); + if (From < 0 || From >= (1 << 30)) + PrintFatalError(Loc, "From out of range"); + + if (IntInit *II = dyn_cast<IntInit>(Expr->arg_begin()[2])) + To = II->getValue(); + else + PrintFatalError(Loc, "From must be an integer: " + Expr->getAsString()); + if (To < 0 || To >= (1 << 30)) + PrintFatalError(Loc, "To out of range"); + + RecordKeeper &Records = + cast<DefInit>(Expr->getOperator())->getDef()->getRecords(); + + Step *= From <= To ? 1 : -1; + while (true) { + if (Step > 0 && From > To) + break; + else if (Step < 0 && From < To) + break; + std::string Name; + raw_string_ostream OS(Name); + OS << format(Format.c_str(), unsigned(From)); + Record *Rec = Records.getDef(OS.str()); + if (!Rec) + PrintFatalError(Loc, "No def named '" + Name + "': " + + Expr->getAsString()); + // Try to reevaluate Rec in case it is a set. + if (const RecVec *Result = ST.expand(Rec)) + Elts.insert(Result->begin(), Result->end()); + else + Elts.insert(Rec); + + From += Step; + } + } +}; + +// Expand a Def into a set by evaluating one of its fields. +struct FieldExpander : public SetTheory::Expander { + StringRef FieldName; + + FieldExpander(StringRef fn) : FieldName(fn) {} + + void expand(SetTheory &ST, Record *Def, RecSet &Elts) override { + ST.evaluate(Def->getValueInit(FieldName), Elts, Def->getLoc()); + } +}; +} // end anonymous namespace + +// Pin the vtables to this file. +void SetTheory::Operator::anchor() {} +void SetTheory::Expander::anchor() {} + + +SetTheory::SetTheory() { + addOperator("add", new AddOp); + addOperator("sub", new SubOp); + addOperator("and", new AndOp); + addOperator("shl", new ShlOp); + addOperator("trunc", new TruncOp); + addOperator("rotl", new RotOp(false)); + addOperator("rotr", new RotOp(true)); + addOperator("decimate", new DecimateOp); + addOperator("interleave", new InterleaveOp); + addOperator("sequence", new SequenceOp); +} + +void SetTheory::addOperator(StringRef Name, Operator *Op) { + Operators[Name] = Op; +} + +void SetTheory::addExpander(StringRef ClassName, Expander *E) { + Expanders[ClassName] = E; +} + +void SetTheory::addFieldExpander(StringRef ClassName, StringRef FieldName) { + addExpander(ClassName, new FieldExpander(FieldName)); +} + +void SetTheory::evaluate(Init *Expr, RecSet &Elts, ArrayRef<SMLoc> Loc) { + // A def in a list can be a just an element, or it may expand. + if (DefInit *Def = dyn_cast<DefInit>(Expr)) { + if (const RecVec *Result = expand(Def->getDef())) + return Elts.insert(Result->begin(), Result->end()); + Elts.insert(Def->getDef()); + return; + } + + // Lists simply expand. + if (ListInit *LI = dyn_cast<ListInit>(Expr)) + return evaluate(LI->begin(), LI->end(), Elts, Loc); + + // Anything else must be a DAG. + DagInit *DagExpr = dyn_cast<DagInit>(Expr); + if (!DagExpr) + PrintFatalError(Loc, "Invalid set element: " + Expr->getAsString()); + DefInit *OpInit = dyn_cast<DefInit>(DagExpr->getOperator()); + if (!OpInit) + PrintFatalError(Loc, "Bad set expression: " + Expr->getAsString()); + Operator *Op = Operators.lookup(OpInit->getDef()->getName()); + if (!Op) + PrintFatalError(Loc, "Unknown set operator: " + Expr->getAsString()); + Op->apply(*this, DagExpr, Elts, Loc); +} + +const RecVec *SetTheory::expand(Record *Set) { + // Check existing entries for Set and return early. + ExpandMap::iterator I = Expansions.find(Set); + if (I != Expansions.end()) + return &I->second; + + // This is the first time we see Set. Find a suitable expander. + const std::vector<Record*> &SC = Set->getSuperClasses(); + for (unsigned i = 0, e = SC.size(); i != e; ++i) { + // Skip unnamed superclasses. + if (!dyn_cast<StringInit>(SC[i]->getNameInit())) + continue; + if (Expander *Exp = Expanders.lookup(SC[i]->getName())) { + // This breaks recursive definitions. + RecVec &EltVec = Expansions[Set]; + RecSet Elts; + Exp->expand(*this, Set, Elts); + EltVec.assign(Elts.begin(), Elts.end()); + return &EltVec; + } + } + + // Set is not expandable. + return nullptr; +} + diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp index 1ec2eea..fc1d3ca 100644 --- a/lib/TableGen/TGLexer.cpp +++ b/lib/TableGen/TGLexer.cpp @@ -27,9 +27,9 @@ using namespace llvm; TGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) { - CurBuffer = 0; - CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); - CurPtr = CurBuf->getBufferStart(); + CurBuffer = SrcMgr.getMainFileID(); + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(); + CurPtr = CurBuf.begin(); TokStart = nullptr; } @@ -52,7 +52,7 @@ int TGLexer::getNextChar() { case 0: { // A nul character in the stream is either the end of the current buffer or // a random nul in the file. Disambiguate that here. - if (CurPtr-1 != CurBuf->getBufferEnd()) + if (CurPtr-1 != CurBuf.end()) return 0; // Just whitespace. // If this is the end of an included file, pop the parent file off the @@ -60,7 +60,7 @@ int TGLexer::getNextChar() { SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); if (ParentIncludeLoc != SMLoc()) { CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc); - CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(); CurPtr = ParentIncludeLoc.getPointer(); return getNextChar(); } @@ -187,7 +187,7 @@ tgtok::TokKind TGLexer::LexString() { while (*CurPtr != '"') { // If we hit the end of the buffer, report an error. - if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) + if (*CurPtr == 0 && CurPtr == CurBuf.end()) return ReturnError(StrStart, "End of file in string literal"); if (*CurPtr == '\n' || *CurPtr == '\r') @@ -220,7 +220,7 @@ tgtok::TokKind TGLexer::LexString() { // If we hit the end of the buffer, report an error. case '\0': - if (CurPtr == CurBuf->getBufferEnd()) + if (CurPtr == CurBuf.end()) return ReturnError(StrStart, "End of file in string literal"); // FALL THROUGH default: @@ -304,7 +304,7 @@ bool TGLexer::LexInclude() { CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr), IncludedFile); - if (CurBuffer == -1) { + if (!CurBuffer) { PrintError(getLoc(), "Could not find include file '" + Filename + "'"); return true; } @@ -319,8 +319,8 @@ bool TGLexer::LexInclude() { } Dependencies.insert(std::make_pair(IncludedFile, getLoc())); // Save the line number and lex buffer of the includer. - CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); - CurPtr = CurBuf->getBufferStart(); + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(); + CurPtr = CurBuf.begin(); return false; } @@ -333,7 +333,7 @@ void TGLexer::SkipBCPLComment() { return; // Newline is end of comment. case 0: // If this is the end of the buffer, end the comment. - if (CurPtr == CurBuf->getBufferEnd()) + if (CurPtr == CurBuf.end()) return; break; } diff --git a/lib/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h index 1e599f8..a2c95ca 100644 --- a/lib/TableGen/TGLexer.h +++ b/lib/TableGen/TGLexer.h @@ -14,6 +14,7 @@ #ifndef TGLEXER_H #define TGLEXER_H +#include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/SMLoc.h" #include <cassert> @@ -21,7 +22,6 @@ #include <string> namespace llvm { -class MemoryBuffer; class SourceMgr; class SMLoc; class Twine; @@ -63,7 +63,7 @@ class TGLexer { SourceMgr &SrcMgr; const char *CurPtr; - const MemoryBuffer *CurBuf; + StringRef CurBuf; // Information about the current token. const char *TokStart; @@ -73,7 +73,7 @@ class TGLexer { /// CurBuffer - This is the current buffer index we're lexing from as managed /// by the SourceMgr object. - int CurBuffer; + unsigned CurBuffer; public: typedef std::map<std::string, SMLoc> DependenciesMapTy; diff --git a/lib/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp index 038e018..0550692 100644 --- a/lib/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -360,8 +360,13 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){ } if (Records.getDef(IterRec->getNameInitAsString())) { - Error(Loc, "def already exists: " + IterRec->getNameInitAsString()); - return true; + // If this record is anonymous, it's no problem, just generate a new name + if (IterRec->isAnonymous()) + IterRec->setName(GetNewAnonymousName()); + else { + Error(Loc, "def already exists: " + IterRec->getNameInitAsString()); + return true; + } } Records.addDef(IterRec); @@ -782,7 +787,7 @@ Init *TGParser::ParseIDValue(Record *CurRec, /// /// Operation ::= XOperator ['<' Type '>'] '(' Args ')' /// -Init *TGParser::ParseOperation(Record *CurRec) { +Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { switch (Lex.getCode()) { default: TokError("unknown operation"); @@ -845,7 +850,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType()); if (!LType && !SType) { - TokError("expected list or string type argumnet in unary operator"); + TokError("expected list or string type argument in unary operator"); return nullptr; } } @@ -853,7 +858,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) { if (!LHSl && !LHSt) { - TokError("expected list type argumnet in unary operator"); + TokError("expected list type argument in unary operator"); return nullptr; } @@ -877,7 +882,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { assert(LHSt && "expected list type argument in unary operator"); ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); if (!LType) { - TokError("expected list type argumnet in unary operator"); + TokError("expected list type argument in unary operator"); return nullptr; } if (Code == UnOpInit::HEAD) { @@ -1021,8 +1026,9 @@ Init *TGParser::ParseOperation(Record *CurRec) { } Lex.Lex(); // eat the ',' - Init *MHS = ParseValue(CurRec); - if (!MHS) return nullptr; + Init *MHS = ParseValue(CurRec, ItemType); + if (!MHS) + return nullptr; if (Lex.getCode() != tgtok::comma) { TokError("expected ',' in ternary operator"); @@ -1030,8 +1036,9 @@ Init *TGParser::ParseOperation(Record *CurRec) { } Lex.Lex(); // eat the ',' - Init *RHS = ParseValue(CurRec); - if (!RHS) return nullptr; + Init *RHS = ParseValue(CurRec, ItemType); + if (!RHS) + return nullptr; if (Lex.getCode() != tgtok::r_paren) { TokError("expected ')' in binary operator"); @@ -1441,7 +1448,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, case tgtok::XIf: case tgtok::XForEach: case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' - return ParseOperation(CurRec); + return ParseOperation(CurRec, ItemType); } } diff --git a/lib/TableGen/TGParser.h b/lib/TableGen/TGParser.h index 6fd442a..9f4b7e9 100644 --- a/lib/TableGen/TGParser.h +++ b/lib/TableGen/TGParser.h @@ -181,7 +181,7 @@ private: // Parser methods. std::vector<unsigned> ParseRangeList(); bool ParseRangePiece(std::vector<unsigned> &Ranges); RecTy *ParseType(); - Init *ParseOperation(Record *CurRec); + Init *ParseOperation(Record *CurRec, RecTy *ItemType); RecTy *ParseOperatorType(); Init *ParseObjectName(MultiClass *CurMultiClass); Record *ParseClassID(); |