//===- TGParser.cpp - Parser for TableGen Files ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implement the Parser for TableGen.
//
//===----------------------------------------------------------------------===//

#include "TGParser.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <limits>

using namespace llvm;

//===----------------------------------------------------------------------===//
// Support Code for the Semantic Actions.
//===----------------------------------------------------------------------===//

namespace llvm {

struct SubClassReference {
  SMRange RefRange;
  Record *Rec;
  SmallVector<Init*, 4> TemplateArgs;

  SubClassReference() : Rec(nullptr) {}

  bool isInvalid() const { return Rec == nullptr; }
};

struct SubMultiClassReference {
  SMRange RefRange;
  MultiClass *MC;
  SmallVector<Init*, 4> TemplateArgs;

  SubMultiClassReference() : MC(nullptr) {}

  bool isInvalid() const { return MC == nullptr; }
  void dump() const;
};

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {
  errs() << "Multiclass:\n";

  MC->dump();

  errs() << "Template args:\n";
  for (Init *TA : TemplateArgs)
    TA->dump();
}
#endif

} // end namespace llvm

static bool checkBitsConcrete(Record &R, const RecordVal &RV) {
  BitsInit *BV = cast<BitsInit>(RV.getValue());
  for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
    Init *Bit = BV->getBit(i);
    bool IsReference = false;
    if (auto VBI = dyn_cast<VarBitInit>(Bit)) {
      if (auto VI = dyn_cast<VarInit>(VBI->getBitVar())) {
        if (R.getValue(VI->getName()))
          IsReference = true;
      }
    } else if (isa<VarInit>(Bit)) {
      IsReference = true;
    }
    if (!(IsReference || Bit->isConcrete()))
      return false;
  }
  return true;
}

static void checkConcrete(Record &R) {
  for (const RecordVal &RV : R.getValues()) {
    // HACK: Disable this check for variables declared with 'field'. This is
    // done merely because existing targets have legitimate cases of
    // non-concrete variables in helper defs. Ideally, we'd introduce a
    // 'maybe' or 'optional' modifier instead of this.
    if (RV.isNonconcreteOK())
      continue;

    if (Init *V = RV.getValue()) {
      bool Ok = isa<BitsInit>(V) ? checkBitsConcrete(R, RV) : V->isConcrete();
      if (!Ok) {
        PrintError(R.getLoc(),
                   Twine("Initializer of '") + RV.getNameInitAsString() +
                   "' in '" + R.getNameInitAsString() +
                   "' could not be fully resolved: " +
                   RV.getValue()->getAsString());
      }
    }
  }
}

/// Return an Init with a qualifier prefix referring
/// to CurRec's name.
static Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass,
                        Init *Name, StringRef Scoper) {
  Init *NewName =
      BinOpInit::getStrConcat(CurRec.getNameInit(), StringInit::get(Scoper));
  NewName = BinOpInit::getStrConcat(NewName, Name);
  if (CurMultiClass && Scoper != "::") {
    Init *Prefix = BinOpInit::getStrConcat(CurMultiClass->Rec.getNameInit(),
                                           StringInit::get("::"));
    NewName = BinOpInit::getStrConcat(Prefix, NewName);
  }

  if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
    NewName = BinOp->Fold(&CurRec);
  return NewName;
}

/// Return the qualified version of the implicit 'NAME' template argument.
static Init *QualifiedNameOfImplicitName(Record &Rec,
                                         MultiClass *MC = nullptr) {
  return QualifyName(Rec, MC, StringInit::get("NAME"), MC ? "::" : ":");
}

static Init *QualifiedNameOfImplicitName(MultiClass *MC) {
  return QualifiedNameOfImplicitName(MC->Rec, MC);
}

bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
  if (!CurRec)
    CurRec = &CurMultiClass->Rec;

  if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) {
    // The value already exists in the class, treat this as a set.
    if (ERV->setValue(RV.getValue()))
      return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
                   RV.getType()->getAsString() + "' is incompatible with " +
                   "previous definition of type '" +
                   ERV->getType()->getAsString() + "'");
  } else {
    CurRec->addValue(RV);
  }
  return false;
}

/// SetValue -
/// Return true on error, false on success.
bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
                        ArrayRef<unsigned> BitList, Init *V,
                        bool AllowSelfAssignment) {
  if (!V) return false;

  if (!CurRec) CurRec = &CurMultiClass->Rec;

  RecordVal *RV = CurRec->getValue(ValName);
  if (!RV)
    return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
                 "' unknown!");

  // Do not allow assignments like 'X = X'.  This will just cause infinite loops
  // in the resolution machinery.
  if (BitList.empty())
    if (VarInit *VI = dyn_cast<VarInit>(V))
      if (VI->getNameInit() == ValName && !AllowSelfAssignment)
        return Error(Loc, "Recursion / self-assignment forbidden");

  // If we are assigning to a subset of the bits in the value... then we must be
  // assigning to a field of BitsRecTy, which must have a BitsInit
  // initializer.
  //
  if (!BitList.empty()) {
    BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue());
    if (!CurVal)
      return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
                   "' is not a bits type");

    // Convert the incoming value to a bits type of the appropriate size...
    Init *BI = V->getCastTo(BitsRecTy::get(BitList.size()));
    if (!BI)
      return Error(Loc, "Initializer is not compatible with bit range");

    SmallVector<Init *, 16> NewBits(CurVal->getNumBits());

    // Loop over bits, assigning values as appropriate.
    for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
      unsigned Bit = BitList[i];
      if (NewBits[Bit])
        return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" +
                     ValName->getAsUnquotedString() + "' more than once");
      NewBits[Bit] = BI->getBit(i);
    }

    for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
      if (!NewBits[i])
        NewBits[i] = CurVal->getBit(i);

    V = BitsInit::get(NewBits);
  }

  if (RV->setValue(V, Loc)) {
    std::string InitType;
    if (BitsInit *BI = dyn_cast<BitsInit>(V))
      InitType = (Twine("' of type bit initializer with length ") +
                  Twine(BI->getNumBits())).str();
    else if (TypedInit *TI = dyn_cast<TypedInit>(V))
      InitType = (Twine("' of type '") + TI->getType()->getAsString()).str();
    return Error(Loc, "Field '" + ValName->getAsUnquotedString() +
                          "' of type '" + RV->getType()->getAsString() +
                          "' is incompatible with value '" +
                          V->getAsString() + InitType + "'");
  }
  return false;
}

/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template
/// args as SubClass's template arguments.
bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
  Record *SC = SubClass.Rec;
  MapResolver R(CurRec);

  // Loop over all the subclass record's fields. Add template arguments
  // to the resolver map. Add regular fields to the new record.
  for (const RecordVal &Field : SC->getValues()) {
    if (Field.isTemplateArg()) {
      R.set(Field.getNameInit(), Field.getValue());
    } else {
      if (AddValue(CurRec, SubClass.RefRange.Start, Field))
        return true;
    }
  }

  ArrayRef<Init *> TArgs = SC->getTemplateArgs();
  assert(SubClass.TemplateArgs.size() <= TArgs.size() &&
         "Too many template arguments allowed");

  // Loop over the template argument names. If a value was specified,
  // reset the map value. If not and there was no default, complain.
  for (unsigned I = 0, E = TArgs.size(); I != E; ++I) {
    if (I < SubClass.TemplateArgs.size())
      R.set(TArgs[I], SubClass.TemplateArgs[I]);
    else if (!R.isComplete(TArgs[I]))
      return Error(SubClass.RefRange.Start,
                   "Value not specified for template argument '" +
                       TArgs[I]->getAsUnquotedString() + "' (#" + Twine(I) +
                       ") of parent class '" + SC->getNameInitAsString() + "'");
  }

  // Copy the subclass record's assertions to the new record.
  CurRec->appendAssertions(SC);

  Init *Name;
  if (CurRec->isClass())
    Name =
        VarInit::get(QualifiedNameOfImplicitName(*CurRec), StringRecTy::get());
  else
    Name = CurRec->getNameInit();
  R.set(QualifiedNameOfImplicitName(*SC), Name);

  CurRec->resolveReferences(R);

  // Since everything went well, we can now set the "superclass" list for the
  // current record.
  ArrayRef<std::pair<Record *, SMRange>> SCs = SC->getSuperClasses();
  for (const auto &SCPair : SCs) {
    if (CurRec->isSubClassOf(SCPair.first))
      return Error(SubClass.RefRange.Start,
                   "Already subclass of '" + SCPair.first->getName() + "'!\n");
    CurRec->addSuperClass(SCPair.first, SCPair.second);
  }

  if (CurRec->isSubClassOf(SC))
    return Error(SubClass.RefRange.Start,
                 "Already subclass of '" + SC->getName() + "'!\n");
  CurRec->addSuperClass(SC, SubClass.RefRange);
  return false;
}

bool TGParser::AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass) {
  if (Entry.Rec)
    return AddSubClass(Entry.Rec.get(), SubClass);

  if (Entry.Assertion)
    return false;

  for (auto &E : Entry.Loop->Entries) {
    if (AddSubClass(E, SubClass))
      return true;
  }

  return false;
}

/// AddSubMultiClass - Add SubMultiClass as a subclass to
/// CurMC, resolving its template args as SubMultiClass's
/// template arguments.
bool TGParser::AddSubMultiClass(MultiClass *CurMC,
                                SubMultiClassReference &SubMultiClass) {
  MultiClass *SMC = SubMultiClass.MC;

  ArrayRef<Init *> SMCTArgs = SMC->Rec.getTemplateArgs();
  if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
    return Error(SubMultiClass.RefRange.Start,
                 "More template args specified than expected");

  // Prepare the mapping of template argument name to value, filling in default
  // values if necessary.
  SubstStack TemplateArgs;
  for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) {
    if (i < SubMultiClass.TemplateArgs.size()) {
      TemplateArgs.emplace_back(SMCTArgs[i], SubMultiClass.TemplateArgs[i]);
    } else {
      Init *Default = SMC->Rec.getValue(SMCTArgs[i])->getValue();
      if (!Default->isComplete()) {
        return Error(SubMultiClass.RefRange.Start,
                     "value not specified for template argument #" + Twine(i) +
                         " (" + SMCTArgs[i]->getAsUnquotedString() +
                         ") of multiclass '" + SMC->Rec.getNameInitAsString() +
                         "'");
      }
      TemplateArgs.emplace_back(SMCTArgs[i], Default);
    }
  }

  TemplateArgs.emplace_back(
      QualifiedNameOfImplicitName(SMC),
      VarInit::get(QualifiedNameOfImplicitName(CurMC), StringRecTy::get()));

  // Add all of the defs in the subclass into the current multiclass.
  return resolve(SMC->Entries, TemplateArgs, false, &CurMC->Entries);
}

/// Add a record, foreach loop, or assertion to the current context.
bool TGParser::addEntry(RecordsEntry E) {
  assert((!!E.Rec + !!E.Loop + !!E.Assertion) == 1 &&
         "RecordsEntry has invalid number of items");

  // If we are parsing a loop, add it to the loop's entries.
  if (!Loops.empty()) {
    Loops.back()->Entries.push_back(std::move(E));
    return false;
  }

  // If it is a loop, then resolve and perform the loop.
  if (E.Loop) {
    SubstStack Stack;
    return resolve(*E.Loop, Stack, CurMultiClass == nullptr,
                   CurMultiClass ? &CurMultiClass->Entries : nullptr);
  }

  // If we are parsing a multiclass, add it to the multiclass's entries.
  if (CurMultiClass) {
    CurMultiClass->Entries.push_back(std::move(E));
    return false;
  }

  // If it is an assertion, then it's a top-level one, so check it.
  if (E.Assertion) {
    CheckAssert(E.Assertion->Loc, E.Assertion->Condition, E.Assertion->Message);
    return false;
  }

  // It must be a record, so finish it off.
  return addDefOne(std::move(E.Rec));
}

/// Resolve the entries in \p Loop, going over inner loops recursively
/// and making the given subsitutions of (name, value) pairs.
///
/// The resulting records are stored in \p Dest if non-null. Otherwise, they
/// are added to the global record keeper.
bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs,
                       bool Final, std::vector<RecordsEntry> *Dest,
                       SMLoc *Loc) {
  MapResolver R;
  for (const auto &S : Substs)
    R.set(S.first, S.second);
  Init *List = Loop.ListValue->resolveReferences(R);
  auto LI = dyn_cast<ListInit>(List);
  if (!LI) {
    if (!Final) {
      Dest->emplace_back(std::make_unique<ForeachLoop>(Loop.Loc, Loop.IterVar,
                                                  List));
      return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
                     Loc);
    }

    PrintError(Loop.Loc, Twine("attempting to loop over '") +
                              List->getAsString() + "', expected a list");
    return true;
  }

  bool Error = false;
  for (auto Elt : *LI) {
    if (Loop.IterVar)
      Substs.emplace_back(Loop.IterVar->getNameInit(), Elt);
    Error = resolve(Loop.Entries, Substs, Final, Dest);
    if (Loop.IterVar)
      Substs.pop_back();
    if (Error)
      break;
  }
  return Error;
}

/// Resolve the entries in \p Source, going over loops recursively and
/// making the given substitutions of (name, value) pairs.
///
/// The resulting records are stored in \p Dest if non-null. Otherwise, they
/// are added to the global record keeper.
bool TGParser::resolve(const std::vector<RecordsEntry> &Source,
                       SubstStack &Substs, bool Final,
                       std::vector<RecordsEntry> *Dest, SMLoc *Loc) {
  bool Error = false;
  for (auto &E : Source) {
    if (E.Loop) {
      Error = resolve(*E.Loop, Substs, Final, Dest);

    } else if (E.Assertion) {
      MapResolver R;
      for (const auto &S : Substs)
        R.set(S.first, S.second);
      Init *Condition = E.Assertion->Condition->resolveReferences(R);
      Init *Message = E.Assertion->Message->resolveReferences(R);

      if (Dest)
        Dest->push_back(std::make_unique<Record::AssertionInfo>(
            E.Assertion->Loc, Condition, Message));
      else
        CheckAssert(E.Assertion->Loc, Condition, Message);

    } else {
      auto Rec = std::make_unique<Record>(*E.Rec);
      if (Loc)
        Rec->appendLoc(*Loc);

      MapResolver R(Rec.get());
      for (const auto &S : Substs)
        R.set(S.first, S.second);
      Rec->resolveReferences(R);

      if (Dest)
        Dest->push_back(std::move(Rec));
      else
        Error = addDefOne(std::move(Rec));
    }
    if (Error)
      break;
  }
  return Error;
}

