//===- 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/DenseMapInfo.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 <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) {
  RecordKeeper &RK = CurRec.getRecords();
  Init *NewName = BinOpInit::getStrConcat(CurRec.getNameInit(),
                                          StringInit::get(RK, Scoper));
  NewName = BinOpInit::getStrConcat(NewName, Name);
  if (CurMultiClass && Scoper != "::") {
    Init *Prefix = BinOpInit::getStrConcat(CurMultiClass->Rec.getNameInit(),
                                           StringInit::get(RK, "::"));
    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(Rec.getRecords(), "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, bool OverrideDefLoc) {
  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(Records, 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(Records, NewBits);
  }

  if (OverrideDefLoc ? RV->setValue(V, Loc) : RV->setValue(V)) {
    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(Records));
  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(Records)));

  // 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(Records);
  default:
    break;
  }

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

  Init *Name = ParseValue(CurRec, StringRecTy::get(Records), 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(Records)), 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);
  } else if (TrackReferenceLocs) {
    Result->appendReferenceLoc(Lex.getLocRange());
  }

  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(Records);
  case tgtok::Bit:
    Lex.Lex();
    return BitRecTy::get(Records);
  case tgtok::Int:
    Lex.Lex();
    return IntRecTy::get(Records);
  case tgtok::Dag:
    Lex.Lex();
    return DagRecTy::get(Records);
  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(Records, 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, SMRange NameLoc,
                             IDParseMode Mode) {
  if (CurRec) {
    if (RecordVal *RV = CurRec->getValue(Name)) {
      if (TrackReferenceLocs)
        RV->addReferenceLoc(NameLoc);
      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);
      if (TrackReferenceLocs)
        RV->addReferenceLoc(NameLoc);
      return VarInit::get(TemplateArgName, RV->getType());
    } else if (Name->getValue() == "NAME") {
      return VarInit::get(TemplateArgName, StringRecTy::get(Records));
    }
  }

  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())) {
    // Add a reference to the global if it's a record.
    if (TrackReferenceLocs) {
      if (auto *Def = dyn_cast<DefInit>(I))
        Def->getDef()->appendReferenceLoc(NameLoc);
    }
    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.Start, "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::XLOG2:
  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(Records);
      break;
    case tgtok::XLOG2:
      Lex.Lex();  // eat the operation
      Code = UnOpInit::LOG2;
      Type = IntRecTy::get(Records);
      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(Records);
      break;
    case tgtok::XEmpty:
      Lex.Lex();  // eat the operation
      Code = UnOpInit::EMPTY;
      Type = IntRecTy::get(Records);
      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(Records, {});
      }
      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::XExists: {
    // Value ::= !exists '<' Type '>' '(' Value ')'
    Lex.Lex(); // eat the operation

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

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

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

    TypedInit *ExprType = dyn_cast<TypedInit>(Expr);
    if (!ExprType) {
      Error(ExprLoc, "expected string type argument in !exists operator");
      return nullptr;
    }

    RecordRecTy *RecType = dyn_cast<RecordRecTy>(ExprType->getType());
    if (RecType) {
      Error(ExprLoc,
            "expected string type argument in !exists operator, please "
            "use !isa instead");
      return nullptr;
    }

    StringRecTy *SType = dyn_cast<StringRecTy>(ExprType->getType());
    if (!SType) {
      Error(ExprLoc, "expected string type argument in !exists operator");
      return nullptr;
    }

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

    return (ExistsOpInit::get(Type, Expr))->Fold(CurRec);
  }

  case tgtok::XConcat:
  case tgtok::XADD:
  case tgtok::XSUB:
  case tgtok::XMUL:
  case tgtok::XDIV:
  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::XListRemove:
  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::XDIV:    Code = BinOpInit::DIV; 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::XListRemove: Code = BinOpInit::LISTREMOVE; 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(Records);
      ArgType = DagRecTy::get(Records);
      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:
    case tgtok::XDIV:
      Type = IntRecTy::get(Records);
      ArgType = IntRecTy::get(Records);
      break;
    case tgtok::XEq:
    case tgtok::XNe:
    case tgtok::XLe:
    case tgtok::XLt:
    case tgtok::XGe:
    case tgtok::XGt:
      Type = BitRecTy::get(Records);
      // 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::XListRemove:
      // We don't know the list type until we parse the first argument.
      ArgType = ItemType;
      break;
    case tgtok::XStrConcat:
      Type = StringRecTy::get(Records);
      ArgType = StringRecTy::get(Records);
      break;
    case tgtok::XInterleave:
      Type = StringRecTy::get(Records);
      // 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::LISTREMOVE:
          if (!isa<ListRecTy>(ArgType)) {
            Error(InitLoc, Twine("expected a list, got value of type '") +
                               ArgType->getAsString() + "'");
            return nullptr;
          }
          break;
        case BinOpInit::EQ:
        case BinOpInit::NE:
          if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) &&
              !ArgType->typeIsConvertibleTo(StringRecTy::get(Records)) &&
              !ArgType->typeIsConvertibleTo(RecordRecTy::get(Records, {}))) {
            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(Records)) &&
              !ArgType->typeIsConvertibleTo(StringRecTy::get(Records))) {
            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(Records)->getListTy() &&
                !ArgType->typeIsConvertibleTo(
                    IntRecTy::get(Records)->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 && Code != BinOpInit::DIV)
          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(Records, {});
          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();
    // listremove returns a list with type of the argument.
    if (Code == BinOpInit::LISTREMOVE)
      Type = ArgType;

    // 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(Records);
      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(Records)->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(Records, MHSbits->getNumBits());
      if (isa<BitInit>(MHS))
        MHSTy = BitRecTy::get(Records);

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

      // 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(Records, 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(Records, 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(Records);

  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(Records, 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(Records);

  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(Records, 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(Records, 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(Records);
      } 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(Records, Vbits->getNumBits());
    if (isa<BitInit>(V))
      VTy = BitRecTy::get(Records);

    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 ::= DIVTOK '(' 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 ::= LISTREMOVETOK '(' 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(Records, 1);
    Lex.Lex();
    break;
  case tgtok::FalseVal:
    R = IntInit::get(Records, 0);
    Lex.Lex();
    break;
  case tgtok::IntVal:
    R = IntInit::get(Records, 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(Records, BinaryVal.first & (1LL << i));
    R = BitsInit::get(Records, 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(Records, Val);
    break;
  }
  case tgtok::CodeFragment:
    R = StringInit::get(Records, Lex.getCurStrVal(), StringInit::SF_Code);
    Lex.Lex();
    break;
  case tgtok::question:
    R = UnsetInit::get(Records);
    Lex.Lex();
    break;
  case tgtok::Id: {
    SMRange NameLoc = Lex.getLocRange();
    StringInit *Name = StringInit::get(Records, 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.Start,
            "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.Start, 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.Start, "Value not specified for template argument '" +
                                 TArgs[I]->getAsUnquotedString() + "' (#" +
                                 Twine(I) + ") of parent class '" +
                                 Class->getNameInitAsString() + "'");
      }
    }

    if (TrackReferenceLocs)
      Class->appendReferenceLoc(NameLoc);
    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(Records));
      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(Records, 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(Records, 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::XExists:
  case tgtok::XIsA:
  case tgtok::XConcat:
  case tgtok::XDag:
  case tgtok::XADD:
  case tgtok::XSUB:
  case tgtok::XMUL:
  case tgtok::XDIV:
  case tgtok::XNOT:
  case tgtok::XLOG2:
  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::XListRemove:
  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;
      }
      SMRange FieldNameLoc = Lex.getLocRange();
      StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
      if (!Result->getFieldType(FieldName)) {
        TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
                 Result->getAsString() + "'");
        return nullptr;
      }

      // Add a reference to this field if we know the record class.
      if (TrackReferenceLocs) {
        if (auto *DI = dyn_cast<DefInit>(Result)) {
          DI->getDef()->getValue(FieldName)->addReferenceLoc(FieldNameLoc);
        } else if (auto *TI = dyn_cast<TypedInit>(Result)) {
          if (auto *RecTy = dyn_cast<RecordRecTy>(TI->getType())) {
            for (Record *R : RecTy->getClasses())
              if (auto *RV = R->getValue(FieldName))
                RV->addReferenceLoc(FieldNameLoc);
          }
        }
      }

      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(Records)) {
        auto CastLHS = dyn_cast<TypedInit>(
            UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get(Records))
                ->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(Records, "");
        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(Records)) {
          auto CastRHS = dyn_cast<TypedInit>(
              UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get(Records))
                  ->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(Records, Lex.getCurStrVal());
      Result.emplace_back(UnsetInit::get(Records), 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(Records, 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(Records, 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, std::nullopt, Val,
                 /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/false)) {
      // 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(Records, 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(Records);
    std::vector<Init *> Values;
    for (unsigned R : Ranges)
      Values.push_back(IntInit::get(Records, 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(Records, 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(Records, 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.

  // If the name of the def is an Id token, use that for the location.
  // Otherwise, the name is more complex and we use the location of the 'def'
  // token.
  SMLoc NameLoc = Lex.getCode() == tgtok::Id ? Lex.getLoc() : DefLoc;

  // 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, NameLoc, 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(Records, 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(Records, 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(Records));
  ListInit *SingletonList =
      ListInit::get({BitInit::get(Records, true)}, BitRecTy::get(Records));
  RecTy *BitListTy = ListRecTy::get(BitRecTy::get(Records));

  // 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");

    CurRec->updateClassLoc(Lex.getLoc());
  } 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(Records, 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(Records)),
          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