/// Resolve the record fully and add it to the record keeper.
bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
  Init *NewName = nullptr;
  if (Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
    if (!Rec->isAnonymous()) {
      PrintError(Rec->getLoc(),
                 "def already exists: " + Rec->getNameInitAsString());
      PrintNote(Prev->getLoc(), "location of previous definition");
      return true;
    }
    NewName = Records.getNewAnonymousName();
  }

  Rec->resolveReferences(NewName);
  checkConcrete(*Rec);

  if (!isa<StringInit>(Rec->getNameInit())) {
    PrintError(Rec->getLoc(), Twine("record name '") +
                                  Rec->getNameInit()->getAsString() +
                                  "' could not be fully resolved");
    return true;
  }

  // Check the assertions.
  Rec->checkRecordAssertions();

  // If ObjectBody has template arguments, it's an error.
  assert(Rec->getTemplateArgs().empty() && "How'd this get template args?");

  for (DefsetRecord *Defset : Defsets) {
    DefInit *I = Rec->getDefInit();
    if (!I->getType()->typeIsA(Defset->EltTy)) {
      PrintError(Rec->getLoc(), Twine("adding record of incompatible type '") +
                                    I->getType()->getAsString() +
                                     "' to defset");
      PrintNote(Defset->Loc, "location of defset declaration");
      return true;
    }
    Defset->Elements.push_back(I);
  }

  Records.addDef(std::move(Rec));
  return false;
}

//===----------------------------------------------------------------------===//
// Parser Code
//===----------------------------------------------------------------------===//

/// isObjectStart - Return true if this is a valid first token for a statement.
static bool isObjectStart(tgtok::TokKind K) {
  return K == tgtok::Assert || K == tgtok::Class || K == tgtok::Def ||
         K == tgtok::Defm || K == tgtok::Defset || K == tgtok::Defvar ||
         K == tgtok::Foreach || K == tgtok::If || K == tgtok::Let ||
         K == tgtok::MultiClass;
}

bool TGParser::consume(tgtok::TokKind K) {
  if (Lex.getCode() == K) {
    Lex.Lex();
    return true;
  }
  return false;
}

/// ParseObjectName - If a valid object name is specified, return it. If no
/// name is specified, return the unset initializer. Return nullptr on parse
/// error.
///   ObjectName ::= Value [ '#' Value ]*
///   ObjectName ::= /*empty*/
///
Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
  switch (Lex.getCode()) {
  case tgtok::colon:
  case tgtok::semi:
  case tgtok::l_brace:
    // These are all of the tokens that can begin an object body.
    // Some of these can also begin values but we disallow those cases
    // because they are unlikely to be useful.
    return UnsetInit::get();
  default:
    break;
  }

  Record *CurRec = nullptr;
  if (CurMultiClass)
    CurRec = &CurMultiClass->Rec;

  Init *Name = ParseValue(CurRec, StringRecTy::get(), ParseNameMode);
  if (!Name)
    return nullptr;

  if (CurMultiClass) {
    Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass);
    HasReferenceResolver R(NameStr);
    Name->resolveReferences(R);
    if (!R.found())
      Name = BinOpInit::getStrConcat(VarInit::get(NameStr, StringRecTy::get()),
                                     Name);
  }

  return Name;
}

/// ParseClassID - Parse and resolve a reference to a class name.  This returns
/// null on error.
///
///    ClassID ::= ID
///
Record *TGParser::ParseClassID() {
  if (Lex.getCode() != tgtok::Id) {
    TokError("expected name for ClassID");
    return nullptr;
  }

  Record *Result = Records.getClass(Lex.getCurStrVal());
  if (!Result) {
    std::string Msg("Couldn't find class '" + Lex.getCurStrVal() + "'");
    if (MultiClasses[Lex.getCurStrVal()].get())
      TokError(Msg + ". Use 'defm' if you meant to use multiclass '" +
               Lex.getCurStrVal() + "'");
    else
      TokError(Msg);
  }

  Lex.Lex();
  return Result;
}

/// ParseMultiClassID - Parse and resolve a reference to a multiclass name.
/// This returns null on error.
///
///    MultiClassID ::= ID
///
MultiClass *TGParser::ParseMultiClassID() {
  if (Lex.getCode() != tgtok::Id) {
    TokError("expected name for MultiClassID");
    return nullptr;
  }

  MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get();
  if (!Result)
    TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");

  Lex.Lex();
  return Result;
}

/// ParseSubClassReference - Parse a reference to a subclass or a
/// multiclass. This returns a SubClassRefTy with a null Record* on error.
///
///  SubClassRef ::= ClassID
///  SubClassRef ::= ClassID '<' ValueList '>'
///
SubClassReference TGParser::
ParseSubClassReference(Record *CurRec, bool isDefm) {
  SubClassReference Result;
  Result.RefRange.Start = Lex.getLoc();

  if (isDefm) {
    if (MultiClass *MC = ParseMultiClassID())
      Result.Rec = &MC->Rec;
  } else {
    Result.Rec = ParseClassID();
  }
  if (!Result.Rec) return Result;

  // If there is no template arg list, we're done.
  if (!consume(tgtok::less)) {
    Result.RefRange.End = Lex.getLoc();
    return Result;
  }

  if (ParseTemplateArgValueList(Result.TemplateArgs, CurRec, Result.Rec)) {
    Result.Rec = nullptr; // Error parsing value list.
    return Result;
  }

  if (CheckTemplateArgValues(Result.TemplateArgs, Result.RefRange.Start,
                             Result.Rec)) {
    Result.Rec = nullptr; // Error checking value list.
    return Result;
  }

  Result.RefRange.End = Lex.getLoc();
  return Result;
}

/// ParseSubMultiClassReference - Parse a reference to a subclass or to a
/// templated submulticlass.  This returns a SubMultiClassRefTy with a null
/// Record* on error.
///
///  SubMultiClassRef ::= MultiClassID
///  SubMultiClassRef ::= MultiClassID '<' ValueList '>'
///
SubMultiClassReference TGParser::
ParseSubMultiClassReference(MultiClass *CurMC) {
  SubMultiClassReference Result;
  Result.RefRange.Start = Lex.getLoc();

  Result.MC = ParseMultiClassID();
  if (!Result.MC) return Result;

  // If there is no template arg list, we're done.
  if (!consume(tgtok::less)) {
    Result.RefRange.End = Lex.getLoc();
    return Result;
  }

  if (ParseTemplateArgValueList(Result.TemplateArgs, &CurMC->Rec,
                                &Result.MC->Rec)) {
    Result.MC = nullptr; // Error parsing value list.
    return Result;
  }

  Result.RefRange.End = Lex.getLoc();

  return Result;
}

/// ParseRangePiece - Parse a bit/value range.
///   RangePiece ::= INTVAL
///   RangePiece ::= INTVAL '...' INTVAL
///   RangePiece ::= INTVAL '-' INTVAL
///   RangePiece ::= INTVAL INTVAL 
// The last two forms are deprecated.
bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
                               TypedInit *FirstItem) {
  Init *CurVal = FirstItem;
  if (!CurVal)
    CurVal = ParseValue(nullptr);

  IntInit *II = dyn_cast_or_null<IntInit>(CurVal);
  if (!II)
    return TokError("expected integer or bitrange");

  int64_t Start = II->getValue();
  int64_t End;

  if (Start < 0)
    return TokError("invalid range, cannot be negative");

  switch (Lex.getCode()) {
  default:
    Ranges.push_back(Start);
    return false;

  case tgtok::dotdotdot:
  case tgtok::minus: {
    Lex.Lex(); // eat

    Init *I_End = ParseValue(nullptr);
    IntInit *II_End = dyn_cast_or_null<IntInit>(I_End);
    if (!II_End) {
      TokError("expected integer value as end of range");
      return true;
    }

    End = II_End->getValue();
    break;
  }
  case tgtok::IntVal: {
    End = -Lex.getCurIntVal();
    Lex.Lex();
    break;
  }
  }
  if (End < 0)
    return TokError("invalid range, cannot be negative");

  // Add to the range.
  if (Start < End)
    for (; Start <= End; ++Start)
      Ranges.push_back(Start);
  else
    for (; Start >= End; --Start)
      Ranges.push_back(Start);
  return false;
}

/// ParseRangeList - Parse a list of scalars and ranges into scalar values.
///
///   RangeList ::= RangePiece (',' RangePiece)*
///
void TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) {
  // Parse the first piece.
  if (ParseRangePiece(Result)) {
    Result.clear();
    return;
  }
  while (consume(tgtok::comma))
    // Parse the next range piece.
    if (ParseRangePiece(Result)) {
      Result.clear();
      return;
    }
}

/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.
///   OptionalRangeList ::= '<' RangeList '>'
///   OptionalRangeList ::= /*empty*/
bool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) {
  SMLoc StartLoc = Lex.getLoc();
  if (!consume(tgtok::less))
    return false;

  // Parse the range list.
  ParseRangeList(Ranges);
  if (Ranges.empty()) return true;

  if (!consume(tgtok::greater)) {
    TokError("expected '>' at end of range list");
    return Error(StartLoc, "to match this '<'");
  }
  return false;
}

/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing.
///   OptionalBitList ::= '{' RangeList '}'
///   OptionalBitList ::= /*empty*/
bool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) {
  SMLoc StartLoc = Lex.getLoc();
  if (!consume(tgtok::l_brace))
    return false;

  // Parse the range list.
  ParseRangeList(Ranges);
  if (Ranges.empty()) return true;

  if (!consume(tgtok::r_brace)) {
    TokError("expected '}' at end of bit list");
    return Error(StartLoc, "to match this '{'");
  }
  return false;
}

/// ParseType - Parse and return a tblgen type.  This returns null on error.
///
///   Type ::= STRING                       // string type
///   Type ::= CODE                         // code type
///   Type ::= BIT                          // bit type
///   Type ::= BITS '<' INTVAL '>'          // bits<x> type
///   Type ::= INT                          // int type
///   Type ::= LIST '<' Type '>'            // list<x> type
///   Type ::= DAG                          // dag type
///   Type ::= ClassID                      // Record Type
///
RecTy *TGParser::ParseType() {
  switch (Lex.getCode()) {
  default: TokError("Unknown token when expecting a type"); return nullptr;
  case tgtok::String:
  case tgtok::Code:   Lex.Lex(); return StringRecTy::get();
  case tgtok::Bit:    Lex.Lex(); return BitRecTy::get();
  case tgtok::Int:    Lex.Lex(); return IntRecTy::get();
  case tgtok::Dag:    Lex.Lex(); return DagRecTy::get();
  case tgtok::Id:
    if (Record *R = ParseClassID()) return RecordRecTy::get(R);
    TokError("unknown class name");
    return nullptr;
  case tgtok::Bits: {
    if (Lex.Lex() != tgtok::less) { // Eat 'bits'
      TokError("expected '<' after bits type");
      return nullptr;
    }
    if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
      TokError("expected integer in bits<n> type");
      return nullptr;
    }
    uint64_t Val = Lex.getCurIntVal();
    if (Lex.Lex() != tgtok::greater) { // Eat count.
      TokError("expected '>' at end of bits<n> type");
      return nullptr;
    }
    Lex.Lex();  // Eat '>'
    return BitsRecTy::get(Val);
  }
  case tgtok::List: {
    if (Lex.Lex() != tgtok::less) { // Eat 'bits'
      TokError("expected '<' after list type");
      return nullptr;
    }
    Lex.Lex();  // Eat '<'
    RecTy *SubType = ParseType();
    if (!SubType) return nullptr;

    if (!consume(tgtok::greater)) {
      TokError("expected '>' at end of list<ty> type");
      return nullptr;
    }
    return ListRecTy::get(SubType);
  }
  }
}

/// ParseIDValue
Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc,
                             IDParseMode Mode) {
  if (CurRec) {
    if (const RecordVal *RV = CurRec->getValue(Name))
      return VarInit::get(Name, RV->getType());
  }

  if ((CurRec && CurRec->isClass()) || CurMultiClass) {
    Init *TemplateArgName;
    if (CurMultiClass) {
      TemplateArgName =
          QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::");
    } else
      TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":");

    Record *TemplateRec = CurMultiClass ? &CurMultiClass->Rec : CurRec;
    if (TemplateRec->isTemplateArg(TemplateArgName)) {
      RecordVal *RV = TemplateRec->getValue(TemplateArgName);
      assert(RV && "Template arg doesn't exist??");
      RV->setUsed(true);
      return VarInit::get(TemplateArgName, RV->getType());
    } else if (Name->getValue() == "NAME") {
      return VarInit::get(TemplateArgName, StringRecTy::get());
    }
  }

  if (CurLocalScope)
    if (Init *I = CurLocalScope->getVar(Name->getValue()))
      return I;

  // If this is in a foreach loop, make sure it's not a loop iterator
  for (const auto &L : Loops) {
    if (L->IterVar) {
      VarInit *IterVar = dyn_cast<VarInit>(L->IterVar);
      if (IterVar && IterVar->getNameInit() == Name)
        return IterVar;
    }
  }

  if (Mode == ParseNameMode)
    return Name;

  if (Init *I = Records.getGlobal(Name->getValue()))
    return I;

  // Allow self-references of concrete defs, but delay the lookup so that we
  // get the correct type.
  if (CurRec && !CurRec->isClass() && !CurMultiClass &&
      CurRec->getNameInit() == Name)
    return UnOpInit::get(UnOpInit::CAST, Name, CurRec->getType());

  Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'");
  return nullptr;
}

/// ParseOperation - Parse an operator.  This returns null on error.
///
/// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
///
Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
  switch (Lex.getCode()) {
  default:
    TokError("unknown bang operator");
    return nullptr;
  case tgtok::XNOT:
  case tgtok::XHead:
  case tgtok::XTail:
  case tgtok::XSize:
  case tgtok::XEmpty:
  case tgtok::XCast:
  case tgtok::XGetDagOp: { // Value ::= !unop '(' Value ')'
    UnOpInit::UnaryOp Code;
    RecTy *Type = nullptr;

    switch (Lex.getCode()) {
    default: llvm_unreachable("Unhandled code!");
    case tgtok::XCast:
      Lex.Lex();  // eat the operation
      Code = UnOpInit::CAST;

      Type = ParseOperatorType();

      if (!Type) {
        TokError("did not get type for unary operator");
        return nullptr;
      }

      break;
    case tgtok::XNOT:
      Lex.Lex();  // eat the operation
      Code = UnOpInit::NOT;
      Type = IntRecTy::get();
      break;
    case tgtok::XHead:
      Lex.Lex();  // eat the operation
      Code = UnOpInit::HEAD;
      break;
    case tgtok::XTail:
      Lex.Lex();  // eat the operation
      Code = UnOpInit::TAIL;
      break;
    case tgtok::XSize:
      Lex.Lex();
      Code = UnOpInit::SIZE;
      Type = IntRecTy::get();
      break;
    case tgtok::XEmpty:
      Lex.Lex();  // eat the operation
      Code = UnOpInit::EMPTY;
      Type = IntRecTy::get();
      break;
    case tgtok::XGetDagOp:
      Lex.Lex();  // eat the operation
      if (Lex.getCode() == tgtok::less) {
        // Parse an optional type suffix, so that you can say
        // !getdagop<BaseClass>(someDag) as a shorthand for
        // !cast<BaseClass>(!getdagop(someDag)).
        Type = ParseOperatorType();

        if (!Type) {
          TokError("did not get type for unary operator");
          return nullptr;
        }

        if (!isa<RecordRecTy>(Type)) {
          TokError("type for !getdagop must be a record type");
          // but keep parsing, to consume the operand
        }
      } else {
        Type = RecordRecTy::get({});
      }
      Code = UnOpInit::GETDAGOP;
      break;
    }
    if (!consume(tgtok::l_paren)) {
      TokError("expected '(' after unary operator");
      return nullptr;
    }

    Init *LHS = ParseValue(CurRec);
    if (!LHS) return nullptr;

    if (Code == UnOpInit::EMPTY || Code == UnOpInit::SIZE) {
      ListInit *LHSl = dyn_cast<ListInit>(LHS);
      StringInit *LHSs = dyn_cast<StringInit>(LHS);
      DagInit *LHSd = dyn_cast<DagInit>(LHS);
      TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
      if (!LHSl && !LHSs && !LHSd && !LHSt) {
        TokError("expected string, list, or dag type argument in unary operator");
        return nullptr;
      }
      if (LHSt) {
        ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
        StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType());
        DagRecTy *DType = dyn_cast<DagRecTy>(LHSt->getType());
        if (!LType && !SType && !DType) {
          TokError("expected string, list, or dag type argument in unary operator");
          return nullptr;
        }
      }
    }

    if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) {
      ListInit *LHSl = dyn_cast<ListInit>(LHS);
      TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
      if (!LHSl && !LHSt) {
        TokError("expected list type argument in unary operator");
        return nullptr;
      }
      if (LHSt) {
        ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
        if (!LType) {
          TokError("expected list type argument in unary operator");
          return nullptr;
        }
      }

      if (LHSl && LHSl->empty()) {
        TokError("empty list argument in unary operator");
        return nullptr;
      }
      if (LHSl) {
        Init *Item = LHSl->getElement(0);
        TypedInit *Itemt = dyn_cast<TypedInit>(Item);
        if (!Itemt) {
          TokError("untyped list element in unary operator");
          return nullptr;
        }
        Type = (Code == UnOpInit::HEAD) ? Itemt->getType()
                                        : ListRecTy::get(Itemt->getType());
      } else {
        assert(LHSt && "expected list type argument in unary operator");
        ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
        Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType;
      }
    }

    if (!consume(tgtok::r_paren)) {
      TokError("expected ')' in unary operator");
      return nullptr;
    }
    return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec);
  }

  case tgtok::XIsA: {
    // Value ::= !isa '<' Type '>' '(' Value ')'
    Lex.Lex(); // eat the operation

    RecTy *Type = ParseOperatorType();
    if (!Type)
      return nullptr;

    if (!consume(tgtok::l_paren)) {
      TokError("expected '(' after type of !isa");
      return nullptr;
    }

    Init *LHS = ParseValue(CurRec);
    if (!LHS)
      return nullptr;

    if (!consume(tgtok::r_paren)) {
      TokError("expected ')' in !isa");
      return nullptr;
    }

    return (IsAOpInit::get(Type, LHS))->Fold();
  }

  case tgtok::XConcat:
  case tgtok::XADD:
  case tgtok::XSUB:
  case tgtok::XMUL:
  case tgtok::XAND:
  case tgtok::XOR:
  case tgtok::XXOR:
  case tgtok::XSRA:
  case tgtok::XSRL:
  case tgtok::XSHL:
  case tgtok::XEq:
  case tgtok::XNe:
  case tgtok::XLe:
  case tgtok::XLt:
  case tgtok::XGe:
  case tgtok::XGt:
  case tgtok::XListConcat:
  case tgtok::XListSplat:
  case tgtok::XStrConcat:
  case tgtok::XInterleave:
  case tgtok::XSetDagOp: { // Value ::= !binop '(' Value ',' Value ')'
    tgtok::TokKind OpTok = Lex.getCode();
    SMLoc OpLoc = Lex.getLoc();
    Lex.Lex();  // eat the operation

    BinOpInit::BinaryOp Code;
    switch (OpTok) {
    default: llvm_unreachable("Unhandled code!");
    case tgtok::XConcat: Code = BinOpInit::CONCAT; break;
    case tgtok::XADD:    Code = BinOpInit::ADD; break;
    case tgtok::XSUB:    Code = BinOpInit::SUB; break;
    case tgtok::XMUL:    Code = BinOpInit::MUL; break;
    case tgtok::XAND:    Code = BinOpInit::AND; break;
    case tgtok::XOR:     Code = BinOpInit::OR; break;
    case tgtok::XXOR:    Code = BinOpInit::XOR; break;
    case tgtok::XSRA:    Code = BinOpInit::SRA; break;
    case tgtok::XSRL:    Code = BinOpInit::SRL; break;
    case tgtok::XSHL:    Code = BinOpInit::SHL; break;
    case tgtok::XEq:     Code = BinOpInit::EQ; break;
    case tgtok::XNe:     Code = BinOpInit::NE; break;
    case tgtok::XLe:     Code = BinOpInit::LE; break;
    case tgtok::XLt:     Code = BinOpInit::LT; break;
    case tgtok::XGe:     Code = BinOpInit::GE; break;
    case tgtok::XGt:     Code = BinOpInit::GT; break;
    case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
    case tgtok::XListSplat:  Code = BinOpInit::LISTSPLAT; break;
    case tgtok::XStrConcat:  Code = BinOpInit::STRCONCAT; break;
    case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break;
    case tgtok::XSetDagOp:   Code = BinOpInit::SETDAGOP; break;
    }

    RecTy *Type = nullptr;
    RecTy *ArgType = nullptr;
    switch (OpTok) {
    default:
      llvm_unreachable("Unhandled code!");
    case tgtok::XConcat:
    case tgtok::XSetDagOp:
      Type = DagRecTy::get();
      ArgType = DagRecTy::get();
      break;
    case tgtok::XAND:
    case tgtok::XOR:
    case tgtok::XXOR:
    case tgtok::XSRA:
    case tgtok::XSRL:
    case tgtok::XSHL:
    case tgtok::XADD:
    case tgtok::XSUB:
    case tgtok::XMUL:
      Type = IntRecTy::get();
      ArgType = IntRecTy::get();
      break;
    case tgtok::XEq:
    case tgtok::XNe:
    case tgtok::XLe:
    case tgtok::XLt:
    case tgtok::XGe:
    case tgtok::XGt:
      Type = BitRecTy::get();
      // ArgType for the comparison operators is not yet known.
      break;
    case tgtok::XListConcat:
      // We don't know the list type until we parse the first argument
      ArgType = ItemType;
      break;
    case tgtok::XListSplat:
      // Can't do any typechecking until we parse the first argument.
      break;
    case tgtok::XStrConcat:
      Type = StringRecTy::get();
      ArgType = StringRecTy::get();
      break;
    case tgtok::XInterleave:
      Type = StringRecTy::get();
      // The first argument type is not yet known.
    }

    if (Type && ItemType && !Type->typeIsConvertibleTo(ItemType)) {
      Error(OpLoc, Twine("expected value of type '") +
                   ItemType->getAsString() + "', got '" +
                   Type->getAsString() + "'");
      return nullptr;
    }

    if (!consume(tgtok::l_paren)) {
      TokError("expected '(' after binary operator");
      return nullptr;
    }

    SmallVector<Init*, 2> InitList;

    // Note that this loop consumes an arbitrary number of arguments.
    // The actual count is checked later.
    for (;;) {
      SMLoc InitLoc = Lex.getLoc();
      InitList.push_back(ParseValue(CurRec, ArgType));
      if (!InitList.back()) return nullptr;

      TypedInit *InitListBack = dyn_cast<TypedInit>(InitList.back());
      if (!InitListBack) {
        Error(OpLoc, Twine("expected value to be a typed value, got '" +
                           InitList.back()->getAsString() + "'"));
        return nullptr;
      }
      RecTy *ListType = InitListBack->getType();

      if (!ArgType) {
        // Argument type must be determined from the argument itself.
        ArgType = ListType;

        switch (Code) {
        case BinOpInit::LISTCONCAT:
          if (!isa<ListRecTy>(ArgType)) {
            Error(InitLoc, Twine("expected a list, got value of type '") +
                           ArgType->getAsString() + "'");
            return nullptr;
          }
          break;
        case BinOpInit::LISTSPLAT:
          if (ItemType && InitList.size() == 1) {
            if (!isa<ListRecTy>(ItemType)) {
              Error(OpLoc,
                    Twine("expected output type to be a list, got type '") +
                        ItemType->getAsString() + "'");
              return nullptr;
            }
            if (!ArgType->getListTy()->typeIsConvertibleTo(ItemType)) {
              Error(OpLoc, Twine("expected first arg type to be '") +
                               ArgType->getAsString() +
                               "', got value of type '" +
                               cast<ListRecTy>(ItemType)
                                   ->getElementType()
                                   ->getAsString() +
                               "'");
              return nullptr;
            }
          }
          if (InitList.size() == 2 && !isa<IntRecTy>(ArgType)) {
            Error(InitLoc, Twine("expected second parameter to be an int, got "
                                 "value of type '") +
                               ArgType->getAsString() + "'");
            return nullptr;
          }
          ArgType = nullptr; // Broken invariant: types not identical.
          break;
        case BinOpInit::EQ:
        case BinOpInit::NE:
          if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) &&
              !ArgType->typeIsConvertibleTo(StringRecTy::get()) &&
              !ArgType->typeIsConvertibleTo(RecordRecTy::get({}))) {
            Error(InitLoc, Twine("expected bit, bits, int, string, or record; "
                                 "got value of type '") + ArgType->getAsString() + 
                                 "'");
            return nullptr;
          }
          break;
        case BinOpInit::LE:
        case BinOpInit::LT:
        case BinOpInit::GE:
        case BinOpInit::GT:
          if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) &&
              !ArgType->typeIsConvertibleTo(StringRecTy::get())) {
            Error(InitLoc, Twine("expected bit, bits, int, or string; "
                                 "got value of type '") + ArgType->getAsString() + 
                                 "'");
            return nullptr;
          }
          break;
        case BinOpInit::INTERLEAVE:
          switch (InitList.size()) {
          case 1: // First argument must be a list of strings or integers.
            if (ArgType != StringRecTy::get()->getListTy() &&
                !ArgType->typeIsConvertibleTo(IntRecTy::get()->getListTy())) {
              Error(InitLoc, Twine("expected list of string, int, bits, or bit; "
                                   "got value of type '") +
                                   ArgType->getAsString() + "'");
              return nullptr;
            }
            break;
          case 2: // Second argument must be a string.
            if (!isa<StringRecTy>(ArgType)) {
              Error(InitLoc, Twine("expected second argument to be a string, "
                                   "got value of type '") +
                                 ArgType->getAsString() + "'");
              return nullptr;
            }
            break;
          default: ;
          }
          ArgType = nullptr; // Broken invariant: types not identical.
          break;
        default: llvm_unreachable("other ops have fixed argument types");
        }

      } else {
        // Desired argument type is a known and in ArgType.
        RecTy *Resolved = resolveTypes(ArgType, ListType);
        if (!Resolved) {
          Error(InitLoc, Twine("expected value of type '") +
                             ArgType->getAsString() + "', got '" +
                             ListType->getAsString() + "'");
          return nullptr;
        }
        if (Code != BinOpInit::ADD && Code != BinOpInit::SUB &&
            Code != BinOpInit::AND && Code != BinOpInit::OR &&
            Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
            Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
            Code != BinOpInit::MUL)
          ArgType = Resolved;
      }

      // Deal with BinOps whose arguments have different types, by
      // rewriting ArgType in between them.
      switch (Code) {
        case BinOpInit::SETDAGOP:
          // After parsing the first dag argument, switch to expecting
          // a record, with no restriction on its superclasses.
          ArgType = RecordRecTy::get({});
          break;
        default:
          break;
      }

      if (!consume(tgtok::comma))
        break;
    }

    if (!consume(tgtok::r_paren)) {
      TokError("expected ')' in operator");
      return nullptr;
    }

    // listconcat returns a list with type of the argument.
    if (Code == BinOpInit::LISTCONCAT)
      Type = ArgType;
    // listsplat returns a list of type of the *first* argument.
    if (Code == BinOpInit::LISTSPLAT)
      Type = cast<TypedInit>(InitList.front())->getType()->getListTy();

    // We allow multiple operands to associative operators like !strconcat as
    // shorthand for nesting them.
    if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT ||
        Code == BinOpInit::CONCAT || Code == BinOpInit::ADD ||
        Code == BinOpInit::AND || Code == BinOpInit::OR ||
        Code == BinOpInit::XOR || Code == BinOpInit::MUL) {
      while (InitList.size() > 2) {
        Init *RHS = InitList.pop_back_val();
        RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec);
        InitList.back() = RHS;
      }
    }

    if (InitList.size() == 2)
      return (BinOpInit::get(Code, InitList[0], InitList[1], Type))
          ->Fold(CurRec);

    Error(OpLoc, "expected two operands to operator");
    return nullptr;
  }

  case tgtok::XForEach:
  case tgtok::XFilter: {
    return ParseOperationForEachFilter(CurRec, ItemType);
  }

  case tgtok::XDag:
  case tgtok::XIf:
  case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
    TernOpInit::TernaryOp Code;
    RecTy *Type = nullptr;

    tgtok::TokKind LexCode = Lex.getCode();
    Lex.Lex();  // eat the operation
    switch (LexCode) {
    default: llvm_unreachable("Unhandled code!");
    case tgtok::XDag:
      Code = TernOpInit::DAG;
      Type = DagRecTy::get();
      ItemType = nullptr;
      break;
    case tgtok::XIf:
      Code = TernOpInit::IF;
      break;
    case tgtok::XSubst:
      Code = TernOpInit::SUBST;
      break;
    }
    if (!consume(tgtok::l_paren)) {
      TokError("expected '(' after ternary operator");
      return nullptr;
    }

    Init *LHS = ParseValue(CurRec);
    if (!LHS) return nullptr;

    if (!consume(tgtok::comma)) {
      TokError("expected ',' in ternary operator");
      return nullptr;
    }

    SMLoc MHSLoc = Lex.getLoc();
    Init *MHS = ParseValue(CurRec, ItemType);
    if (!MHS)
      return nullptr;

    if (!consume(tgtok::comma)) {
      TokError("expected ',' in ternary operator");
      return nullptr;
    }

    SMLoc RHSLoc = Lex.getLoc();
    Init *RHS = ParseValue(CurRec, ItemType);
    if (!RHS)
      return nullptr;

    if (!consume(tgtok::r_paren)) {
      TokError("expected ')' in binary operator");
      return nullptr;
    }

    switch (LexCode) {
    default: llvm_unreachable("Unhandled code!");
    case tgtok::XDag: {
      TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
      if (!MHSt && !isa<UnsetInit>(MHS)) {
        Error(MHSLoc, "could not determine type of the child list in !dag");
        return nullptr;
      }
      if (MHSt && !isa<ListRecTy>(MHSt->getType())) {
        Error(MHSLoc, Twine("expected list of children, got type '") +
                          MHSt->getType()->getAsString() + "'");
        return nullptr;
      }

      TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
      if (!RHSt && !isa<UnsetInit>(RHS)) {
        Error(RHSLoc, "could not determine type of the name list in !dag");
        return nullptr;
      }
      if (RHSt && StringRecTy::get()->getListTy() != RHSt->getType()) {
        Error(RHSLoc, Twine("expected list<string>, got type '") +
                          RHSt->getType()->getAsString() + "'");
        return nullptr;
      }

      if (!MHSt && !RHSt) {
        Error(MHSLoc,
              "cannot have both unset children and unset names in !dag");
        return nullptr;
      }
      break;
    }
    case tgtok::XIf: {
      RecTy *MHSTy = nullptr;
      RecTy *RHSTy = nullptr;

      if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
        MHSTy = MHSt->getType();
      if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS))
        MHSTy = BitsRecTy::get(MHSbits->getNumBits());
      if (isa<BitInit>(MHS))
        MHSTy = BitRecTy::get();

      if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS))
        RHSTy = RHSt->getType();
      if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS))
        RHSTy = BitsRecTy::get(RHSbits->getNumBits());
      if (isa<BitInit>(RHS))
        RHSTy = BitRecTy::get();

      // For UnsetInit, it's typed from the other hand.
      if (isa<UnsetInit>(MHS))
        MHSTy = RHSTy;
      if (isa<UnsetInit>(RHS))
        RHSTy = MHSTy;

      if (!MHSTy || !RHSTy) {
        TokError("could not get type for !if");
        return nullptr;
      }

      Type = resolveTypes(MHSTy, RHSTy);
      if (!Type) {
        TokError(Twine("inconsistent types '") + MHSTy->getAsString() +
                 "' and '" + RHSTy->getAsString() + "' for !if");
        return nullptr;
      }
      break;
    }
    case tgtok::XSubst: {
      TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
      if (!RHSt) {
        TokError("could not get type for !subst");
        return nullptr;
      }
      Type = RHSt->getType();
      break;
    }
    }
    return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
  }

  case tgtok::XSubstr:
    return ParseOperationSubstr(CurRec, ItemType);

  case tgtok::XFind:
    return ParseOperationFind(CurRec, ItemType);

  case tgtok::XCond:
    return ParseOperationCond(CurRec, ItemType);

  case tgtok::XFoldl: {
    // Value ::= !foldl '(' Value ',' Value ',' Id ',' Id ',' Expr ')'
    Lex.Lex(); // eat the operation
    if (!consume(tgtok::l_paren)) {
      TokError("expected '(' after !foldl");
      return nullptr;
    }

    Init *StartUntyped = ParseValue(CurRec);
    if (!StartUntyped)
      return nullptr;

    TypedInit *Start = dyn_cast<TypedInit>(StartUntyped);
    if (!Start) {
      TokError(Twine("could not get type of !foldl start: '") +
               StartUntyped->getAsString() + "'");
      return nullptr;
    }

    if (!consume(tgtok::comma)) {
      TokError("expected ',' in !foldl");
      return nullptr;
    }

    Init *ListUntyped = ParseValue(CurRec);
    if (!ListUntyped)
      return nullptr;

    TypedInit *List = dyn_cast<TypedInit>(ListUntyped);
    if (!List) {
      TokError(Twine("could not get type of !foldl list: '") +
               ListUntyped->getAsString() + "'");
      return nullptr;
    }

    ListRecTy *ListType = dyn_cast<ListRecTy>(List->getType());
    if (!ListType) {
      TokError(Twine("!foldl list must be a list, but is of type '") +
               List->getType()->getAsString());
      return nullptr;
    }

    if (Lex.getCode() != tgtok::comma) {
      TokError("expected ',' in !foldl");
      return nullptr;
    }

    if (Lex.Lex() != tgtok::Id) { // eat the ','
      TokError("third argument of !foldl must be an identifier");
      return nullptr;
    }

    Init *A = StringInit::get(Lex.getCurStrVal());
    if (CurRec && CurRec->getValue(A)) {
      TokError((Twine("left !foldl variable '") + A->getAsString() +
                "' already defined")
                   .str());
      return nullptr;
    }

    if (Lex.Lex() != tgtok::comma) { // eat the id
      TokError("expected ',' in !foldl");
      return nullptr;
    }

    if (Lex.Lex() != tgtok::Id) { // eat the ','
      TokError("fourth argument of !foldl must be an identifier");
      return nullptr;
    }

    Init *B = StringInit::get(Lex.getCurStrVal());
    if (CurRec && CurRec->getValue(B)) {
      TokError((Twine("right !foldl variable '") + B->getAsString() +
                "' already defined")
                   .str());
      return nullptr;
    }

    if (Lex.Lex() != tgtok::comma) { // eat the id
      TokError("expected ',' in !foldl");
      return nullptr;
    }
    Lex.Lex(); // eat the ','

    // We need to create a temporary record to provide a scope for the
    // two variables.
    std::unique_ptr<Record> ParseRecTmp;
    Record *ParseRec = CurRec;
    if (!ParseRec) {
      ParseRecTmp = std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);
      ParseRec = ParseRecTmp.get();
    }

    ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal));
    ParseRec->addValue(RecordVal(B, ListType->getElementType(),
                                 RecordVal::FK_Normal));
    Init *ExprUntyped = ParseValue(ParseRec);
    ParseRec->removeValue(A);
    ParseRec->removeValue(B);
    if (!ExprUntyped)
      return nullptr;

    TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped);
    if (!Expr) {
      TokError("could not get type of !foldl expression");
      return nullptr;
    }

    if (Expr->getType() != Start->getType()) {
      TokError(Twine("!foldl expression must be of same type as start (") +
               Start->getType()->getAsString() + "), but is of type " +
               Expr->getType()->getAsString());
      return nullptr;
    }

    if (!consume(tgtok::r_paren)) {
      TokError("expected ')' in fold operator");
      return nullptr;
    }

    return FoldOpInit::get(Start, List, A, B, Expr, Start->getType())
        ->Fold(CurRec);
  }
  }
}

/// ParseOperatorType - Parse a type for an operator.  This returns
/// null on error.
///
/// OperatorType ::= '<' Type '>'
///
RecTy *TGParser::ParseOperatorType() {
  RecTy *Type = nullptr;

  if (!consume(tgtok::less)) {
    TokError("expected type name for operator");
    return nullptr;
  }

  if (Lex.getCode() == tgtok::Code)
    TokError("the 'code' type is not allowed in bang operators; use 'string'");

  Type = ParseType();

  if (!Type) {
    TokError("expected type name for operator");
    return nullptr;
  }

  if (!consume(tgtok::greater)) {
    TokError("expected type name for operator");
    return nullptr;
  }

  return Type;
}

/// Parse the !substr operation. Return null on error.
///
/// Substr ::= !substr(string, start-int [, length-int]) => string
Init *TGParser::ParseOperationSubstr(Record *CurRec, RecTy *ItemType) {
  TernOpInit::TernaryOp Code = TernOpInit::SUBSTR;
  RecTy *Type = StringRecTy::get();

  Lex.Lex(); // eat the operation

  if (!consume(tgtok::l_paren)) {
    TokError("expected '(' after !substr operator");
    return nullptr;
  }

  Init *LHS = ParseValue(CurRec);
  if (!LHS)
    return nullptr;

  if (!consume(tgtok::comma)) {
    TokError("expected ',' in !substr operator");
    return nullptr;
  }

  SMLoc MHSLoc = Lex.getLoc();
  Init *MHS = ParseValue(CurRec);
  if (!MHS)
    return nullptr;

  SMLoc RHSLoc = Lex.getLoc();
  Init *RHS;
  if (consume(tgtok::comma)) {
    RHSLoc = Lex.getLoc();
    RHS = ParseValue(CurRec);
    if (!RHS)
      return nullptr;
  } else {
    RHS = IntInit::get(std::numeric_limits<int64_t>::max());
  }

  if (!consume(tgtok::r_paren)) {
    TokError("expected ')' in !substr operator");
    return nullptr;
  }

  if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {
    Error(RHSLoc, Twine("expected value of type '") +
                  ItemType->getAsString() + "', got '" +
                  Type->getAsString() + "'");
  }

  TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
  if (!LHSt && !isa<UnsetInit>(LHS)) {
    TokError("could not determine type of the string in !substr");
    return nullptr;
  }
  if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
    TokError(Twine("expected string, got type '") +
             LHSt->getType()->getAsString() + "'");
    return nullptr;
  }

  TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
  if (!MHSt && !isa<UnsetInit>(MHS)) {
    TokError("could not determine type of the start position in !substr");
    return nullptr;
  }
  if (MHSt && !isa<IntRecTy>(MHSt->getType())) {
    Error(MHSLoc, Twine("expected int, got type '") +
                      MHSt->getType()->getAsString() + "'");
    return nullptr;
  }

  if (RHS) {
    TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
    if (!RHSt && !isa<UnsetInit>(RHS)) {
      TokError("could not determine type of the length in !substr");
      return nullptr;
    }
    if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
      TokError(Twine("expected int, got type '") +
               RHSt->getType()->getAsString() + "'");
      return nullptr;
    }
  }

  return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
}

/// Parse the !find operation. Return null on error.
///
/// Substr ::= !find(string, string [, start-int]) => int
Init *TGParser::ParseOperationFind(Record *CurRec, RecTy *ItemType) {
  TernOpInit::TernaryOp Code = TernOpInit::FIND;
  RecTy *Type = IntRecTy::get();

  Lex.Lex(); // eat the operation

  if (!consume(tgtok::l_paren)) {
    TokError("expected '(' after !find operator");
    return nullptr;
  }

  Init *LHS = ParseValue(CurRec);
  if (!LHS)
    return nullptr;

  if (!consume(tgtok::comma)) {
    TokError("expected ',' in !find operator");
    return nullptr;
  }

  SMLoc MHSLoc = Lex.getLoc();
  Init *MHS = ParseValue(CurRec);
  if (!MHS)
    return nullptr;

  SMLoc RHSLoc = Lex.getLoc();
  Init *RHS;
  if (consume(tgtok::comma)) {
    RHSLoc = Lex.getLoc();
    RHS = ParseValue(CurRec);
    if (!RHS)
      return nullptr;
  } else {
    RHS = IntInit::get(0);
  }

  if (!consume(tgtok::r_paren)) {
    TokError("expected ')' in !find operator");
    return nullptr;
  }

  if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {
    Error(RHSLoc, Twine("expected value of type '") +
                  ItemType->getAsString() + "', got '" +
                  Type->getAsString() + "'");
  }

  TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
  if (!LHSt && !isa<UnsetInit>(LHS)) {
    TokError("could not determine type of the source string in !find");
    return nullptr;
  }
  if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
    TokError(Twine("expected string, got type '") +
             LHSt->getType()->getAsString() + "'");
    return nullptr;
  }

  TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
  if (!MHSt && !isa<UnsetInit>(MHS)) {
    TokError("could not determine type of the target string in !find");
    return nullptr;
  }
  if (MHSt && !isa<StringRecTy>(MHSt->getType())) {
    Error(MHSLoc, Twine("expected string, got type '") +
                      MHSt->getType()->getAsString() + "'");
    return nullptr;
  }

  if (RHS) {
    TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
    if (!RHSt && !isa<UnsetInit>(RHS)) {
      TokError("could not determine type of the start position in !find");
      return nullptr;
    }
    if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
      TokError(Twine("expected int, got type '") +
               RHSt->getType()->getAsString() + "'");
      return nullptr;
    }
  }

  return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
}

/// Parse the !foreach and !filter operations. Return null on error.
///
/// ForEach ::= !foreach(ID, list-or-dag, expr) => list<expr type>
/// Filter  ::= !foreach(ID, list, predicate) ==> list<list type>
Init *TGParser::ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType) { 
  SMLoc OpLoc = Lex.getLoc();
  tgtok::TokKind Operation = Lex.getCode();
  Lex.Lex(); // eat the operation
  if (Lex.getCode() != tgtok::l_paren) {
    TokError("expected '(' after !foreach/!filter");
    return nullptr;
  }

  if (Lex.Lex() != tgtok::Id) { // eat the '('
    TokError("first argument of !foreach/!filter must be an identifier");
    return nullptr;
  }

  Init *LHS = StringInit::get(Lex.getCurStrVal());
  Lex.Lex(); // eat the ID.

  if (CurRec && CurRec->getValue(LHS)) {
    TokError((Twine("iteration variable '") + LHS->getAsString() +
              "' is already defined")
                 .str());
    return nullptr;
  }

  if (!consume(tgtok::comma)) {
    TokError("expected ',' in !foreach/!filter");
    return nullptr;
  }

  Init *MHS = ParseValue(CurRec);
  if (!MHS)
    return nullptr;

  if (!consume(tgtok::comma)) {
    TokError("expected ',' in !foreach/!filter");
    return nullptr;
  }

  TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
  if (!MHSt) {
    TokError("could not get type of !foreach/!filter list or dag");
    return nullptr;
  }

  RecTy *InEltType = nullptr;
  RecTy *ExprEltType = nullptr;
  bool IsDAG = false;

  if (ListRecTy *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) {
    InEltType = InListTy->getElementType();
    if (ItemType) {
      if (ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) {
        ExprEltType = (Operation == tgtok::XForEach)
                          ? OutListTy->getElementType()
                          : IntRecTy::get();
      } else {
        Error(OpLoc,
              "expected value of type '" +
                  Twine(ItemType->getAsString()) +
                  "', but got list type");
        return nullptr;
      }
    }
  } else if (DagRecTy *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) {
    if (Operation == tgtok::XFilter) {
      TokError("!filter must have a list argument");
      return nullptr;
    }
    InEltType = InDagTy;
    if (ItemType && !isa<DagRecTy>(ItemType)) {
      Error(OpLoc,
            "expected value of type '" + Twine(ItemType->getAsString()) +
                "', but got dag type");
      return nullptr;
    }
    IsDAG = true;
  } else {
    if (Operation == tgtok::XForEach)
      TokError("!foreach must have a list or dag argument");
    else
      TokError("!filter must have a list argument");
    return nullptr;
  }

  // We need to create a temporary record to provide a scope for the
  // iteration variable.
  std::unique_ptr<Record> ParseRecTmp;
  Record *ParseRec = CurRec;
  if (!ParseRec) {
    ParseRecTmp =
        std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);
    ParseRec = ParseRecTmp.get();
  }

  ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal));
  Init *RHS = ParseValue(ParseRec, ExprEltType);
  ParseRec->removeValue(LHS);
  if (!RHS)
    return nullptr;

  if (!consume(tgtok::r_paren)) {
    TokError("expected ')' in !foreach/!filter");
    return nullptr;
  }

  RecTy *OutType = InEltType;
  if (Operation == tgtok::XForEach && !IsDAG) {
    TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
    if (!RHSt) {
      TokError("could not get type of !foreach result expression");
      return nullptr;
    }
    OutType = RHSt->getType()->getListTy();
  } else if (Operation == tgtok::XFilter) {
    OutType = InEltType->getListTy();
  }    

  return (TernOpInit::get((Operation == tgtok::XForEach) ? TernOpInit::FOREACH
                                                         : TernOpInit::FILTER,
                          LHS, MHS, RHS, OutType))
      ->Fold(CurRec);
}

Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
  Lex.Lex();  // eat the operation 'cond'

  if (!consume(tgtok::l_paren)) {
    TokError("expected '(' after !cond operator");
    return nullptr;
  }

  // Parse through '[Case: Val,]+'
  SmallVector<Init *, 4> Case;
  SmallVector<Init *, 4> Val;
  while (true) {
    if (consume(tgtok::r_paren))
      break;

    Init *V = ParseValue(CurRec);
    if (!V)
      return nullptr;
    Case.push_back(V);

    if (!consume(tgtok::colon)) {
      TokError("expected ':'  following a condition in !cond operator");
      return nullptr;
    }

    V = ParseValue(CurRec, ItemType);
    if (!V)
      return nullptr;
    Val.push_back(V);

    if (consume(tgtok::r_paren))
      break;

    if (!consume(tgtok::comma)) {
      TokError("expected ',' or ')' following a value in !cond operator");
      return nullptr;
    }
  }

  if (Case.size() < 1) {
    TokError("there should be at least 1 'condition : value' in the !cond operator");
    return nullptr;
  }

  // resolve type
  RecTy *Type = nullptr;
  for (Init *V : Val) {
    RecTy *VTy = nullptr;
    if (TypedInit *Vt = dyn_cast<TypedInit>(V))
      VTy = Vt->getType();
    if (BitsInit *Vbits = dyn_cast<BitsInit>(V))
      VTy = BitsRecTy::get(Vbits->getNumBits());
    if (isa<BitInit>(V))
      VTy = BitRecTy::get();

    if (Type == nullptr) {
      if (!isa<UnsetInit>(V))
        Type = VTy;
    } else {
      if (!isa<UnsetInit>(V)) {
        RecTy *RType = resolveTypes(Type, VTy);
        if (!RType) {
          TokError(Twine("inconsistent types '") + Type->getAsString() +
                         "' and '" + VTy->getAsString() + "' for !cond");
          return nullptr;
        }
        Type = RType;
      }
    }
  }

  if (!Type) {
    TokError("could not determine type for !cond from its arguments");
    return nullptr;
  }
  return CondOpInit::get(Case, Val, Type)->Fold(CurRec);
}

/// ParseSimpleValue - Parse a tblgen value.  This returns null on error.
///
///   SimpleValue ::= IDValue
///   SimpleValue ::= INTVAL
///   SimpleValue ::= STRVAL+
///   SimpleValue ::= CODEFRAGMENT
///   SimpleValue ::= '?'
///   SimpleValue ::= '{' ValueList '}'
///   SimpleValue ::= ID '<' ValueListNE '>'
///   SimpleValue ::= '[' ValueList ']'
///   SimpleValue ::= '(' IDValue DagArgList ')'
///   SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
///   SimpleValue ::= ADDTOK '(' Value ',' Value ')'
///   SimpleValue ::= SUBTOK '(' Value ',' Value ')'
///   SimpleValue ::= SHLTOK '(' Value ',' Value ')'
///   SimpleValue ::= SRATOK '(' Value ',' Value ')'
///   SimpleValue ::= SRLTOK '(' Value ',' Value ')'
///   SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
///   SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')'
///   SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
///   SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
///
Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
                                 IDParseMode Mode) {
  Init *R = nullptr;
  switch (Lex.getCode()) {
  default: TokError("Unknown or reserved token when parsing a value"); break;

  case tgtok::TrueVal:
    R = IntInit::get(1);
    Lex.Lex();
    break;
  case tgtok::FalseVal:
    R = IntInit::get(0);
    Lex.Lex();
    break;
  case tgtok::IntVal:
    R = IntInit::get(Lex.getCurIntVal());
    Lex.Lex();
    break;
  case tgtok::BinaryIntVal: {
    auto BinaryVal = Lex.getCurBinaryIntVal();
    SmallVector<Init*, 16> Bits(BinaryVal.second);
    for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)
      Bits[i] = BitInit::get(BinaryVal.first & (1LL << i));
    R = BitsInit::get(Bits);
    Lex.Lex();
    break;
  }
  case tgtok::StrVal: {
    std::string Val = Lex.getCurStrVal();
    Lex.Lex();

    // Handle multiple consecutive concatenated strings.
    while (Lex.getCode() == tgtok::StrVal) {
      Val += Lex.getCurStrVal();
      Lex.Lex();
    }

    R = StringInit::get(Val);
    break;
  }
  case tgtok::CodeFragment:
    R = StringInit::get(Lex.getCurStrVal(), StringInit::SF_Code);
    Lex.Lex();
    break;
  case tgtok::question:
    R = UnsetInit::get();
    Lex.Lex();
    break;
  case tgtok::Id: {
    SMLoc NameLoc = Lex.getLoc();
    StringInit *Name = StringInit::get(Lex.getCurStrVal());
    if (Lex.Lex() != tgtok::less)  // consume the Id.
      return ParseIDValue(CurRec, Name, NameLoc, Mode);    // Value ::= IDValue

    // Value ::= CLASSID '<' ValueListNE '>' (CLASSID has been consumed)
    // This is supposed to synthesize a new anonymous definition, deriving
    // from the class with the template arguments, but no body.
    Record *Class = Records.getClass(Name->getValue());
    if (!Class) {
      Error(NameLoc, "Expected a class name, got '" + Name->getValue() + "'");
      return nullptr;
    }

    SmallVector<Init *, 8> Args;
    Lex.Lex(); // consume the <
    if (ParseTemplateArgValueList(Args, CurRec, Class))
      return nullptr; // Error parsing value list.

    if (CheckTemplateArgValues(Args, NameLoc, Class))
      return nullptr; // Error checking template argument values.

    // Loop through the arguments that were not specified and make sure
    // they have a complete value.
    ArrayRef<Init *> TArgs = Class->getTemplateArgs();
    for (unsigned I = Args.size(), E = TArgs.size(); I < E; ++I) {
      RecordVal *Arg = Class->getValue(TArgs[I]);
      if (!Arg->getValue()->isComplete()) 
        Error(NameLoc, "Value not specified for template argument '" +
                           TArgs[I]->getAsUnquotedString() + "' (#" + Twine(I) +
                           ") of parent class '" +
                           Class->getNameInitAsString() + "'");
              
    }

    return VarDefInit::get(Class, Args)->Fold();
  }
  case tgtok::l_brace: {           // Value ::= '{' ValueList '}'
    SMLoc BraceLoc = Lex.getLoc();
    Lex.Lex(); // eat the '{'
    SmallVector<Init*, 16> Vals;

    if (Lex.getCode() != tgtok::r_brace) {
      ParseValueList(Vals, CurRec);
      if (Vals.empty()) return nullptr;
    }
    if (!consume(tgtok::r_brace)) {
      TokError("expected '}' at end of bit list value");
      return nullptr;
    }

    SmallVector<Init *, 16> NewBits;

    // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it
    // first.  We'll first read everything in to a vector, then we can reverse
    // it to get the bits in the correct order for the BitsInit value.
    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
      // FIXME: The following two loops would not be duplicated
      //        if the API was a little more orthogonal.

      // bits<n> values are allowed to initialize n bits.
      if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) {
        for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
          NewBits.push_back(BI->getBit((e - i) - 1));
        continue;
      }
      // bits<n> can also come from variable initializers.
      if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) {
        if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) {
          for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
            NewBits.push_back(VI->getBit((e - i) - 1));
          continue;
        }
        // Fallthrough to try convert this to a bit.
      }
      // All other values must be convertible to just a single bit.
      Init *Bit = Vals[i]->getCastTo(BitRecTy::get());
      if (!Bit) {
        Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
              ") is not convertable to a bit");
        return nullptr;
      }
      NewBits.push_back(Bit);
    }
    std::reverse(NewBits.begin(), NewBits.end());
    return BitsInit::get(NewBits);
  }
  case tgtok::l_square: {          // Value ::= '[' ValueList ']'
    Lex.Lex(); // eat the '['
    SmallVector<Init*, 16> Vals;

    RecTy *DeducedEltTy = nullptr;
    ListRecTy *GivenListTy = nullptr;

    if (ItemType) {
      ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
      if (!ListType) {
        TokError(Twine("Encountered a list when expecting a ") +
                 ItemType->getAsString());
        return nullptr;
      }
      GivenListTy = ListType;
    }

    if (Lex.getCode() != tgtok::r_square) {
      ParseValueList(Vals, CurRec,
                     GivenListTy ? GivenListTy->getElementType() : nullptr);
      if (Vals.empty()) return nullptr;
    }
    if (!consume(tgtok::r_square)) {
      TokError("expected ']' at end of list value");
      return nullptr;
    }

    RecTy *GivenEltTy = nullptr;
    if (consume(tgtok::less)) {
      // Optional list element type
      GivenEltTy = ParseType();
      if (!GivenEltTy) {
        // Couldn't parse element type
        return nullptr;
      }

      if (!consume(tgtok::greater)) {
        TokError("expected '>' at end of list element type");
        return nullptr;
      }
    }

    // Check elements
    RecTy *EltTy = nullptr;
    for (Init *V : Vals) {
      TypedInit *TArg = dyn_cast<TypedInit>(V);
      if (TArg) {
        if (EltTy) {
          EltTy = resolveTypes(EltTy, TArg->getType());
          if (!EltTy) {
            TokError("Incompatible types in list elements");
            return nullptr;
          }
        } else {
          EltTy = TArg->getType();
        }
      }
    }

    if (GivenEltTy) {
      if (EltTy) {
        // Verify consistency
        if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
          TokError("Incompatible types in list elements");
          return nullptr;
        }
      }
      EltTy = GivenEltTy;
    }

    if (!EltTy) {
      if (!ItemType) {
        TokError("No type for list");
        return nullptr;
      }
      DeducedEltTy = GivenListTy->getElementType();
    } else {
      // Make sure the deduced type is compatible with the given type
      if (GivenListTy) {
        if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
          TokError(Twine("Element type mismatch for list: element type '") +
                   EltTy->getAsString() + "' not convertible to '" +
                   GivenListTy->getElementType()->getAsString());
          return nullptr;
        }
      }
      DeducedEltTy = EltTy;
    }

    return ListInit::get(Vals, DeducedEltTy);
  }
  case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
    Lex.Lex();   // eat the '('
    if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&
        Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp) {
      TokError("expected identifier in dag init");
      return nullptr;
    }

    Init *Operator = ParseValue(CurRec);
    if (!Operator) return nullptr;

    // If the operator name is present, parse it.
    StringInit *OperatorName = nullptr;
    if (consume(tgtok::colon)) {
      if (Lex.getCode() != tgtok::VarName) { // eat the ':'
        TokError("expected variable name in dag operator");
        return nullptr;
      }
      OperatorName = StringInit::get(Lex.getCurStrVal());
      Lex.Lex();  // eat the VarName.
    }

    SmallVector<std::pair<llvm::Init*, StringInit*>, 8> DagArgs;
    if (Lex.getCode() != tgtok::r_paren) {
      ParseDagArgList(DagArgs, CurRec);
      if (DagArgs.empty()) return nullptr;
    }

    if (!consume(tgtok::r_paren)) {
      TokError("expected ')' in dag init");
      return nullptr;
    }

    return DagInit::get(Operator, OperatorName, DagArgs);
  }

  case tgtok::XHead:
  case tgtok::XTail:
  case tgtok::XSize:
  case tgtok::XEmpty:
  case tgtok::XCast:
  case tgtok::XGetDagOp: // Value ::= !unop '(' Value ')'
  case tgtok::XIsA:
  case tgtok::XConcat:
  case tgtok::XDag:
  case tgtok::XADD:
  case tgtok::XSUB:
  case tgtok::XMUL:
  case tgtok::XNOT:
  case tgtok::XAND:
  case tgtok::XOR:
  case tgtok::XXOR:
  case tgtok::XSRA:
  case tgtok::XSRL:
  case tgtok::XSHL:
  case tgtok::XEq:
  case tgtok::XNe:
  case tgtok::XLe:
  case tgtok::XLt:
  case tgtok::XGe:
  case tgtok::XGt:
  case tgtok::XListConcat:
  case tgtok::XListSplat:
  case tgtok::XStrConcat:
  case tgtok::XInterleave:
  case tgtok::XSetDagOp: // Value ::= !binop '(' Value ',' Value ')'
  case tgtok::XIf:
  case tgtok::XCond:
  case tgtok::XFoldl:
  case tgtok::XForEach:
  case tgtok::XFilter:
  case tgtok::XSubst:
  case tgtok::XSubstr:
  case tgtok::XFind: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
    return ParseOperation(CurRec, ItemType);
  }
  }

  return R;
}

/// ParseValue - Parse a TableGen value. This returns null on error.
///
///   Value       ::= SimpleValue ValueSuffix*
///   ValueSuffix ::= '{' BitList '}'
///   ValueSuffix ::= '[' BitList ']'
///   ValueSuffix ::= '.' ID
///
Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
  Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
  if (!Result) return nullptr;

  // Parse the suffixes now if present.
  while (true) {
    switch (Lex.getCode()) {
    default: return Result;
    case tgtok::l_brace: {
      if (Mode == ParseNameMode)
        // This is the beginning of the object body.
        return Result;

      SMLoc CurlyLoc = Lex.getLoc();
      Lex.Lex(); // eat the '{'
      SmallVector<unsigned, 16> Ranges;
      ParseRangeList(Ranges);
      if (Ranges.empty()) return nullptr;

      // Reverse the bitlist.
      std::reverse(Ranges.begin(), Ranges.end());
      Result = Result->convertInitializerBitRange(Ranges);
      if (!Result) {
        Error(CurlyLoc, "Invalid bit range for value");
        return nullptr;
      }

      // Eat the '}'.
      if (!consume(tgtok::r_brace)) {
        TokError("expected '}' at end of bit range list");
        return nullptr;
      }
      break;
    }
    case tgtok::l_square: {
      SMLoc SquareLoc = Lex.getLoc();
      Lex.Lex(); // eat the '['
      SmallVector<unsigned, 16> Ranges;
      ParseRangeList(Ranges);
      if (Ranges.empty()) return nullptr;

      Result = Result->convertInitListSlice(Ranges);
      if (!Result) {
        Error(SquareLoc, "Invalid range for list slice");
        return nullptr;
      }

      // Eat the ']'.
      if (!consume(tgtok::r_square)) {
        TokError("expected ']' at end of list slice");
        return nullptr;
      }
      break;
    }
    case tgtok::dot: {
      if (Lex.Lex() != tgtok::Id) { // eat the .
        TokError("expected field identifier after '.'");
        return nullptr;
      }
      StringInit *FieldName = StringInit::get(Lex.getCurStrVal());
      if (!Result->getFieldType(FieldName)) {
        TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
                 Result->getAsString() + "'");
        return nullptr;
      }
      Result = FieldInit::get(Result, FieldName)->Fold(CurRec);
      Lex.Lex();  // eat field name
      break;
    }

    case tgtok::paste:
      SMLoc PasteLoc = Lex.getLoc();
      TypedInit *LHS = dyn_cast<TypedInit>(Result);
      if (!LHS) {
        Error(PasteLoc, "LHS of paste is not typed!");
        return nullptr;
      }

      // Check if it's a 'listA # listB'
      if (isa<ListRecTy>(LHS->getType())) {
        Lex.Lex();  // Eat the '#'.

        assert(Mode == ParseValueMode && "encountered paste of lists in name");

        switch (Lex.getCode()) {
        case tgtok::colon:
        case tgtok::semi:
        case tgtok::l_brace:
          Result = LHS; // trailing paste, ignore.
          break;
        default:
          Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
          if (!RHSResult)
            return nullptr;
          Result = BinOpInit::getListConcat(LHS, RHSResult);
          break;
        }
        break;
      }

      // Create a !strconcat() operation, first casting each operand to
      // a string if necessary.
      if (LHS->getType() != StringRecTy::get()) {
        auto CastLHS = dyn_cast<TypedInit>(
            UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get())
                ->Fold(CurRec));
        if (!CastLHS) {
          Error(PasteLoc,
                Twine("can't cast '") + LHS->getAsString() + "' to string");
          return nullptr;
        }
        LHS = CastLHS;
      }

      TypedInit *RHS = nullptr;

      Lex.Lex();  // Eat the '#'.
      switch (Lex.getCode()) {
      case tgtok::colon:
      case tgtok::semi:
      case tgtok::l_brace:
        // These are all of the tokens that can begin an object body.
        // Some of these can also begin values but we disallow those cases
        // because they are unlikely to be useful.

        // Trailing paste, concat with an empty string.
        RHS = StringInit::get("");
        break;

      default:
        Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
        if (!RHSResult)
          return nullptr;
        RHS = dyn_cast<TypedInit>(RHSResult);
        if (!RHS) {
          Error(PasteLoc, "RHS of paste is not typed!");
          return nullptr;
        }

        if (RHS->getType() != StringRecTy::get()) {
          auto CastRHS = dyn_cast<TypedInit>(
              UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get())
                  ->Fold(CurRec));
          if (!CastRHS) {
            Error(PasteLoc,
                  Twine("can't cast '") + RHS->getAsString() + "' to string");
            return nullptr;
          }
          RHS = CastRHS;
        }

        break;
      }

      Result = BinOpInit::getStrConcat(LHS, RHS);
      break;
    }
  }
}

/// ParseDagArgList - Parse the argument list for a dag literal expression.
///
///    DagArg     ::= Value (':' VARNAME)?
///    DagArg     ::= VARNAME
///    DagArgList ::= DagArg
///    DagArgList ::= DagArgList ',' DagArg
void TGParser::ParseDagArgList(
    SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
    Record *CurRec) {

  while (true) {
    // DagArg ::= VARNAME
    if (Lex.getCode() == tgtok::VarName) {
      // A missing value is treated like '?'.
      StringInit *VarName = StringInit::get(Lex.getCurStrVal());
      Result.emplace_back(UnsetInit::get(), VarName);
      Lex.Lex();
    } else {
      // DagArg ::= Value (':' VARNAME)?
      Init *Val = ParseValue(CurRec);
      if (!Val) {
        Result.clear();
        return;
      }

      // If the variable name is present, add it.
      StringInit *VarName = nullptr;
      if (Lex.getCode() == tgtok::colon) {
        if (Lex.Lex() != tgtok::VarName) { // eat the ':'
          TokError("expected variable name in dag literal");
          Result.clear();
          return;
        }
        VarName = StringInit::get(Lex.getCurStrVal());
        Lex.Lex();  // eat the VarName.
      }

      Result.push_back(std::make_pair(Val, VarName));
    }
    if (!consume(tgtok::comma))
      break;
  }
}

/// ParseValueList - Parse a comma separated list of values, returning them
/// in a vector. Note that this always expects to be able to parse at least one
/// value. It returns an empty list if this is not possible.
///
///   ValueList ::= Value (',' Value)
///
void TGParser::ParseValueList(SmallVectorImpl<Init *> &Result, Record *CurRec,
                              RecTy *ItemType) {

  Result.push_back(ParseValue(CurRec, ItemType));
  if (!Result.back()) {
    Result.clear();
    return;
  }

  while (consume(tgtok::comma)) {
    // ignore trailing comma for lists
    if (Lex.getCode() == tgtok::r_square)
      return;
    Result.push_back(ParseValue(CurRec, ItemType));
    if (!Result.back()) {
      Result.clear();
      return;
    }
  }
}

// ParseTemplateArgValueList - Parse a template argument list with the syntax
// shown, filling in the Result vector. The open angle has been consumed.
// An empty argument list is allowed. Return false if okay, true if an 
// error was detected.
//
//   TemplateArgList ::= '<' [Value {',' Value}*] '>'
bool TGParser::ParseTemplateArgValueList(SmallVectorImpl<Init *> &Result,
                                         Record *CurRec, Record *ArgsRec) {

  assert(Result.empty() && "Result vector is not empty");
  ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
  unsigned ArgIndex = 0;
  RecTy *ItemType;

  if (consume(tgtok::greater)) // empty value list
    return false;

  while (true) {
    if (ArgIndex >= TArgs.size()) {
      TokError("Too many template arguments: " + utostr(ArgIndex + 1));
      return true;
    }
    const RecordVal *Arg = ArgsRec->getValue(TArgs[ArgIndex]);
    assert(Arg && "Template argument record not found");

    ItemType = Arg->getType();
    Init *Value = ParseValue(CurRec, ItemType);
    if (!Value)
      return true;
    Result.push_back(Value);

    if (consume(tgtok::greater)) // end of argument list?
      return false;
    if (!consume(tgtok::comma))
      return TokError("Expected comma before next argument");
    ++ArgIndex;
  }
}

/// ParseDeclaration - Read a declaration, returning the name of field ID, or an
/// empty string on error.  This can happen in a number of different contexts,
/// including within a def or in the template args for a class (in which case
/// CurRec will be non-null) and within the template args for a multiclass (in
/// which case CurRec will be null, but CurMultiClass will be set).  This can
/// also happen within a def that is within a multiclass, which will set both
/// CurRec and CurMultiClass.
///
///  Declaration ::= FIELD? Type ID ('=' Value)?
///
Init *TGParser::ParseDeclaration(Record *CurRec,
                                       bool ParsingTemplateArgs) {
  // Read the field prefix if present.
  bool HasField = consume(tgtok::Field);

  RecTy *Type = ParseType();
  if (!Type) return nullptr;

  if (Lex.getCode() != tgtok::Id) {
    TokError("Expected identifier in declaration");
    return nullptr;
  }

  std::string Str = Lex.getCurStrVal();
  if (Str == "NAME") {
    TokError("'" + Str + "' is a reserved variable name");
    return nullptr;
  }

  SMLoc IdLoc = Lex.getLoc();
  Init *DeclName = StringInit::get(Str);
  Lex.Lex();

  bool BadField;
  if (!ParsingTemplateArgs) { // def, possibly in a multiclass
    BadField = AddValue(CurRec, IdLoc,
                        RecordVal(DeclName, IdLoc, Type,
                                  HasField ? RecordVal::FK_NonconcreteOK
                                           : RecordVal::FK_Normal));

  } else if (CurRec) { // class template argument
    DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":");
    BadField = AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type,
                                                 RecordVal::FK_TemplateArg));

  } else { // multiclass template argument
    assert(CurMultiClass && "invalid context for template argument");
    DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName, "::");
    BadField = AddValue(CurRec, IdLoc, RecordVal(DeclName, IdLoc, Type,
                                                 RecordVal::FK_TemplateArg));
  }
  if (BadField)
    return nullptr;

  // If a value is present, parse it and set new field's value.
  if (consume(tgtok::equal)) {
    SMLoc ValLoc = Lex.getLoc();
    Init *Val = ParseValue(CurRec, Type);
    if (!Val ||
        SetValue(CurRec, ValLoc, DeclName, None, Val))
      // Return the name, even if an error is thrown.  This is so that we can
      // continue to make some progress, even without the value having been
      // initialized.
      return DeclName;
  }

  return DeclName;
}

/// ParseForeachDeclaration - Read a foreach declaration, returning
/// the name of the declared object or a NULL Init on error.  Return
/// the name of the parsed initializer list through ForeachListName.
///
///  ForeachDeclaration ::= ID '=' '{' RangeList '}'
///  ForeachDeclaration ::= ID '=' RangePiece
///  ForeachDeclaration ::= ID '=' Value
///
VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
  if (Lex.getCode() != tgtok::Id) {
    TokError("Expected identifier in foreach declaration");
    return nullptr;
  }

  Init *DeclName = StringInit::get(Lex.getCurStrVal());
  Lex.Lex();

  // If a value is present, parse it.
  if (!consume(tgtok::equal)) {
    TokError("Expected '=' in foreach declaration");
    return nullptr;
  }

  RecTy *IterType = nullptr;
  SmallVector<unsigned, 16> Ranges;

  switch (Lex.getCode()) {
  case tgtok::l_brace: { // '{' RangeList '}'
    Lex.Lex(); // eat the '{'
    ParseRangeList(Ranges);
    if (!consume(tgtok::r_brace)) {
      TokError("expected '}' at end of bit range list");
      return nullptr;
    }
    break;
  }

  default: {
    SMLoc ValueLoc = Lex.getLoc();
    Init *I = ParseValue(nullptr);
    if (!I)
      return nullptr;

    TypedInit *TI = dyn_cast<TypedInit>(I);
    if (TI && isa<ListRecTy>(TI->getType())) {
      ForeachListValue = I;
      IterType = cast<ListRecTy>(TI->getType())->getElementType();
      break;
    }

    if (TI) {
      if (ParseRangePiece(Ranges, TI))
        return nullptr;
      break;
    }

    Error(ValueLoc, "expected a list, got '" + I->getAsString() + "'");
    if (CurMultiClass) {
      PrintNote({}, "references to multiclass template arguments cannot be "
                "resolved at this time");
    }
    return nullptr;
  }
  }


  if (!Ranges.empty()) {
    assert(!IterType && "Type already initialized?");
    IterType = IntRecTy::get();
    std::vector<Init *> Values;
    for (unsigned R : Ranges)
      Values.push_back(IntInit::get(R));
    ForeachListValue = ListInit::get(Values, IterType);
  }

  if (!IterType)
    return nullptr;

  return VarInit::get(DeclName, IterType);
}

/// ParseTemplateArgList - Read a template argument list, which is a non-empty
/// sequence of template-declarations in <>'s.  If CurRec is non-null, these are
/// template args for a class. If null, these are the template args for a
/// multiclass.
///
///    TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
///
bool TGParser::ParseTemplateArgList(Record *CurRec) {
  assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
  Lex.Lex(); // eat the '<'

  Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;

  // Read the first declaration.
  Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
  if (!TemplArg)
    return true;

  TheRecToAddTo->addTemplateArg(TemplArg);

  while (consume(tgtok::comma)) {
    // Read the following declarations.
    SMLoc Loc = Lex.getLoc();
    TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
    if (!TemplArg)
      return true;

    if (TheRecToAddTo->isTemplateArg(TemplArg))
      return Error(Loc, "template argument with the same name has already been "
                        "defined");

    TheRecToAddTo->addTemplateArg(TemplArg);
  }

  if (!consume(tgtok::greater))
    return TokError("expected '>' at end of template argument list");
  return false;
}

/// ParseBodyItem - Parse a single item within the body of a def or class.
///
///   BodyItem ::= Declaration ';'
///   BodyItem ::= LET ID OptionalBitList '=' Value ';'
///   BodyItem ::= Defvar
///   BodyItem ::= Assert
///
bool TGParser::ParseBodyItem(Record *CurRec) {
  if (Lex.getCode() == tgtok::Assert)
    return ParseAssert(nullptr, CurRec);

  if (Lex.getCode() == tgtok::Defvar)
    return ParseDefvar();

  if (Lex.getCode() != tgtok::Let) {
    if (!ParseDeclaration(CurRec, false))
      return true;

    if (!consume(tgtok::semi))
      return TokError("expected ';' after declaration");
    return false;
  }

  // LET ID OptionalRangeList '=' Value ';'
  if (Lex.Lex() != tgtok::Id)
    return TokError("expected field identifier after let");

  SMLoc IdLoc = Lex.getLoc();
  StringInit *FieldName = StringInit::get(Lex.getCurStrVal());
  Lex.Lex();  // eat the field name.

  SmallVector<unsigned, 16> BitList;
  if (ParseOptionalBitList(BitList))
    return true;
  std::reverse(BitList.begin(), BitList.end());

  if (!consume(tgtok::equal))
    return TokError("expected '=' in let expression");

  RecordVal *Field = CurRec->getValue(FieldName);
  if (!Field)
    return TokError("Value '" + FieldName->getValue() + "' unknown!");

  RecTy *Type = Field->getType();
  if (!BitList.empty() && isa<BitsRecTy>(Type)) {
    // When assigning to a subset of a 'bits' object, expect the RHS to have
    // the type of that subset instead of the type of the whole object.
    Type = BitsRecTy::get(BitList.size());
  }

  Init *Val = ParseValue(CurRec, Type);
  if (!Val) return true;

  if (!consume(tgtok::semi))
    return TokError("expected ';' after let expression");

  return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
}

/// ParseBody - Read the body of a class or def.  Return true on error, false on
/// success.
///
///   Body     ::= ';'
///   Body     ::= '{' BodyList '}'
///   BodyList BodyItem*
///
bool TGParser::ParseBody(Record *CurRec) {
  // If this is a null definition, just eat the semi and return.
  if (consume(tgtok::semi))
    return false;

  if (!consume(tgtok::l_brace))
    return TokError("Expected '{' to start body or ';' for declaration only");

  // An object body introduces a new scope for local variables.
  TGLocalVarScope *BodyScope = PushLocalScope();

  while (Lex.getCode() != tgtok::r_brace)
    if (ParseBodyItem(CurRec))
      return true;

  PopLocalScope(BodyScope);

  // Eat the '}'.
  Lex.Lex();

  // If we have a semicolon, print a gentle error.
  SMLoc SemiLoc = Lex.getLoc();
  if (consume(tgtok::semi)) {
    PrintError(SemiLoc, "A class or def body should not end with a semicolon");
    PrintNote("Semicolon ignored; remove to eliminate this error");    
  }

  return false;
}

/// Apply the current let bindings to \a CurRec.
/// \returns true on error, false otherwise.
bool TGParser::ApplyLetStack(Record *CurRec) {
  for (SmallVectorImpl<LetRecord> &LetInfo : LetStack)
    for (LetRecord &LR : LetInfo)
      if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
        return true;
  return false;
}

/// Apply the current let bindings to the RecordsEntry.
bool TGParser::ApplyLetStack(RecordsEntry &Entry) {
  if (Entry.Rec)
    return ApplyLetStack(Entry.Rec.get());

  // Let bindings are not applied to assertions.
  if (Entry.Assertion)
    return false;

  for (auto &E : Entry.Loop->Entries) {
    if (ApplyLetStack(E))
      return true;
  }

  return false;
}

/// ParseObjectBody - Parse the body of a def or class.  This consists of an
/// optional ClassList followed by a Body.  CurRec is the current def or class
/// that is being parsed.
///
///   ObjectBody      ::= BaseClassList Body
///   BaseClassList   ::= /*empty*/
///   BaseClassList   ::= ':' BaseClassListNE
///   BaseClassListNE ::= SubClassRef (',' SubClassRef)*
///
bool TGParser::ParseObjectBody(Record *CurRec) {
  // If there is a baseclass list, read it.
  if (consume(tgtok::colon)) {

    // Read all of the subclasses.
    SubClassReference SubClass = ParseSubClassReference(CurRec, false);
    while (true) {
      // Check for error.
      if (!SubClass.Rec) return true;

      // Add it.
      if (AddSubClass(CurRec, SubClass))
        return true;

      if (!consume(tgtok::comma))
        break;
      SubClass = ParseSubClassReference(CurRec, false);
    }
  }

  if (ApplyLetStack(CurRec))
    return true;

  return ParseBody(CurRec);
}

/// ParseDef - Parse and return a top level or multiclass record definition.
/// Return false if okay, true if error.
///
///   DefInst ::= DEF ObjectName ObjectBody
///
bool TGParser::ParseDef(MultiClass *CurMultiClass) {
  SMLoc DefLoc = Lex.getLoc();
  assert(Lex.getCode() == tgtok::Def && "Unknown tok");
  Lex.Lex();  // Eat the 'def' token.

  // Parse ObjectName and make a record for it.
  std::unique_ptr<Record> CurRec;
  Init *Name = ParseObjectName(CurMultiClass);
  if (!Name)
    return true;

  if (isa<UnsetInit>(Name))
    CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc, Records,
                                 /*Anonymous=*/true);
  else
    CurRec = std::make_unique<Record>(Name, DefLoc, Records);

  if (ParseObjectBody(CurRec.get()))
    return true;

  return addEntry(std::move(CurRec));
}

/// ParseDefset - Parse a defset statement.
///
///   Defset ::= DEFSET Type Id '=' '{' ObjectList '}'
///
bool TGParser::ParseDefset() {
  assert(Lex.getCode() == tgtok::Defset);
  Lex.Lex(); // Eat the 'defset' token

  DefsetRecord Defset;
  Defset.Loc = Lex.getLoc();
  RecTy *Type = ParseType();
  if (!Type)
    return true;
  if (!isa<ListRecTy>(Type))
    return Error(Defset.Loc, "expected list type");
  Defset.EltTy = cast<ListRecTy>(Type)->getElementType();

  if (Lex.getCode() != tgtok::Id)
    return TokError("expected identifier");
  StringInit *DeclName = StringInit::get(Lex.getCurStrVal());
  if (Records.getGlobal(DeclName->getValue()))
    return TokError("def or global variable of this name already exists");

  if (Lex.Lex() != tgtok::equal) // Eat the identifier
    return TokError("expected '='");
  if (Lex.Lex() != tgtok::l_brace) // Eat the '='
    return TokError("expected '{'");
  SMLoc BraceLoc = Lex.getLoc();
  Lex.Lex(); // Eat the '{'

  Defsets.push_back(&Defset);
  bool Err = ParseObjectList(nullptr);
  Defsets.pop_back();
  if (Err)
    return true;

  if (!consume(tgtok::r_brace)) {
    TokError("expected '}' at end of defset");
    return Error(BraceLoc, "to match this '{'");
  }

  Records.addExtraGlobal(DeclName->getValue(),
                         ListInit::get(Defset.Elements, Defset.EltTy));
  return false;
}

/// ParseDefvar - Parse a defvar statement.
///
///   Defvar ::= DEFVAR Id '=' Value ';'
///
bool TGParser::ParseDefvar() {
  assert(Lex.getCode() == tgtok::Defvar);
  Lex.Lex(); // Eat the 'defvar' token

  if (Lex.getCode() != tgtok::Id)
    return TokError("expected identifier");
  StringInit *DeclName = StringInit::get(Lex.getCurStrVal());
  if (CurLocalScope) {
    if (CurLocalScope->varAlreadyDefined(DeclName->getValue()))
      return TokError("local variable of this name already exists");
  } else {
    if (Records.getGlobal(DeclName->getValue()))
      return TokError("def or global variable of this name already exists");
  }

  Lex.Lex();
  if (!consume(tgtok::equal))
    return TokError("expected '='");

  Init *Value = ParseValue(nullptr);
  if (!Value)
    return true;

  if (!consume(tgtok::semi))
    return TokError("expected ';'");

  if (CurLocalScope)
    CurLocalScope->addVar(DeclName->getValue(), Value);
  else
    Records.addExtraGlobal(DeclName->getValue(), Value);

  return false;
}

/// ParseForeach - Parse a for statement.  Return the record corresponding
/// to it.  This returns true on error.
///
///   Foreach ::= FOREACH Declaration IN '{ ObjectList '}'
///   Foreach ::= FOREACH Declaration IN Object
///
bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
  SMLoc Loc = Lex.getLoc();
  assert(Lex.getCode() == tgtok::Foreach && "Unknown tok");
  Lex.Lex();  // Eat the 'for' token.

  // Make a temporary object to record items associated with the for
  // loop.
  Init *ListValue = nullptr;
  VarInit *IterName = ParseForeachDeclaration(ListValue);
  if (!IterName)
    return TokError("expected declaration in for");

  if (!consume(tgtok::In))
    return TokError("Unknown tok");

  // Create a loop object and remember it.
  Loops.push_back(std::make_unique<ForeachLoop>(Loc, IterName, ListValue));

  // A foreach loop introduces a new scope for local variables.
  TGLocalVarScope *ForeachScope = PushLocalScope();

  if (Lex.getCode() != tgtok::l_brace) {
    // FOREACH Declaration IN Object
    if (ParseObject(CurMultiClass))
      return true;
  } else {
    SMLoc BraceLoc = Lex.getLoc();
    // Otherwise, this is a group foreach.
    Lex.Lex();  // eat the '{'.

    // Parse the object list.
    if (ParseObjectList(CurMultiClass))
      return true;

    if (!consume(tgtok::r_brace)) {
      TokError("expected '}' at end of foreach command");
      return Error(BraceLoc, "to match this '{'");
    }
  }

  PopLocalScope(ForeachScope);

  // Resolve the loop or store it for later resolution.
  std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
  Loops.pop_back();

  return addEntry(std::move(Loop));
}

/// ParseIf - Parse an if statement.
///
///   If ::= IF Value THEN IfBody
///   If ::= IF Value THEN IfBody ELSE IfBody
///
bool TGParser::ParseIf(MultiClass *CurMultiClass) {
  SMLoc Loc = Lex.getLoc();
  assert(Lex.getCode() == tgtok::If && "Unknown tok");
  Lex.Lex(); // Eat the 'if' token.

  // Make a temporary object to record items associated with the for
  // loop.
  Init *Condition = ParseValue(nullptr);
  if (!Condition)
    return true;

  if (!consume(tgtok::Then))
    return TokError("Unknown tok");

  // We have to be able to save if statements to execute later, and they have
  // to live on the same stack as foreach loops. The simplest implementation
  // technique is to convert each 'then' or 'else' clause *into* a foreach
  // loop, over a list of length 0 or 1 depending on the condition, and with no
  // iteration variable being assigned.

  ListInit *EmptyList = ListInit::get({}, BitRecTy::get());
  ListInit *SingletonList = ListInit::get({BitInit::get(1)}, BitRecTy::get());
  RecTy *BitListTy = ListRecTy::get(BitRecTy::get());

  // The foreach containing the then-clause selects SingletonList if
  // the condition is true.
  Init *ThenClauseList =
      TernOpInit::get(TernOpInit::IF, Condition, SingletonList, EmptyList,
                      BitListTy)
          ->Fold(nullptr);
  Loops.push_back(std::make_unique<ForeachLoop>(Loc, nullptr, ThenClauseList));

  if (ParseIfBody(CurMultiClass, "then"))
    return true;

  std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
  Loops.pop_back();

  if (addEntry(std::move(Loop)))
    return true;

  // Now look for an optional else clause. The if-else syntax has the usual
  // dangling-else ambiguity, and by greedily matching an else here if we can,
  // we implement the usual resolution of pairing with the innermost unmatched
  // if.
  if (consume(tgtok::ElseKW)) {
    // The foreach containing the else-clause uses the same pair of lists as
    // above, but this time, selects SingletonList if the condition is *false*.
    Init *ElseClauseList =
        TernOpInit::get(TernOpInit::IF, Condition, EmptyList, SingletonList,
                        BitListTy)
            ->Fold(nullptr);
    Loops.push_back(
        std::make_unique<ForeachLoop>(Loc, nullptr, ElseClauseList));

    if (ParseIfBody(CurMultiClass, "else"))
      return true;

    Loop = std::move(Loops.back());
    Loops.pop_back();

    if (addEntry(std::move(Loop)))
      return true;
  }

  return false;
}

/// ParseIfBody - Parse the then-clause or else-clause of an if statement.
///
///   IfBody ::= Object
///   IfBody ::= '{' ObjectList '}'
///
bool TGParser::ParseIfBody(MultiClass *CurMultiClass, StringRef Kind) {
  TGLocalVarScope *BodyScope = PushLocalScope();

  if (Lex.getCode() != tgtok::l_brace) {
    // A single object.
    if (ParseObject(CurMultiClass))
      return true;
  } else {
    SMLoc BraceLoc = Lex.getLoc();
    // A braced block.
    Lex.Lex(); // eat the '{'.

    // Parse the object list.
    if (ParseObjectList(CurMultiClass))
      return true;

    if (!consume(tgtok::r_brace)) {
      TokError("expected '}' at end of '" + Kind + "' clause");
      return Error(BraceLoc, "to match this '{'");
    }
  }

  PopLocalScope(BodyScope);
  return false;
}

/// ParseAssert - Parse an assert statement.
///
///   Assert ::= ASSERT condition , message ;
bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
  assert(Lex.getCode() == tgtok::Assert && "Unknown tok");
  Lex.Lex(); // Eat the 'assert' token.

  SMLoc ConditionLoc = Lex.getLoc();
  Init *Condition = ParseValue(CurRec);
  if (!Condition)
    return true;

  if (!consume(tgtok::comma)) {
    TokError("expected ',' in assert statement");
    return true;
  }

  Init *Message = ParseValue(CurRec);
  if (!Message)
    return true;

  if (!consume(tgtok::semi))
    return TokError("expected ';'");

  if (CurRec)
    CurRec->addAssertion(ConditionLoc, Condition, Message);
  else
    addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
                                                     Message));
  return false;
}

/// ParseClass - Parse a tblgen class definition.
///
///   ClassInst ::= CLASS ID TemplateArgList? ObjectBody
///
bool TGParser::ParseClass() {
  assert(Lex.getCode() == tgtok::Class && "Unexpected token!");
  Lex.Lex();

  if (Lex.getCode() != tgtok::Id)
    return TokError("expected class name after 'class' keyword");

  Record *CurRec = Records.getClass(Lex.getCurStrVal());
  if (CurRec) {
    // If the body was previously defined, this is an error.
    if (!CurRec->getValues().empty() ||
        !CurRec->getSuperClasses().empty() ||
        !CurRec->getTemplateArgs().empty())
      return TokError("Class '" + CurRec->getNameInitAsString() +
                      "' already defined");
  } else {
    // If this is the first reference to this class, create and add it.
    auto NewRec =
        std::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(), Records,
                                  /*Class=*/true);
    CurRec = NewRec.get();
    Records.addClass(std::move(NewRec));
  }
  Lex.Lex(); // eat the name.

  // If there are template args, parse them.
  if (Lex.getCode() == tgtok::less)
    if (ParseTemplateArgList(CurRec))
      return true;

  if (ParseObjectBody(CurRec))
    return true;

  if (!NoWarnOnUnusedTemplateArgs)
    CurRec->checkUnusedTemplateArgs();
  return false;
}

/// ParseLetList - Parse a non-empty list of assignment expressions into a list
/// of LetRecords.
///
///   LetList ::= LetItem (',' LetItem)*
///   LetItem ::= ID OptionalRangeList '=' Value
///
void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) {
  do {
    if (Lex.getCode() != tgtok::Id) {
      TokError("expected identifier in let definition");
      Result.clear();
      return;
    }

    StringInit *Name = StringInit::get(Lex.getCurStrVal());
    SMLoc NameLoc = Lex.getLoc();
    Lex.Lex();  // Eat the identifier.

    // Check for an optional RangeList.
    SmallVector<unsigned, 16> Bits;
    if (ParseOptionalRangeList(Bits)) {
      Result.clear();
      return;
    }
    std::reverse(Bits.begin(), Bits.end());

    if (!consume(tgtok::equal)) {
      TokError("expected '=' in let expression");
      Result.clear();
      return;
    }

    Init *Val = ParseValue(nullptr);
    if (!Val) {
      Result.clear();
      return;
    }

    // Now that we have everything, add the record.
    Result.emplace_back(Name, Bits, Val, NameLoc);
  } while (consume(tgtok::comma));
}

/// ParseTopLevelLet - Parse a 'let' at top level.  This can be a couple of
/// different related productions. This works inside multiclasses too.
///
///   Object ::= LET LetList IN '{' ObjectList '}'
///   Object ::= LET LetList IN Object
///
bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
  assert(Lex.getCode() == tgtok::Let && "Unexpected token");
  Lex.Lex();

  // Add this entry to the let stack.
  SmallVector<LetRecord, 8> LetInfo;
  ParseLetList(LetInfo);
  if (LetInfo.empty()) return true;
  LetStack.push_back(std::move(LetInfo));

  if (!consume(tgtok::In))
    return TokError("expected 'in' at end of top-level 'let'");

  TGLocalVarScope *LetScope = PushLocalScope();

  // If this is a scalar let, just handle it now
  if (Lex.getCode() != tgtok::l_brace) {
    // LET LetList IN Object
    if (ParseObject(CurMultiClass))
      return true;
  } else {   // Object ::= LETCommand '{' ObjectList '}'
    SMLoc BraceLoc = Lex.getLoc();
    // Otherwise, this is a group let.
    Lex.Lex();  // eat the '{'.

    // Parse the object list.
    if (ParseObjectList(CurMultiClass))
      return true;

    if (!consume(tgtok::r_brace)) {
      TokError("expected '}' at end of top level let command");
      return Error(BraceLoc, "to match this '{'");
    }
  }

  PopLocalScope(LetScope);

  // Outside this let scope, this let block is not active.
  LetStack.pop_back();
  return false;
}

/// ParseMultiClass - Parse a multiclass definition.
///
///  MultiClassInst ::= MULTICLASS ID TemplateArgList?
///                     ':' BaseMultiClassList '{' MultiClassObject+ '}'
///  MultiClassObject ::= Assert
///  MultiClassObject ::= DefInst
///  MultiClassObject ::= DefMInst
///  MultiClassObject ::= Defvar
///  MultiClassObject ::= Foreach
///  MultiClassObject ::= If
///  MultiClassObject ::= LETCommand '{' ObjectList '}'
///  MultiClassObject ::= LETCommand Object
///
bool TGParser::ParseMultiClass() {
  assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
  Lex.Lex();  // Eat the multiclass token.

  if (Lex.getCode() != tgtok::Id)
    return TokError("expected identifier after multiclass for name");
  std::string Name = Lex.getCurStrVal();

  auto Result =
    MultiClasses.insert(std::make_pair(Name,
                    std::make_unique<MultiClass>(Name, Lex.getLoc(),Records)));

  if (!Result.second)
    return TokError("multiclass '" + Name + "' already defined");

  CurMultiClass = Result.first->second.get();
  Lex.Lex();  // Eat the identifier.

  // If there are template args, parse them.
  if (Lex.getCode() == tgtok::less)
    if (ParseTemplateArgList(nullptr))
      return true;

  bool inherits = false;

  // If there are submulticlasses, parse them.
  if (consume(tgtok::colon)) {
    inherits = true;

    // Read all of the submulticlasses.
    SubMultiClassReference SubMultiClass =
      ParseSubMultiClassReference(CurMultiClass);
    while (true) {
      // Check for error.
      if (!SubMultiClass.MC) return true;

      // Add it.
      if (AddSubMultiClass(CurMultiClass, SubMultiClass))
        return true;

      if (!consume(tgtok::comma))
        break;
      SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
    }
  }

  if (Lex.getCode() != tgtok::l_brace) {
    if (!inherits)
      return TokError("expected '{' in multiclass definition");
    if (!consume(tgtok::semi))
      return TokError("expected ';' in multiclass definition");
  } else {
    if (Lex.Lex() == tgtok::r_brace)  // eat the '{'.
      return TokError("multiclass must contain at least one def");

    // A multiclass body introduces a new scope for local variables.
    TGLocalVarScope *MulticlassScope = PushLocalScope();

    while (Lex.getCode() != tgtok::r_brace) {
      switch (Lex.getCode()) {
      default:
        return TokError("expected 'assert', 'def', 'defm', 'defvar', "
                        "'foreach', 'if', or 'let' in multiclass body");

      case tgtok::Assert:
      case tgtok::Def:
      case tgtok::Defm:
      case tgtok::Defvar:
      case tgtok::Foreach:
      case tgtok::If:
      case tgtok::Let:
        if (ParseObject(CurMultiClass))
          return true;
        break;
      }
    }
    Lex.Lex();  // eat the '}'.

    // If we have a semicolon, print a gentle error.
    SMLoc SemiLoc = Lex.getLoc();
    if (consume(tgtok::semi)) {
      PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
      PrintNote("Semicolon ignored; remove to eliminate this error");    
    }

    PopLocalScope(MulticlassScope);
  }

  if (!NoWarnOnUnusedTemplateArgs)
    CurMultiClass->Rec.checkUnusedTemplateArgs();

  CurMultiClass = nullptr;
  return false;
}

/// ParseDefm - Parse the instantiation of a multiclass.
///
///   DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
///
bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
  assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
  Lex.Lex(); // eat the defm

  Init *DefmName = ParseObjectName(CurMultiClass);
  if (!DefmName)
    return true;
  if (isa<UnsetInit>(DefmName)) {
    DefmName = Records.getNewAnonymousName();
    if (CurMultiClass)
      DefmName = BinOpInit::getStrConcat(
          VarInit::get(QualifiedNameOfImplicitName(CurMultiClass),
                       StringRecTy::get()),
          DefmName);
  }

  if (Lex.getCode() != tgtok::colon)
    return TokError("expected ':' after defm identifier");

  // Keep track of the new generated record definitions.
  std::vector<RecordsEntry> NewEntries;

  // This record also inherits from a regular class (non-multiclass)?
  bool InheritFromClass = false;

  // eat the colon.
  Lex.Lex();

  SMLoc SubClassLoc = Lex.getLoc();
  SubClassReference Ref = ParseSubClassReference(nullptr, true);

  while (true) {
    if (!Ref.Rec) return true;

    // To instantiate a multiclass, we get the multiclass and then loop
    // through its template argument names. Substs contains a substitution
    // value for each argument, either the value specified or the default.
    // Then we can resolve the template arguments.
    MultiClass *MC = MultiClasses[std::string(Ref.Rec->getName())].get();
    assert(MC && "Didn't lookup multiclass correctly?");

    ArrayRef<Init *> TemplateVals = Ref.TemplateArgs;
    ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs();
    SubstStack Substs;

    for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
      if (i < TemplateVals.size()) {
        Substs.emplace_back(TArgs[i], TemplateVals[i]);
      } else {
        Init *Default = MC->Rec.getValue(TArgs[i])->getValue();
        if (!Default->isComplete())
          return Error(SubClassLoc,
                       "value not specified for template argument '" +
                           TArgs[i]->getAsUnquotedString() + "' (#" +
                           Twine(i) + ") of multiclass '" +
                           MC->Rec.getNameInitAsString() + "'");
        Substs.emplace_back(TArgs[i], Default);
      }
    }

    Substs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName);

    if (resolve(MC->Entries, Substs, !CurMultiClass && Loops.empty(),
                &NewEntries, &SubClassLoc))
      return true;

    if (!consume(tgtok::comma))
      break;

    if (Lex.getCode() != tgtok::Id)
      return TokError("expected identifier");

    SubClassLoc = Lex.getLoc();

    // A defm can inherit from regular classes (non-multiclasses) as
    // long as they come in the end of the inheritance list.
    InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr);

    if (InheritFromClass)
      break;

    Ref = ParseSubClassReference(nullptr, true);
  }

  if (InheritFromClass) {
    // Process all the classes to inherit as if they were part of a
    // regular 'def' and inherit all record values.
    SubClassReference SubClass = ParseSubClassReference(nullptr, false);
    while (true) {
      // Check for error.
      if (!SubClass.Rec) return true;

      // Get the expanded definition prototypes and teach them about
      // the record values the current class to inherit has
      for (auto &E : NewEntries) {
        // Add it.
        if (AddSubClass(E, SubClass))
          return true;
      }

      if (!consume(tgtok::comma))
        break;
      SubClass = ParseSubClassReference(nullptr, false);
    }
  }

  for (auto &E : NewEntries) {
    if (ApplyLetStack(E))
      return true;

    addEntry(std::move(E));
  }

  if (!consume(tgtok::semi))
    return TokError("expected ';' at end of defm");

  return false;
}

/// ParseObject
///   Object ::= ClassInst
///   Object ::= DefInst
///   Object ::= MultiClassInst
///   Object ::= DefMInst
///   Object ::= LETCommand '{' ObjectList '}'
///   Object ::= LETCommand Object
///   Object ::= Defset
///   Object ::= Defvar
///   Object ::= Assert
bool TGParser::ParseObject(MultiClass *MC) {
  switch (Lex.getCode()) {
  default:
    return TokError(
               "Expected assert, class, def, defm, defset, foreach, if, or let");
  case tgtok::Assert:  return ParseAssert(MC);
  case tgtok::Def:     return ParseDef(MC);
  case tgtok::Defm:    return ParseDefm(MC);
  case tgtok::Defvar:  return ParseDefvar();
  case tgtok::Foreach: return ParseForeach(MC);
  case tgtok::If:      return ParseIf(MC);
  case tgtok::Let:     return ParseTopLevelLet(MC);
  case tgtok::Defset:
    if (MC)
      return TokError("defset is not allowed inside multiclass");
    return ParseDefset();
  case tgtok::Class:
    if (MC)
      return TokError("class is not allowed inside multiclass");
    if (!Loops.empty())
      return TokError("class is not allowed inside foreach loop");
    return ParseClass();
  case tgtok::MultiClass:
    if (!Loops.empty())
      return TokError("multiclass is not allowed inside foreach loop");
    return ParseMultiClass();
  }
}

/// ParseObjectList
///   ObjectList :== Object*
bool TGParser::ParseObjectList(MultiClass *MC) {
  while (isObjectStart(Lex.getCode())) {
    if (ParseObject(MC))
      return true;
  }
  return false;
}

bool TGParser::ParseFile() {
  Lex.Lex(); // Prime the lexer.
  if (ParseObjectList()) return true;

  // If we have unread input at the end of the file, report it.
  if (Lex.getCode() == tgtok::Eof)
    return false;

  return TokError("Unexpected token at top level");
}

// Check the types of the template argument values for a class
// inheritance, multiclass invocation, or anonymous class invocation.
// If necessary, replace an argument with a cast to the required type.
// The argument count has already been checked.
bool TGParser::CheckTemplateArgValues(SmallVectorImpl<llvm::Init *> &Values,
                                      SMLoc Loc, Record *ArgsRec) {

  ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();

  for (unsigned I = 0, E = Values.size(); I < E; ++I) {
    RecordVal *Arg = ArgsRec->getValue(TArgs[I]);
    RecTy *ArgType = Arg->getType();
    auto *Value = Values[I];

    if (TypedInit *ArgValue = dyn_cast<TypedInit>(Value)) { 
      auto *CastValue = ArgValue->getCastTo(ArgType);
      if (CastValue) {
        assert((!isa<TypedInit>(CastValue) ||
                cast<TypedInit>(CastValue)->getType()->typeIsA(ArgType)) &&
               "result of template arg value cast has wrong type");
        Values[I] = CastValue;
      } else {
        PrintFatalError(Loc,
                        "Value specified for template argument '" +
                            Arg->getNameInitAsString() + "' (#" + Twine(I) +
                            ") is of type " + ArgValue->getType()->getAsString() +
                            "; expected type " + ArgType->getAsString() + ": " +
                            ArgValue->getAsString());
      }
    }
  }

  return false;
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void RecordsEntry::dump() const {
  if (Loop)
    Loop->dump();
  if (Rec)
    Rec->dump();
}

LLVM_DUMP_METHOD void ForeachLoop::dump() const {
  errs() << "foreach " << IterVar->getAsString() << " = "
         << ListValue->getAsString() << " in {\n";

  for (const auto &E : Entries)
    E.dump();

  errs() << "}\n";
}

LLVM_DUMP_METHOD void MultiClass::dump() const {
  errs() << "Record:\n";
  Rec.dump();

  errs() << "Defs:\n";
  for (const auto &E : Entries)
    E.dump();
}
#endif
