xref: /freebsd/contrib/llvm-project/llvm/lib/TableGen/TGParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- TGParser.cpp - Parser for TableGen Files ---------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Implement the Parser for TableGen.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "TGParser.h"
140b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
165ffd83dbSDimitry Andric #include "llvm/ADT/Twine.h"
170b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
180b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
220b57cec5SDimitry Andric #include <algorithm>
230b57cec5SDimitry Andric #include <cassert>
240b57cec5SDimitry Andric #include <cstdint>
25e8d8bef9SDimitry Andric #include <limits>
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric using namespace llvm;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
300b57cec5SDimitry Andric // Support Code for the Semantic Actions.
310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric namespace llvm {
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric struct SubClassReference {
360b57cec5SDimitry Andric   SMRange RefRange;
375f757f3fSDimitry Andric   Record *Rec = nullptr;
3806c3fb27SDimitry Andric   SmallVector<ArgumentInit *, 4> TemplateArgs;
390b57cec5SDimitry Andric 
405f757f3fSDimitry Andric   SubClassReference() = default;
410b57cec5SDimitry Andric 
isInvalidllvm::SubClassReference420b57cec5SDimitry Andric   bool isInvalid() const { return Rec == nullptr; }
430b57cec5SDimitry Andric };
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric struct SubMultiClassReference {
460b57cec5SDimitry Andric   SMRange RefRange;
475f757f3fSDimitry Andric   MultiClass *MC = nullptr;
4806c3fb27SDimitry Andric   SmallVector<ArgumentInit *, 4> TemplateArgs;
490b57cec5SDimitry Andric 
505f757f3fSDimitry Andric   SubMultiClassReference() = default;
510b57cec5SDimitry Andric 
isInvalidllvm::SubMultiClassReference520b57cec5SDimitry Andric   bool isInvalid() const { return MC == nullptr; }
530b57cec5SDimitry Andric   void dump() const;
540b57cec5SDimitry Andric };
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const570b57cec5SDimitry Andric LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {
580b57cec5SDimitry Andric   errs() << "Multiclass:\n";
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   MC->dump();
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   errs() << "Template args:\n";
630b57cec5SDimitry Andric   for (Init *TA : TemplateArgs)
640b57cec5SDimitry Andric     TA->dump();
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric #endif
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric } // end namespace llvm
690b57cec5SDimitry Andric 
checkBitsConcrete(Record & R,const RecordVal & RV)700b57cec5SDimitry Andric static bool checkBitsConcrete(Record &R, const RecordVal &RV) {
710b57cec5SDimitry Andric   BitsInit *BV = cast<BitsInit>(RV.getValue());
720b57cec5SDimitry Andric   for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
730b57cec5SDimitry Andric     Init *Bit = BV->getBit(i);
740b57cec5SDimitry Andric     bool IsReference = false;
750b57cec5SDimitry Andric     if (auto VBI = dyn_cast<VarBitInit>(Bit)) {
760b57cec5SDimitry Andric       if (auto VI = dyn_cast<VarInit>(VBI->getBitVar())) {
770b57cec5SDimitry Andric         if (R.getValue(VI->getName()))
780b57cec5SDimitry Andric           IsReference = true;
790b57cec5SDimitry Andric       }
800b57cec5SDimitry Andric     } else if (isa<VarInit>(Bit)) {
810b57cec5SDimitry Andric       IsReference = true;
820b57cec5SDimitry Andric     }
830b57cec5SDimitry Andric     if (!(IsReference || Bit->isConcrete()))
840b57cec5SDimitry Andric       return false;
850b57cec5SDimitry Andric   }
860b57cec5SDimitry Andric   return true;
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
checkConcrete(Record & R)890b57cec5SDimitry Andric static void checkConcrete(Record &R) {
900b57cec5SDimitry Andric   for (const RecordVal &RV : R.getValues()) {
910b57cec5SDimitry Andric     // HACK: Disable this check for variables declared with 'field'. This is
920b57cec5SDimitry Andric     // done merely because existing targets have legitimate cases of
930b57cec5SDimitry Andric     // non-concrete variables in helper defs. Ideally, we'd introduce a
940b57cec5SDimitry Andric     // 'maybe' or 'optional' modifier instead of this.
95e8d8bef9SDimitry Andric     if (RV.isNonconcreteOK())
960b57cec5SDimitry Andric       continue;
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric     if (Init *V = RV.getValue()) {
990b57cec5SDimitry Andric       bool Ok = isa<BitsInit>(V) ? checkBitsConcrete(R, RV) : V->isConcrete();
1000b57cec5SDimitry Andric       if (!Ok) {
1010b57cec5SDimitry Andric         PrintError(R.getLoc(),
1020b57cec5SDimitry Andric                    Twine("Initializer of '") + RV.getNameInitAsString() +
1030b57cec5SDimitry Andric                    "' in '" + R.getNameInitAsString() +
1040b57cec5SDimitry Andric                    "' could not be fully resolved: " +
1050b57cec5SDimitry Andric                    RV.getValue()->getAsString());
1060b57cec5SDimitry Andric       }
1070b57cec5SDimitry Andric     }
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric /// Return an Init with a qualifier prefix referring
1120b57cec5SDimitry Andric /// to CurRec's name.
QualifyName(Record & CurRec,Init * Name)1135f757f3fSDimitry Andric static Init *QualifyName(Record &CurRec, Init *Name) {
11481ad6265SDimitry Andric   RecordKeeper &RK = CurRec.getRecords();
1155f757f3fSDimitry Andric   Init *NewName = BinOpInit::getStrConcat(
1165f757f3fSDimitry Andric       CurRec.getNameInit(),
1175f757f3fSDimitry Andric       StringInit::get(RK, CurRec.isMultiClass() ? "::" : ":"));
1180b57cec5SDimitry Andric   NewName = BinOpInit::getStrConcat(NewName, Name);
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName))
1210b57cec5SDimitry Andric     NewName = BinOp->Fold(&CurRec);
1220b57cec5SDimitry Andric   return NewName;
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
QualifyName(MultiClass * MC,Init * Name)1255f757f3fSDimitry Andric static Init *QualifyName(MultiClass *MC, Init *Name) {
1265f757f3fSDimitry Andric   return QualifyName(MC->Rec, Name);
1275f757f3fSDimitry Andric }
1285f757f3fSDimitry Andric 
1290b57cec5SDimitry Andric /// Return the qualified version of the implicit 'NAME' template argument.
QualifiedNameOfImplicitName(Record & Rec)1305f757f3fSDimitry Andric static Init *QualifiedNameOfImplicitName(Record &Rec) {
1315f757f3fSDimitry Andric   return QualifyName(Rec, StringInit::get(Rec.getRecords(), "NAME"));
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
QualifiedNameOfImplicitName(MultiClass * MC)1340b57cec5SDimitry Andric static Init *QualifiedNameOfImplicitName(MultiClass *MC) {
1355f757f3fSDimitry Andric   return QualifiedNameOfImplicitName(MC->Rec);
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
getVar(RecordKeeper & Records,MultiClass * ParsingMultiClass,StringInit * Name,SMRange NameLoc,bool TrackReferenceLocs) const13806c3fb27SDimitry Andric Init *TGVarScope::getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass,
13906c3fb27SDimitry Andric                          StringInit *Name, SMRange NameLoc,
14006c3fb27SDimitry Andric                          bool TrackReferenceLocs) const {
14106c3fb27SDimitry Andric   // First, we search in local variables.
14206c3fb27SDimitry Andric   auto It = Vars.find(Name->getValue());
14306c3fb27SDimitry Andric   if (It != Vars.end())
14406c3fb27SDimitry Andric     return It->second;
14506c3fb27SDimitry Andric 
1465f757f3fSDimitry Andric   auto FindValueInArgs = [&](Record *Rec, StringInit *Name) -> Init * {
14706c3fb27SDimitry Andric     if (!Rec)
14806c3fb27SDimitry Andric       return nullptr;
1495f757f3fSDimitry Andric     Init *ArgName = QualifyName(*Rec, Name);
15006c3fb27SDimitry Andric     if (Rec->isTemplateArg(ArgName)) {
15106c3fb27SDimitry Andric       RecordVal *RV = Rec->getValue(ArgName);
15206c3fb27SDimitry Andric       assert(RV && "Template arg doesn't exist??");
15306c3fb27SDimitry Andric       RV->setUsed(true);
15406c3fb27SDimitry Andric       if (TrackReferenceLocs)
15506c3fb27SDimitry Andric         RV->addReferenceLoc(NameLoc);
15606c3fb27SDimitry Andric       return VarInit::get(ArgName, RV->getType());
15706c3fb27SDimitry Andric     }
15806c3fb27SDimitry Andric     return Name->getValue() == "NAME"
15906c3fb27SDimitry Andric                ? VarInit::get(ArgName, StringRecTy::get(Records))
16006c3fb27SDimitry Andric                : nullptr;
16106c3fb27SDimitry Andric   };
16206c3fb27SDimitry Andric 
16306c3fb27SDimitry Andric   // If not found, we try to find the variable in additional variables like
16406c3fb27SDimitry Andric   // arguments, loop iterator, etc.
16506c3fb27SDimitry Andric   switch (Kind) {
16606c3fb27SDimitry Andric   case SK_Local:
16706c3fb27SDimitry Andric     break; /* do nothing. */
16806c3fb27SDimitry Andric   case SK_Record: {
16906c3fb27SDimitry Andric     if (CurRec) {
17006c3fb27SDimitry Andric       // The variable is a record field?
17106c3fb27SDimitry Andric       if (RecordVal *RV = CurRec->getValue(Name)) {
17206c3fb27SDimitry Andric         if (TrackReferenceLocs)
17306c3fb27SDimitry Andric           RV->addReferenceLoc(NameLoc);
17406c3fb27SDimitry Andric         return VarInit::get(Name, RV->getType());
17506c3fb27SDimitry Andric       }
17606c3fb27SDimitry Andric 
17706c3fb27SDimitry Andric       // The variable is a class template argument?
17806c3fb27SDimitry Andric       if (CurRec->isClass())
1795f757f3fSDimitry Andric         if (auto *V = FindValueInArgs(CurRec, Name))
18006c3fb27SDimitry Andric           return V;
18106c3fb27SDimitry Andric     }
18206c3fb27SDimitry Andric     break;
18306c3fb27SDimitry Andric   }
18406c3fb27SDimitry Andric   case SK_ForeachLoop: {
18506c3fb27SDimitry Andric     // The variable is a loop iterator?
18606c3fb27SDimitry Andric     if (CurLoop->IterVar) {
18706c3fb27SDimitry Andric       VarInit *IterVar = dyn_cast<VarInit>(CurLoop->IterVar);
18806c3fb27SDimitry Andric       if (IterVar && IterVar->getNameInit() == Name)
18906c3fb27SDimitry Andric         return IterVar;
19006c3fb27SDimitry Andric     }
19106c3fb27SDimitry Andric     break;
19206c3fb27SDimitry Andric   }
19306c3fb27SDimitry Andric   case SK_MultiClass: {
19406c3fb27SDimitry Andric     // The variable is a multiclass template argument?
19506c3fb27SDimitry Andric     if (CurMultiClass)
1965f757f3fSDimitry Andric       if (auto *V = FindValueInArgs(&CurMultiClass->Rec, Name))
19706c3fb27SDimitry Andric         return V;
19806c3fb27SDimitry Andric     break;
19906c3fb27SDimitry Andric   }
20006c3fb27SDimitry Andric   }
20106c3fb27SDimitry Andric 
20206c3fb27SDimitry Andric   // Then, we try to find the name in parent scope.
20306c3fb27SDimitry Andric   if (Parent)
20406c3fb27SDimitry Andric     return Parent->getVar(Records, ParsingMultiClass, Name, NameLoc,
20506c3fb27SDimitry Andric                           TrackReferenceLocs);
20606c3fb27SDimitry Andric 
20706c3fb27SDimitry Andric   return nullptr;
20806c3fb27SDimitry Andric }
20906c3fb27SDimitry Andric 
AddValue(Record * CurRec,SMLoc Loc,const RecordVal & RV)2100b57cec5SDimitry Andric bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
2110b57cec5SDimitry Andric   if (!CurRec)
2120b57cec5SDimitry Andric     CurRec = &CurMultiClass->Rec;
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) {
2150b57cec5SDimitry Andric     // The value already exists in the class, treat this as a set.
2160b57cec5SDimitry Andric     if (ERV->setValue(RV.getValue()))
2170b57cec5SDimitry Andric       return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
2180b57cec5SDimitry Andric                    RV.getType()->getAsString() + "' is incompatible with " +
2190b57cec5SDimitry Andric                    "previous definition of type '" +
2200b57cec5SDimitry Andric                    ERV->getType()->getAsString() + "'");
2210b57cec5SDimitry Andric   } else {
2220b57cec5SDimitry Andric     CurRec->addValue(RV);
2230b57cec5SDimitry Andric   }
2240b57cec5SDimitry Andric   return false;
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric /// SetValue -
2280b57cec5SDimitry Andric /// Return true on error, false on success.
SetValue(Record * CurRec,SMLoc Loc,Init * ValName,ArrayRef<unsigned> BitList,Init * V,bool AllowSelfAssignment,bool OverrideDefLoc)2290b57cec5SDimitry Andric bool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName,
2300b57cec5SDimitry Andric                         ArrayRef<unsigned> BitList, Init *V,
231bdd1243dSDimitry Andric                         bool AllowSelfAssignment, bool OverrideDefLoc) {
2320b57cec5SDimitry Andric   if (!V) return false;
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   if (!CurRec) CurRec = &CurMultiClass->Rec;
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   RecordVal *RV = CurRec->getValue(ValName);
2370b57cec5SDimitry Andric   if (!RV)
2380b57cec5SDimitry Andric     return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
2390b57cec5SDimitry Andric                  "' unknown!");
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric   // Do not allow assignments like 'X = X'.  This will just cause infinite loops
2420b57cec5SDimitry Andric   // in the resolution machinery.
2430b57cec5SDimitry Andric   if (BitList.empty())
2440b57cec5SDimitry Andric     if (VarInit *VI = dyn_cast<VarInit>(V))
2450b57cec5SDimitry Andric       if (VI->getNameInit() == ValName && !AllowSelfAssignment)
2460b57cec5SDimitry Andric         return Error(Loc, "Recursion / self-assignment forbidden");
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   // If we are assigning to a subset of the bits in the value... then we must be
2490b57cec5SDimitry Andric   // assigning to a field of BitsRecTy, which must have a BitsInit
2500b57cec5SDimitry Andric   // initializer.
2510b57cec5SDimitry Andric   //
2520b57cec5SDimitry Andric   if (!BitList.empty()) {
2530b57cec5SDimitry Andric     BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue());
2540b57cec5SDimitry Andric     if (!CurVal)
2550b57cec5SDimitry Andric       return Error(Loc, "Value '" + ValName->getAsUnquotedString() +
2560b57cec5SDimitry Andric                    "' is not a bits type");
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric     // Convert the incoming value to a bits type of the appropriate size...
25981ad6265SDimitry Andric     Init *BI = V->getCastTo(BitsRecTy::get(Records, BitList.size()));
2600b57cec5SDimitry Andric     if (!BI)
2610b57cec5SDimitry Andric       return Error(Loc, "Initializer is not compatible with bit range");
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric     SmallVector<Init *, 16> NewBits(CurVal->getNumBits());
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric     // Loop over bits, assigning values as appropriate.
2660b57cec5SDimitry Andric     for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
2670b57cec5SDimitry Andric       unsigned Bit = BitList[i];
2680b57cec5SDimitry Andric       if (NewBits[Bit])
2690b57cec5SDimitry Andric         return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" +
2700b57cec5SDimitry Andric                      ValName->getAsUnquotedString() + "' more than once");
2710b57cec5SDimitry Andric       NewBits[Bit] = BI->getBit(i);
2720b57cec5SDimitry Andric     }
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric     for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
2750b57cec5SDimitry Andric       if (!NewBits[i])
2760b57cec5SDimitry Andric         NewBits[i] = CurVal->getBit(i);
2770b57cec5SDimitry Andric 
27881ad6265SDimitry Andric     V = BitsInit::get(Records, NewBits);
2790b57cec5SDimitry Andric   }
2800b57cec5SDimitry Andric 
281bdd1243dSDimitry Andric   if (OverrideDefLoc ? RV->setValue(V, Loc) : RV->setValue(V)) {
2820b57cec5SDimitry Andric     std::string InitType;
2830b57cec5SDimitry Andric     if (BitsInit *BI = dyn_cast<BitsInit>(V))
2840b57cec5SDimitry Andric       InitType = (Twine("' of type bit initializer with length ") +
2850b57cec5SDimitry Andric                   Twine(BI->getNumBits())).str();
2860b57cec5SDimitry Andric     else if (TypedInit *TI = dyn_cast<TypedInit>(V))
2870b57cec5SDimitry Andric       InitType = (Twine("' of type '") + TI->getType()->getAsString()).str();
288e8d8bef9SDimitry Andric     return Error(Loc, "Field '" + ValName->getAsUnquotedString() +
2890b57cec5SDimitry Andric                           "' of type '" + RV->getType()->getAsString() +
290e8d8bef9SDimitry Andric                           "' is incompatible with value '" +
2910b57cec5SDimitry Andric                           V->getAsString() + InitType + "'");
2920b57cec5SDimitry Andric   }
2930b57cec5SDimitry Andric   return false;
2940b57cec5SDimitry Andric }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric /// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template
2970b57cec5SDimitry Andric /// args as SubClass's template arguments.
AddSubClass(Record * CurRec,SubClassReference & SubClass)2980b57cec5SDimitry Andric bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
2990b57cec5SDimitry Andric   Record *SC = SubClass.Rec;
3000b57cec5SDimitry Andric   MapResolver R(CurRec);
3010b57cec5SDimitry Andric 
30206c3fb27SDimitry Andric   // Loop over all the subclass record's fields. Add regular fields to the new
30306c3fb27SDimitry Andric   // record.
30406c3fb27SDimitry Andric   for (const RecordVal &Field : SC->getValues())
30506c3fb27SDimitry Andric     if (!Field.isTemplateArg())
306fe6060f1SDimitry Andric       if (AddValue(CurRec, SubClass.RefRange.Start, Field))
3070b57cec5SDimitry Andric         return true;
308fe6060f1SDimitry Andric 
30906c3fb27SDimitry Andric   if (resolveArgumentsOfClass(R, SC, SubClass.TemplateArgs,
31006c3fb27SDimitry Andric                               SubClass.RefRange.Start))
31106c3fb27SDimitry Andric     return true;
3120b57cec5SDimitry Andric 
313fe6060f1SDimitry Andric   // Copy the subclass record's assertions to the new record.
314fe6060f1SDimitry Andric   CurRec->appendAssertions(SC);
3150b57cec5SDimitry Andric 
3165f757f3fSDimitry Andric   // Copy the subclass record's dumps to the new record.
3175f757f3fSDimitry Andric   CurRec->appendDumps(SC);
3185f757f3fSDimitry Andric 
3190b57cec5SDimitry Andric   Init *Name;
3200b57cec5SDimitry Andric   if (CurRec->isClass())
32181ad6265SDimitry Andric     Name = VarInit::get(QualifiedNameOfImplicitName(*CurRec),
32281ad6265SDimitry Andric                         StringRecTy::get(Records));
3230b57cec5SDimitry Andric   else
3240b57cec5SDimitry Andric     Name = CurRec->getNameInit();
3250b57cec5SDimitry Andric   R.set(QualifiedNameOfImplicitName(*SC), Name);
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   CurRec->resolveReferences(R);
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric   // Since everything went well, we can now set the "superclass" list for the
3300b57cec5SDimitry Andric   // current record.
3310b57cec5SDimitry Andric   ArrayRef<std::pair<Record *, SMRange>> SCs = SC->getSuperClasses();
3320b57cec5SDimitry Andric   for (const auto &SCPair : SCs) {
3330b57cec5SDimitry Andric     if (CurRec->isSubClassOf(SCPair.first))
3340b57cec5SDimitry Andric       return Error(SubClass.RefRange.Start,
3350b57cec5SDimitry Andric                    "Already subclass of '" + SCPair.first->getName() + "'!\n");
3360b57cec5SDimitry Andric     CurRec->addSuperClass(SCPair.first, SCPair.second);
3370b57cec5SDimitry Andric   }
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   if (CurRec->isSubClassOf(SC))
3400b57cec5SDimitry Andric     return Error(SubClass.RefRange.Start,
3410b57cec5SDimitry Andric                  "Already subclass of '" + SC->getName() + "'!\n");
3420b57cec5SDimitry Andric   CurRec->addSuperClass(SC, SubClass.RefRange);
3430b57cec5SDimitry Andric   return false;
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric 
AddSubClass(RecordsEntry & Entry,SubClassReference & SubClass)3460b57cec5SDimitry Andric bool TGParser::AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass) {
3470b57cec5SDimitry Andric   if (Entry.Rec)
3480b57cec5SDimitry Andric     return AddSubClass(Entry.Rec.get(), SubClass);
3490b57cec5SDimitry Andric 
350fe6060f1SDimitry Andric   if (Entry.Assertion)
351fe6060f1SDimitry Andric     return false;
352fe6060f1SDimitry Andric 
3530b57cec5SDimitry Andric   for (auto &E : Entry.Loop->Entries) {
3540b57cec5SDimitry Andric     if (AddSubClass(E, SubClass))
3550b57cec5SDimitry Andric       return true;
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   return false;
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric /// AddSubMultiClass - Add SubMultiClass as a subclass to
3620b57cec5SDimitry Andric /// CurMC, resolving its template args as SubMultiClass's
3630b57cec5SDimitry Andric /// template arguments.
AddSubMultiClass(MultiClass * CurMC,SubMultiClassReference & SubMultiClass)3640b57cec5SDimitry Andric bool TGParser::AddSubMultiClass(MultiClass *CurMC,
3650b57cec5SDimitry Andric                                 SubMultiClassReference &SubMultiClass) {
3660b57cec5SDimitry Andric   MultiClass *SMC = SubMultiClass.MC;
3670b57cec5SDimitry Andric 
36806c3fb27SDimitry Andric   SubstStack Substs;
36906c3fb27SDimitry Andric   if (resolveArgumentsOfMultiClass(
37006c3fb27SDimitry Andric           Substs, SMC, SubMultiClass.TemplateArgs,
37181ad6265SDimitry Andric           VarInit::get(QualifiedNameOfImplicitName(CurMC),
37206c3fb27SDimitry Andric                        StringRecTy::get(Records)),
37306c3fb27SDimitry Andric           SubMultiClass.RefRange.Start))
37406c3fb27SDimitry Andric     return true;
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric   // Add all of the defs in the subclass into the current multiclass.
37706c3fb27SDimitry Andric   return resolve(SMC->Entries, Substs, false, &CurMC->Entries);
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
380fe6060f1SDimitry Andric /// Add a record, foreach loop, or assertion to the current context.
addEntry(RecordsEntry E)3810b57cec5SDimitry Andric bool TGParser::addEntry(RecordsEntry E) {
3825f757f3fSDimitry Andric   assert((!!E.Rec + !!E.Loop + !!E.Assertion + !!E.Dump) == 1 &&
383fe6060f1SDimitry Andric          "RecordsEntry has invalid number of items");
3840b57cec5SDimitry Andric 
385fe6060f1SDimitry Andric   // If we are parsing a loop, add it to the loop's entries.
3860b57cec5SDimitry Andric   if (!Loops.empty()) {
3870b57cec5SDimitry Andric     Loops.back()->Entries.push_back(std::move(E));
3880b57cec5SDimitry Andric     return false;
3890b57cec5SDimitry Andric   }
3900b57cec5SDimitry Andric 
391fe6060f1SDimitry Andric   // If it is a loop, then resolve and perform the loop.
3920b57cec5SDimitry Andric   if (E.Loop) {
3930b57cec5SDimitry Andric     SubstStack Stack;
3940b57cec5SDimitry Andric     return resolve(*E.Loop, Stack, CurMultiClass == nullptr,
3950b57cec5SDimitry Andric                    CurMultiClass ? &CurMultiClass->Entries : nullptr);
3960b57cec5SDimitry Andric   }
3970b57cec5SDimitry Andric 
398fe6060f1SDimitry Andric   // If we are parsing a multiclass, add it to the multiclass's entries.
3990b57cec5SDimitry Andric   if (CurMultiClass) {
4000b57cec5SDimitry Andric     CurMultiClass->Entries.push_back(std::move(E));
4010b57cec5SDimitry Andric     return false;
4020b57cec5SDimitry Andric   }
4030b57cec5SDimitry Andric 
404fe6060f1SDimitry Andric   // If it is an assertion, then it's a top-level one, so check it.
405fe6060f1SDimitry Andric   if (E.Assertion) {
406fe6060f1SDimitry Andric     CheckAssert(E.Assertion->Loc, E.Assertion->Condition, E.Assertion->Message);
407fe6060f1SDimitry Andric     return false;
408fe6060f1SDimitry Andric   }
409fe6060f1SDimitry Andric 
4105f757f3fSDimitry Andric   if (E.Dump) {
4115f757f3fSDimitry Andric     dumpMessage(E.Dump->Loc, E.Dump->Message);
4125f757f3fSDimitry Andric     return false;
4135f757f3fSDimitry Andric   }
4145f757f3fSDimitry Andric 
415fe6060f1SDimitry Andric   // It must be a record, so finish it off.
4160b57cec5SDimitry Andric   return addDefOne(std::move(E.Rec));
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric /// Resolve the entries in \p Loop, going over inner loops recursively
4200b57cec5SDimitry Andric /// and making the given subsitutions of (name, value) pairs.
4210b57cec5SDimitry Andric ///
4220b57cec5SDimitry Andric /// The resulting records are stored in \p Dest if non-null. Otherwise, they
4230b57cec5SDimitry Andric /// are added to the global record keeper.
resolve(const ForeachLoop & Loop,SubstStack & Substs,bool Final,std::vector<RecordsEntry> * Dest,SMLoc * Loc)4240b57cec5SDimitry Andric bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs,
4250b57cec5SDimitry Andric                        bool Final, std::vector<RecordsEntry> *Dest,
4260b57cec5SDimitry Andric                        SMLoc *Loc) {
42706c3fb27SDimitry Andric 
4280b57cec5SDimitry Andric   MapResolver R;
4290b57cec5SDimitry Andric   for (const auto &S : Substs)
4300b57cec5SDimitry Andric     R.set(S.first, S.second);
4310b57cec5SDimitry Andric   Init *List = Loop.ListValue->resolveReferences(R);
43206c3fb27SDimitry Andric 
43306c3fb27SDimitry Andric   // For if-then-else blocks, we lower to a foreach loop whose list is a
43406c3fb27SDimitry Andric   // ternary selection between lists of different length.  Since we don't
43506c3fb27SDimitry Andric   // have a means to track variable length record lists, we *must* resolve
43606c3fb27SDimitry Andric   // the condition here.  We want to defer final resolution of the arms
43706c3fb27SDimitry Andric   // until the resulting records are finalized.
43806c3fb27SDimitry Andric   // e.g. !if(!exists<SchedWrite>("__does_not_exist__"), [1], [])
43906c3fb27SDimitry Andric   if (auto *TI = dyn_cast<TernOpInit>(List);
44006c3fb27SDimitry Andric       TI && TI->getOpcode() == TernOpInit::IF && Final) {
44106c3fb27SDimitry Andric     Init *OldLHS = TI->getLHS();
44206c3fb27SDimitry Andric     R.setFinal(true);
44306c3fb27SDimitry Andric     Init *LHS = OldLHS->resolveReferences(R);
44406c3fb27SDimitry Andric     if (LHS == OldLHS) {
44506c3fb27SDimitry Andric       PrintError(Loop.Loc,
44606c3fb27SDimitry Andric                  Twine("unable to resolve if condition '") +
44706c3fb27SDimitry Andric                  LHS->getAsString() + "' at end of containing scope");
44806c3fb27SDimitry Andric       return true;
44906c3fb27SDimitry Andric     }
45006c3fb27SDimitry Andric     Init *MHS = TI->getMHS();
45106c3fb27SDimitry Andric     Init *RHS = TI->getRHS();
45206c3fb27SDimitry Andric     List = TernOpInit::get(TernOpInit::IF, LHS, MHS, RHS, TI->getType())
45306c3fb27SDimitry Andric       ->Fold(nullptr);
45406c3fb27SDimitry Andric   }
45506c3fb27SDimitry Andric 
4560b57cec5SDimitry Andric   auto LI = dyn_cast<ListInit>(List);
4570b57cec5SDimitry Andric   if (!LI) {
4580b57cec5SDimitry Andric     if (!Final) {
4598bcb0991SDimitry Andric       Dest->emplace_back(std::make_unique<ForeachLoop>(Loop.Loc, Loop.IterVar,
4600b57cec5SDimitry Andric                                                   List));
4610b57cec5SDimitry Andric       return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
4620b57cec5SDimitry Andric                      Loc);
4630b57cec5SDimitry Andric     }
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric     PrintError(Loop.Loc, Twine("attempting to loop over '") +
4660b57cec5SDimitry Andric                               List->getAsString() + "', expected a list");
4670b57cec5SDimitry Andric     return true;
4680b57cec5SDimitry Andric   }
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   bool Error = false;
471bdd1243dSDimitry Andric   for (auto *Elt : *LI) {
472480093f4SDimitry Andric     if (Loop.IterVar)
4730b57cec5SDimitry Andric       Substs.emplace_back(Loop.IterVar->getNameInit(), Elt);
4740b57cec5SDimitry Andric     Error = resolve(Loop.Entries, Substs, Final, Dest);
475480093f4SDimitry Andric     if (Loop.IterVar)
4760b57cec5SDimitry Andric       Substs.pop_back();
4770b57cec5SDimitry Andric     if (Error)
4780b57cec5SDimitry Andric       break;
4790b57cec5SDimitry Andric   }
4800b57cec5SDimitry Andric   return Error;
4810b57cec5SDimitry Andric }
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric /// Resolve the entries in \p Source, going over loops recursively and
4840b57cec5SDimitry Andric /// making the given substitutions of (name, value) pairs.
4850b57cec5SDimitry Andric ///
4860b57cec5SDimitry Andric /// The resulting records are stored in \p Dest if non-null. Otherwise, they
4870b57cec5SDimitry Andric /// are added to the global record keeper.
resolve(const std::vector<RecordsEntry> & Source,SubstStack & Substs,bool Final,std::vector<RecordsEntry> * Dest,SMLoc * Loc)4880b57cec5SDimitry Andric bool TGParser::resolve(const std::vector<RecordsEntry> &Source,
4890b57cec5SDimitry Andric                        SubstStack &Substs, bool Final,
4900b57cec5SDimitry Andric                        std::vector<RecordsEntry> *Dest, SMLoc *Loc) {
4910b57cec5SDimitry Andric   bool Error = false;
4920b57cec5SDimitry Andric   for (auto &E : Source) {
4930b57cec5SDimitry Andric     if (E.Loop) {
4940b57cec5SDimitry Andric       Error = resolve(*E.Loop, Substs, Final, Dest);
495fe6060f1SDimitry Andric 
496fe6060f1SDimitry Andric     } else if (E.Assertion) {
497fe6060f1SDimitry Andric       MapResolver R;
498fe6060f1SDimitry Andric       for (const auto &S : Substs)
499fe6060f1SDimitry Andric         R.set(S.first, S.second);
500fe6060f1SDimitry Andric       Init *Condition = E.Assertion->Condition->resolveReferences(R);
501fe6060f1SDimitry Andric       Init *Message = E.Assertion->Message->resolveReferences(R);
502fe6060f1SDimitry Andric 
503fe6060f1SDimitry Andric       if (Dest)
504fe6060f1SDimitry Andric         Dest->push_back(std::make_unique<Record::AssertionInfo>(
505fe6060f1SDimitry Andric             E.Assertion->Loc, Condition, Message));
506fe6060f1SDimitry Andric       else
507fe6060f1SDimitry Andric         CheckAssert(E.Assertion->Loc, Condition, Message);
508fe6060f1SDimitry Andric 
5095f757f3fSDimitry Andric     } else if (E.Dump) {
5105f757f3fSDimitry Andric       MapResolver R;
5115f757f3fSDimitry Andric       for (const auto &S : Substs)
5125f757f3fSDimitry Andric         R.set(S.first, S.second);
5135f757f3fSDimitry Andric       Init *Message = E.Dump->Message->resolveReferences(R);
5145f757f3fSDimitry Andric 
5155f757f3fSDimitry Andric       if (Dest)
5165f757f3fSDimitry Andric         Dest->push_back(
5175f757f3fSDimitry Andric             std::make_unique<Record::DumpInfo>(E.Dump->Loc, Message));
5185f757f3fSDimitry Andric       else
5195f757f3fSDimitry Andric         dumpMessage(E.Dump->Loc, Message);
5205f757f3fSDimitry Andric 
5210b57cec5SDimitry Andric     } else {
5228bcb0991SDimitry Andric       auto Rec = std::make_unique<Record>(*E.Rec);
5230b57cec5SDimitry Andric       if (Loc)
5240b57cec5SDimitry Andric         Rec->appendLoc(*Loc);
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric       MapResolver R(Rec.get());
5270b57cec5SDimitry Andric       for (const auto &S : Substs)
5280b57cec5SDimitry Andric         R.set(S.first, S.second);
5290b57cec5SDimitry Andric       Rec->resolveReferences(R);
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric       if (Dest)
5320b57cec5SDimitry Andric         Dest->push_back(std::move(Rec));
5330b57cec5SDimitry Andric       else
5340b57cec5SDimitry Andric         Error = addDefOne(std::move(Rec));
5350b57cec5SDimitry Andric     }
5360b57cec5SDimitry Andric     if (Error)
5370b57cec5SDimitry Andric       break;
5380b57cec5SDimitry Andric   }
5390b57cec5SDimitry Andric   return Error;
5400b57cec5SDimitry Andric }
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric /// Resolve the record fully and add it to the record keeper.
addDefOne(std::unique_ptr<Record> Rec)5430b57cec5SDimitry Andric bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
544fe6060f1SDimitry Andric   Init *NewName = nullptr;
5450b57cec5SDimitry Andric   if (Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
5460b57cec5SDimitry Andric     if (!Rec->isAnonymous()) {
5470b57cec5SDimitry Andric       PrintError(Rec->getLoc(),
5480b57cec5SDimitry Andric                  "def already exists: " + Rec->getNameInitAsString());
5490b57cec5SDimitry Andric       PrintNote(Prev->getLoc(), "location of previous definition");
5500b57cec5SDimitry Andric       return true;
5510b57cec5SDimitry Andric     }
552fe6060f1SDimitry Andric     NewName = Records.getNewAnonymousName();
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric 
555fe6060f1SDimitry Andric   Rec->resolveReferences(NewName);
5560b57cec5SDimitry Andric   checkConcrete(*Rec);
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric   if (!isa<StringInit>(Rec->getNameInit())) {
5590b57cec5SDimitry Andric     PrintError(Rec->getLoc(), Twine("record name '") +
5600b57cec5SDimitry Andric                                   Rec->getNameInit()->getAsString() +
5610b57cec5SDimitry Andric                                   "' could not be fully resolved");
5620b57cec5SDimitry Andric     return true;
5630b57cec5SDimitry Andric   }
5640b57cec5SDimitry Andric 
565fe6060f1SDimitry Andric   // Check the assertions.
566fe6060f1SDimitry Andric   Rec->checkRecordAssertions();
567fe6060f1SDimitry Andric 
5685f757f3fSDimitry Andric   // Run the dumps.
5695f757f3fSDimitry Andric   Rec->emitRecordDumps();
5705f757f3fSDimitry Andric 
5710b57cec5SDimitry Andric   // If ObjectBody has template arguments, it's an error.
5720b57cec5SDimitry Andric   assert(Rec->getTemplateArgs().empty() && "How'd this get template args?");
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   for (DefsetRecord *Defset : Defsets) {
5750b57cec5SDimitry Andric     DefInit *I = Rec->getDefInit();
5760b57cec5SDimitry Andric     if (!I->getType()->typeIsA(Defset->EltTy)) {
5770b57cec5SDimitry Andric       PrintError(Rec->getLoc(), Twine("adding record of incompatible type '") +
5780b57cec5SDimitry Andric                                     I->getType()->getAsString() +
5790b57cec5SDimitry Andric                                      "' to defset");
5800b57cec5SDimitry Andric       PrintNote(Defset->Loc, "location of defset declaration");
5810b57cec5SDimitry Andric       return true;
5820b57cec5SDimitry Andric     }
5830b57cec5SDimitry Andric     Defset->Elements.push_back(I);
5840b57cec5SDimitry Andric   }
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric   Records.addDef(std::move(Rec));
5870b57cec5SDimitry Andric   return false;
5880b57cec5SDimitry Andric }
5890b57cec5SDimitry Andric 
resolveArguments(Record * Rec,ArrayRef<ArgumentInit * > ArgValues,SMLoc Loc,ArgValueHandler ArgValueHandler)59006c3fb27SDimitry Andric bool TGParser::resolveArguments(Record *Rec, ArrayRef<ArgumentInit *> ArgValues,
59106c3fb27SDimitry Andric                                 SMLoc Loc, ArgValueHandler ArgValueHandler) {
59206c3fb27SDimitry Andric   ArrayRef<Init *> ArgNames = Rec->getTemplateArgs();
59306c3fb27SDimitry Andric   assert(ArgValues.size() <= ArgNames.size() &&
59406c3fb27SDimitry Andric          "Too many template arguments allowed");
59506c3fb27SDimitry Andric 
59606c3fb27SDimitry Andric   // Loop over the template arguments and handle the (name, value) pair.
59706c3fb27SDimitry Andric   SmallVector<Init *, 2> UnsolvedArgNames(ArgNames);
59806c3fb27SDimitry Andric   for (auto *Arg : ArgValues) {
59906c3fb27SDimitry Andric     Init *ArgName = nullptr;
60006c3fb27SDimitry Andric     Init *ArgValue = Arg->getValue();
60106c3fb27SDimitry Andric     if (Arg->isPositional())
60206c3fb27SDimitry Andric       ArgName = ArgNames[Arg->getIndex()];
60306c3fb27SDimitry Andric     if (Arg->isNamed())
60406c3fb27SDimitry Andric       ArgName = Arg->getName();
60506c3fb27SDimitry Andric 
60606c3fb27SDimitry Andric     // We can only specify the template argument once.
60706c3fb27SDimitry Andric     if (!is_contained(UnsolvedArgNames, ArgName))
60806c3fb27SDimitry Andric       return Error(Loc, "We can only specify the template argument '" +
60906c3fb27SDimitry Andric                             ArgName->getAsUnquotedString() + "' once");
61006c3fb27SDimitry Andric 
61106c3fb27SDimitry Andric     ArgValueHandler(ArgName, ArgValue);
6125f757f3fSDimitry Andric     llvm::erase(UnsolvedArgNames, ArgName);
61306c3fb27SDimitry Andric   }
61406c3fb27SDimitry Andric 
61506c3fb27SDimitry Andric   // For unsolved arguments, if there is no default value, complain.
61606c3fb27SDimitry Andric   for (auto *UnsolvedArgName : UnsolvedArgNames) {
61706c3fb27SDimitry Andric     Init *Default = Rec->getValue(UnsolvedArgName)->getValue();
61806c3fb27SDimitry Andric     if (!Default->isComplete()) {
6198a4dda33SDimitry Andric       std::string Name = UnsolvedArgName->getAsUnquotedString();
6208a4dda33SDimitry Andric       Error(Loc, "value not specified for template argument '" + Name + "'");
6218a4dda33SDimitry Andric       PrintNote(Rec->getFieldLoc(Name),
6228a4dda33SDimitry Andric                 "declared in '" + Rec->getNameInitAsString() + "'");
6238a4dda33SDimitry Andric       return true;
62406c3fb27SDimitry Andric     }
62506c3fb27SDimitry Andric     ArgValueHandler(UnsolvedArgName, Default);
62606c3fb27SDimitry Andric   }
62706c3fb27SDimitry Andric 
62806c3fb27SDimitry Andric   return false;
62906c3fb27SDimitry Andric }
63006c3fb27SDimitry Andric 
63106c3fb27SDimitry Andric /// Resolve the arguments of class and set them to MapResolver.
63206c3fb27SDimitry Andric /// Returns true if failed.
resolveArgumentsOfClass(MapResolver & R,Record * Rec,ArrayRef<ArgumentInit * > ArgValues,SMLoc Loc)63306c3fb27SDimitry Andric bool TGParser::resolveArgumentsOfClass(MapResolver &R, Record *Rec,
63406c3fb27SDimitry Andric                                        ArrayRef<ArgumentInit *> ArgValues,
63506c3fb27SDimitry Andric                                        SMLoc Loc) {
63606c3fb27SDimitry Andric   return resolveArguments(Rec, ArgValues, Loc,
63706c3fb27SDimitry Andric                           [&](Init *Name, Init *Value) { R.set(Name, Value); });
63806c3fb27SDimitry Andric }
63906c3fb27SDimitry Andric 
64006c3fb27SDimitry Andric /// Resolve the arguments of multiclass and store them into SubstStack.
64106c3fb27SDimitry Andric /// Returns true if failed.
resolveArgumentsOfMultiClass(SubstStack & Substs,MultiClass * MC,ArrayRef<ArgumentInit * > ArgValues,Init * DefmName,SMLoc Loc)64206c3fb27SDimitry Andric bool TGParser::resolveArgumentsOfMultiClass(SubstStack &Substs, MultiClass *MC,
64306c3fb27SDimitry Andric                                             ArrayRef<ArgumentInit *> ArgValues,
64406c3fb27SDimitry Andric                                             Init *DefmName, SMLoc Loc) {
64506c3fb27SDimitry Andric   // Add an implicit argument NAME.
64606c3fb27SDimitry Andric   Substs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName);
64706c3fb27SDimitry Andric   return resolveArguments(
64806c3fb27SDimitry Andric       &MC->Rec, ArgValues, Loc,
64906c3fb27SDimitry Andric       [&](Init *Name, Init *Value) { Substs.emplace_back(Name, Value); });
65006c3fb27SDimitry Andric }
65106c3fb27SDimitry Andric 
6520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6530b57cec5SDimitry Andric // Parser Code
6540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6550b57cec5SDimitry Andric 
consume(tgtok::TokKind K)6565ffd83dbSDimitry Andric bool TGParser::consume(tgtok::TokKind K) {
6575ffd83dbSDimitry Andric   if (Lex.getCode() == K) {
6585ffd83dbSDimitry Andric     Lex.Lex();
6595ffd83dbSDimitry Andric     return true;
6605ffd83dbSDimitry Andric   }
6615ffd83dbSDimitry Andric   return false;
6625ffd83dbSDimitry Andric }
6635ffd83dbSDimitry Andric 
6640b57cec5SDimitry Andric /// ParseObjectName - If a valid object name is specified, return it. If no
6650b57cec5SDimitry Andric /// name is specified, return the unset initializer. Return nullptr on parse
6660b57cec5SDimitry Andric /// error.
6670b57cec5SDimitry Andric ///   ObjectName ::= Value [ '#' Value ]*
6680b57cec5SDimitry Andric ///   ObjectName ::= /*empty*/
6690b57cec5SDimitry Andric ///
ParseObjectName(MultiClass * CurMultiClass)6700b57cec5SDimitry Andric Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
6710b57cec5SDimitry Andric   switch (Lex.getCode()) {
6720b57cec5SDimitry Andric   case tgtok::colon:
6730b57cec5SDimitry Andric   case tgtok::semi:
6740b57cec5SDimitry Andric   case tgtok::l_brace:
6750b57cec5SDimitry Andric     // These are all of the tokens that can begin an object body.
6760b57cec5SDimitry Andric     // Some of these can also begin values but we disallow those cases
6770b57cec5SDimitry Andric     // because they are unlikely to be useful.
67881ad6265SDimitry Andric     return UnsetInit::get(Records);
6790b57cec5SDimitry Andric   default:
6800b57cec5SDimitry Andric     break;
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   Record *CurRec = nullptr;
6840b57cec5SDimitry Andric   if (CurMultiClass)
6850b57cec5SDimitry Andric     CurRec = &CurMultiClass->Rec;
6860b57cec5SDimitry Andric 
68781ad6265SDimitry Andric   Init *Name = ParseValue(CurRec, StringRecTy::get(Records), ParseNameMode);
6880b57cec5SDimitry Andric   if (!Name)
6890b57cec5SDimitry Andric     return nullptr;
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   if (CurMultiClass) {
6920b57cec5SDimitry Andric     Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass);
6930b57cec5SDimitry Andric     HasReferenceResolver R(NameStr);
6940b57cec5SDimitry Andric     Name->resolveReferences(R);
6950b57cec5SDimitry Andric     if (!R.found())
69681ad6265SDimitry Andric       Name = BinOpInit::getStrConcat(
69781ad6265SDimitry Andric           VarInit::get(NameStr, StringRecTy::get(Records)), Name);
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   return Name;
7010b57cec5SDimitry Andric }
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric /// ParseClassID - Parse and resolve a reference to a class name.  This returns
7040b57cec5SDimitry Andric /// null on error.
7050b57cec5SDimitry Andric ///
7060b57cec5SDimitry Andric ///    ClassID ::= ID
7070b57cec5SDimitry Andric ///
ParseClassID()7080b57cec5SDimitry Andric Record *TGParser::ParseClassID() {
7090b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Id) {
7100b57cec5SDimitry Andric     TokError("expected name for ClassID");
7110b57cec5SDimitry Andric     return nullptr;
7120b57cec5SDimitry Andric   }
7130b57cec5SDimitry Andric 
7140b57cec5SDimitry Andric   Record *Result = Records.getClass(Lex.getCurStrVal());
7150b57cec5SDimitry Andric   if (!Result) {
7160b57cec5SDimitry Andric     std::string Msg("Couldn't find class '" + Lex.getCurStrVal() + "'");
7170b57cec5SDimitry Andric     if (MultiClasses[Lex.getCurStrVal()].get())
7180b57cec5SDimitry Andric       TokError(Msg + ". Use 'defm' if you meant to use multiclass '" +
7190b57cec5SDimitry Andric                Lex.getCurStrVal() + "'");
7200b57cec5SDimitry Andric     else
7210b57cec5SDimitry Andric       TokError(Msg);
722bdd1243dSDimitry Andric   } else if (TrackReferenceLocs) {
723bdd1243dSDimitry Andric     Result->appendReferenceLoc(Lex.getLocRange());
7240b57cec5SDimitry Andric   }
7250b57cec5SDimitry Andric 
7260b57cec5SDimitry Andric   Lex.Lex();
7270b57cec5SDimitry Andric   return Result;
7280b57cec5SDimitry Andric }
7290b57cec5SDimitry Andric 
7300b57cec5SDimitry Andric /// ParseMultiClassID - Parse and resolve a reference to a multiclass name.
7310b57cec5SDimitry Andric /// This returns null on error.
7320b57cec5SDimitry Andric ///
7330b57cec5SDimitry Andric ///    MultiClassID ::= ID
7340b57cec5SDimitry Andric ///
ParseMultiClassID()7350b57cec5SDimitry Andric MultiClass *TGParser::ParseMultiClassID() {
7360b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Id) {
7370b57cec5SDimitry Andric     TokError("expected name for MultiClassID");
7380b57cec5SDimitry Andric     return nullptr;
7390b57cec5SDimitry Andric   }
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric   MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get();
7420b57cec5SDimitry Andric   if (!Result)
7430b57cec5SDimitry Andric     TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric   Lex.Lex();
7460b57cec5SDimitry Andric   return Result;
7470b57cec5SDimitry Andric }
7480b57cec5SDimitry Andric 
749fe6060f1SDimitry Andric /// ParseSubClassReference - Parse a reference to a subclass or a
750fe6060f1SDimitry Andric /// multiclass. This returns a SubClassRefTy with a null Record* on error.
7510b57cec5SDimitry Andric ///
7520b57cec5SDimitry Andric ///  SubClassRef ::= ClassID
75306c3fb27SDimitry Andric ///  SubClassRef ::= ClassID '<' ArgValueList '>'
7540b57cec5SDimitry Andric ///
7550b57cec5SDimitry Andric SubClassReference TGParser::
ParseSubClassReference(Record * CurRec,bool isDefm)7560b57cec5SDimitry Andric ParseSubClassReference(Record *CurRec, bool isDefm) {
7570b57cec5SDimitry Andric   SubClassReference Result;
7580b57cec5SDimitry Andric   Result.RefRange.Start = Lex.getLoc();
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric   if (isDefm) {
7610b57cec5SDimitry Andric     if (MultiClass *MC = ParseMultiClassID())
7620b57cec5SDimitry Andric       Result.Rec = &MC->Rec;
7630b57cec5SDimitry Andric   } else {
7640b57cec5SDimitry Andric     Result.Rec = ParseClassID();
7650b57cec5SDimitry Andric   }
7660b57cec5SDimitry Andric   if (!Result.Rec) return Result;
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric   // If there is no template arg list, we're done.
7695ffd83dbSDimitry Andric   if (!consume(tgtok::less)) {
7700b57cec5SDimitry Andric     Result.RefRange.End = Lex.getLoc();
7710b57cec5SDimitry Andric     return Result;
7720b57cec5SDimitry Andric   }
7730b57cec5SDimitry Andric 
7745f757f3fSDimitry Andric   if (ParseTemplateArgValueList(Result.TemplateArgs, CurRec, Result.Rec)) {
7750b57cec5SDimitry Andric     Result.Rec = nullptr; // Error parsing value list.
7760b57cec5SDimitry Andric     return Result;
7770b57cec5SDimitry Andric   }
7780b57cec5SDimitry Andric 
779fe6060f1SDimitry Andric   if (CheckTemplateArgValues(Result.TemplateArgs, Result.RefRange.Start,
780fe6060f1SDimitry Andric                              Result.Rec)) {
781fe6060f1SDimitry Andric     Result.Rec = nullptr; // Error checking value list.
7820b57cec5SDimitry Andric     return Result;
7830b57cec5SDimitry Andric   }
7840b57cec5SDimitry Andric 
785fe6060f1SDimitry Andric   Result.RefRange.End = Lex.getLoc();
7860b57cec5SDimitry Andric   return Result;
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric /// ParseSubMultiClassReference - Parse a reference to a subclass or to a
7900b57cec5SDimitry Andric /// templated submulticlass.  This returns a SubMultiClassRefTy with a null
7910b57cec5SDimitry Andric /// Record* on error.
7920b57cec5SDimitry Andric ///
7930b57cec5SDimitry Andric ///  SubMultiClassRef ::= MultiClassID
79406c3fb27SDimitry Andric ///  SubMultiClassRef ::= MultiClassID '<' ArgValueList '>'
7950b57cec5SDimitry Andric ///
7960b57cec5SDimitry Andric SubMultiClassReference TGParser::
ParseSubMultiClassReference(MultiClass * CurMC)7970b57cec5SDimitry Andric ParseSubMultiClassReference(MultiClass *CurMC) {
7980b57cec5SDimitry Andric   SubMultiClassReference Result;
7990b57cec5SDimitry Andric   Result.RefRange.Start = Lex.getLoc();
8000b57cec5SDimitry Andric 
8010b57cec5SDimitry Andric   Result.MC = ParseMultiClassID();
8020b57cec5SDimitry Andric   if (!Result.MC) return Result;
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   // If there is no template arg list, we're done.
8055ffd83dbSDimitry Andric   if (!consume(tgtok::less)) {
8060b57cec5SDimitry Andric     Result.RefRange.End = Lex.getLoc();
8070b57cec5SDimitry Andric     return Result;
8080b57cec5SDimitry Andric   }
8090b57cec5SDimitry Andric 
810fe6060f1SDimitry Andric   if (ParseTemplateArgValueList(Result.TemplateArgs, &CurMC->Rec,
8115f757f3fSDimitry Andric                                 &Result.MC->Rec)) {
8120b57cec5SDimitry Andric     Result.MC = nullptr; // Error parsing value list.
8130b57cec5SDimitry Andric     return Result;
8140b57cec5SDimitry Andric   }
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric   Result.RefRange.End = Lex.getLoc();
8170b57cec5SDimitry Andric 
8180b57cec5SDimitry Andric   return Result;
8190b57cec5SDimitry Andric }
8200b57cec5SDimitry Andric 
82106c3fb27SDimitry Andric /// ParseSliceElement - Parse subscript or range
82206c3fb27SDimitry Andric ///
82306c3fb27SDimitry Andric ///  SliceElement  ::= Value<list<int>>
82406c3fb27SDimitry Andric ///  SliceElement  ::= Value<int>
82506c3fb27SDimitry Andric ///  SliceElement  ::= Value<int> '...' Value<int>
82606c3fb27SDimitry Andric ///  SliceElement  ::= Value<int> '-' Value<int> (deprecated)
82706c3fb27SDimitry Andric ///  SliceElement  ::= Value<int> INTVAL(Negative; deprecated)
82806c3fb27SDimitry Andric ///
82906c3fb27SDimitry Andric /// SliceElement is either IntRecTy, ListRecTy, or nullptr
83006c3fb27SDimitry Andric ///
ParseSliceElement(Record * CurRec)83106c3fb27SDimitry Andric TypedInit *TGParser::ParseSliceElement(Record *CurRec) {
83206c3fb27SDimitry Andric   auto LHSLoc = Lex.getLoc();
83306c3fb27SDimitry Andric   auto *CurVal = ParseValue(CurRec);
83406c3fb27SDimitry Andric   if (!CurVal)
83506c3fb27SDimitry Andric     return nullptr;
83606c3fb27SDimitry Andric   auto *LHS = cast<TypedInit>(CurVal);
83706c3fb27SDimitry Andric 
83806c3fb27SDimitry Andric   TypedInit *RHS = nullptr;
83906c3fb27SDimitry Andric   switch (Lex.getCode()) {
84006c3fb27SDimitry Andric   case tgtok::dotdotdot:
84106c3fb27SDimitry Andric   case tgtok::minus: { // Deprecated
84206c3fb27SDimitry Andric     Lex.Lex();         // eat
84306c3fb27SDimitry Andric     auto RHSLoc = Lex.getLoc();
84406c3fb27SDimitry Andric     CurVal = ParseValue(CurRec);
84506c3fb27SDimitry Andric     if (!CurVal)
84606c3fb27SDimitry Andric       return nullptr;
84706c3fb27SDimitry Andric     RHS = cast<TypedInit>(CurVal);
84806c3fb27SDimitry Andric     if (!isa<IntRecTy>(RHS->getType())) {
84906c3fb27SDimitry Andric       Error(RHSLoc,
85006c3fb27SDimitry Andric             "expected int...int, got " + Twine(RHS->getType()->getAsString()));
85106c3fb27SDimitry Andric       return nullptr;
85206c3fb27SDimitry Andric     }
85306c3fb27SDimitry Andric     break;
85406c3fb27SDimitry Andric   }
85506c3fb27SDimitry Andric   case tgtok::IntVal: { // Deprecated "-num"
85606c3fb27SDimitry Andric     auto i = -Lex.getCurIntVal();
85706c3fb27SDimitry Andric     if (i < 0) {
85806c3fb27SDimitry Andric       TokError("invalid range, cannot be negative");
85906c3fb27SDimitry Andric       return nullptr;
86006c3fb27SDimitry Andric     }
86106c3fb27SDimitry Andric     RHS = IntInit::get(Records, i);
86206c3fb27SDimitry Andric     Lex.Lex(); // eat IntVal
86306c3fb27SDimitry Andric     break;
86406c3fb27SDimitry Andric   }
86506c3fb27SDimitry Andric   default: // Single value (IntRecTy or ListRecTy)
86606c3fb27SDimitry Andric     return LHS;
86706c3fb27SDimitry Andric   }
86806c3fb27SDimitry Andric 
86906c3fb27SDimitry Andric   assert(RHS);
87006c3fb27SDimitry Andric   assert(isa<IntRecTy>(RHS->getType()));
87106c3fb27SDimitry Andric 
87206c3fb27SDimitry Andric   // Closed-interval range <LHS:IntRecTy>...<RHS:IntRecTy>
87306c3fb27SDimitry Andric   if (!isa<IntRecTy>(LHS->getType())) {
87406c3fb27SDimitry Andric     Error(LHSLoc,
87506c3fb27SDimitry Andric           "expected int...int, got " + Twine(LHS->getType()->getAsString()));
87606c3fb27SDimitry Andric     return nullptr;
87706c3fb27SDimitry Andric   }
87806c3fb27SDimitry Andric 
87906c3fb27SDimitry Andric   return cast<TypedInit>(BinOpInit::get(BinOpInit::RANGEC, LHS, RHS,
88006c3fb27SDimitry Andric                                         IntRecTy::get(Records)->getListTy())
88106c3fb27SDimitry Andric                              ->Fold(CurRec));
88206c3fb27SDimitry Andric }
88306c3fb27SDimitry Andric 
88406c3fb27SDimitry Andric /// ParseSliceElements - Parse subscripts in square brackets.
88506c3fb27SDimitry Andric ///
88606c3fb27SDimitry Andric ///  SliceElements ::= ( SliceElement ',' )* SliceElement ','?
88706c3fb27SDimitry Andric ///
88806c3fb27SDimitry Andric /// SliceElement is either IntRecTy, ListRecTy, or nullptr
88906c3fb27SDimitry Andric ///
89006c3fb27SDimitry Andric /// Returns ListRecTy by defaut.
89106c3fb27SDimitry Andric /// Returns IntRecTy if;
89206c3fb27SDimitry Andric ///  - Single=true
89306c3fb27SDimitry Andric ///  - SliceElements is Value<int> w/o trailing comma
89406c3fb27SDimitry Andric ///
ParseSliceElements(Record * CurRec,bool Single)89506c3fb27SDimitry Andric TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
89606c3fb27SDimitry Andric   TypedInit *CurVal;
89706c3fb27SDimitry Andric   SmallVector<Init *, 2> Elems;       // int
89806c3fb27SDimitry Andric   SmallVector<TypedInit *, 2> Slices; // list<int>
89906c3fb27SDimitry Andric 
90006c3fb27SDimitry Andric   auto FlushElems = [&] {
90106c3fb27SDimitry Andric     if (!Elems.empty()) {
90206c3fb27SDimitry Andric       Slices.push_back(ListInit::get(Elems, IntRecTy::get(Records)));
90306c3fb27SDimitry Andric       Elems.clear();
90406c3fb27SDimitry Andric     }
90506c3fb27SDimitry Andric   };
90606c3fb27SDimitry Andric 
90706c3fb27SDimitry Andric   do {
90806c3fb27SDimitry Andric     auto LHSLoc = Lex.getLoc();
90906c3fb27SDimitry Andric     CurVal = ParseSliceElement(CurRec);
91006c3fb27SDimitry Andric     if (!CurVal)
91106c3fb27SDimitry Andric       return nullptr;
91206c3fb27SDimitry Andric     auto *CurValTy = CurVal->getType();
91306c3fb27SDimitry Andric 
91406c3fb27SDimitry Andric     if (auto *ListValTy = dyn_cast<ListRecTy>(CurValTy)) {
91506c3fb27SDimitry Andric       if (!isa<IntRecTy>(ListValTy->getElementType())) {
91606c3fb27SDimitry Andric         Error(LHSLoc,
91706c3fb27SDimitry Andric               "expected list<int>, got " + Twine(ListValTy->getAsString()));
91806c3fb27SDimitry Andric         return nullptr;
91906c3fb27SDimitry Andric       }
92006c3fb27SDimitry Andric 
92106c3fb27SDimitry Andric       FlushElems();
92206c3fb27SDimitry Andric       Slices.push_back(CurVal);
92306c3fb27SDimitry Andric       Single = false;
92406c3fb27SDimitry Andric       CurVal = nullptr;
92506c3fb27SDimitry Andric     } else if (!isa<IntRecTy>(CurValTy)) {
92606c3fb27SDimitry Andric       Error(LHSLoc,
92706c3fb27SDimitry Andric             "unhandled type " + Twine(CurValTy->getAsString()) + " in range");
92806c3fb27SDimitry Andric       return nullptr;
92906c3fb27SDimitry Andric     }
93006c3fb27SDimitry Andric 
93106c3fb27SDimitry Andric     if (Lex.getCode() != tgtok::comma)
93206c3fb27SDimitry Andric       break;
93306c3fb27SDimitry Andric 
93406c3fb27SDimitry Andric     Lex.Lex(); // eat comma
93506c3fb27SDimitry Andric 
93606c3fb27SDimitry Andric     // `[i,]` is not LISTELEM but LISTSLICE
93706c3fb27SDimitry Andric     Single = false;
93806c3fb27SDimitry Andric     if (CurVal)
93906c3fb27SDimitry Andric       Elems.push_back(CurVal);
94006c3fb27SDimitry Andric     CurVal = nullptr;
94106c3fb27SDimitry Andric   } while (Lex.getCode() != tgtok::r_square);
94206c3fb27SDimitry Andric 
94306c3fb27SDimitry Andric   if (CurVal) {
94406c3fb27SDimitry Andric     // LISTELEM
94506c3fb27SDimitry Andric     if (Single)
94606c3fb27SDimitry Andric       return CurVal;
94706c3fb27SDimitry Andric 
94806c3fb27SDimitry Andric     Elems.push_back(CurVal);
94906c3fb27SDimitry Andric   }
95006c3fb27SDimitry Andric 
95106c3fb27SDimitry Andric   FlushElems();
95206c3fb27SDimitry Andric 
95306c3fb27SDimitry Andric   // Concatenate lists in Slices
95406c3fb27SDimitry Andric   TypedInit *Result = nullptr;
95506c3fb27SDimitry Andric   for (auto *Slice : Slices) {
95606c3fb27SDimitry Andric     Result = (Result ? cast<TypedInit>(BinOpInit::getListConcat(Result, Slice))
95706c3fb27SDimitry Andric                      : Slice);
95806c3fb27SDimitry Andric   }
95906c3fb27SDimitry Andric 
96006c3fb27SDimitry Andric   return Result;
96106c3fb27SDimitry Andric }
96206c3fb27SDimitry Andric 
9630b57cec5SDimitry Andric /// ParseRangePiece - Parse a bit/value range.
9640b57cec5SDimitry Andric ///   RangePiece ::= INTVAL
965e8d8bef9SDimitry Andric ///   RangePiece ::= INTVAL '...' INTVAL
9660b57cec5SDimitry Andric ///   RangePiece ::= INTVAL '-' INTVAL
9670b57cec5SDimitry Andric ///   RangePiece ::= INTVAL INTVAL
968e8d8bef9SDimitry Andric // The last two forms are deprecated.
ParseRangePiece(SmallVectorImpl<unsigned> & Ranges,TypedInit * FirstItem)9690b57cec5SDimitry Andric bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
9700b57cec5SDimitry Andric                                TypedInit *FirstItem) {
9710b57cec5SDimitry Andric   Init *CurVal = FirstItem;
9720b57cec5SDimitry Andric   if (!CurVal)
9730b57cec5SDimitry Andric     CurVal = ParseValue(nullptr);
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric   IntInit *II = dyn_cast_or_null<IntInit>(CurVal);
9760b57cec5SDimitry Andric   if (!II)
9770b57cec5SDimitry Andric     return TokError("expected integer or bitrange");
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric   int64_t Start = II->getValue();
9800b57cec5SDimitry Andric   int64_t End;
9810b57cec5SDimitry Andric 
9820b57cec5SDimitry Andric   if (Start < 0)
9830b57cec5SDimitry Andric     return TokError("invalid range, cannot be negative");
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   switch (Lex.getCode()) {
9860b57cec5SDimitry Andric   default:
9870b57cec5SDimitry Andric     Ranges.push_back(Start);
9880b57cec5SDimitry Andric     return false;
989e8d8bef9SDimitry Andric 
990e8d8bef9SDimitry Andric   case tgtok::dotdotdot:
9910b57cec5SDimitry Andric   case tgtok::minus: {
9920b57cec5SDimitry Andric     Lex.Lex(); // eat
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric     Init *I_End = ParseValue(nullptr);
9950b57cec5SDimitry Andric     IntInit *II_End = dyn_cast_or_null<IntInit>(I_End);
9960b57cec5SDimitry Andric     if (!II_End) {
9970b57cec5SDimitry Andric       TokError("expected integer value as end of range");
9980b57cec5SDimitry Andric       return true;
9990b57cec5SDimitry Andric     }
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric     End = II_End->getValue();
10020b57cec5SDimitry Andric     break;
10030b57cec5SDimitry Andric   }
10040b57cec5SDimitry Andric   case tgtok::IntVal: {
10050b57cec5SDimitry Andric     End = -Lex.getCurIntVal();
10060b57cec5SDimitry Andric     Lex.Lex();
10070b57cec5SDimitry Andric     break;
10080b57cec5SDimitry Andric   }
10090b57cec5SDimitry Andric   }
10100b57cec5SDimitry Andric   if (End < 0)
10110b57cec5SDimitry Andric     return TokError("invalid range, cannot be negative");
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric   // Add to the range.
10140b57cec5SDimitry Andric   if (Start < End)
10150b57cec5SDimitry Andric     for (; Start <= End; ++Start)
10160b57cec5SDimitry Andric       Ranges.push_back(Start);
10170b57cec5SDimitry Andric   else
10180b57cec5SDimitry Andric     for (; Start >= End; --Start)
10190b57cec5SDimitry Andric       Ranges.push_back(Start);
10200b57cec5SDimitry Andric   return false;
10210b57cec5SDimitry Andric }
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric /// ParseRangeList - Parse a list of scalars and ranges into scalar values.
10240b57cec5SDimitry Andric ///
10250b57cec5SDimitry Andric ///   RangeList ::= RangePiece (',' RangePiece)*
10260b57cec5SDimitry Andric ///
ParseRangeList(SmallVectorImpl<unsigned> & Result)10270b57cec5SDimitry Andric void TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) {
10280b57cec5SDimitry Andric   // Parse the first piece.
10290b57cec5SDimitry Andric   if (ParseRangePiece(Result)) {
10300b57cec5SDimitry Andric     Result.clear();
10310b57cec5SDimitry Andric     return;
10320b57cec5SDimitry Andric   }
10335ffd83dbSDimitry Andric   while (consume(tgtok::comma))
10340b57cec5SDimitry Andric     // Parse the next range piece.
10350b57cec5SDimitry Andric     if (ParseRangePiece(Result)) {
10360b57cec5SDimitry Andric       Result.clear();
10370b57cec5SDimitry Andric       return;
10380b57cec5SDimitry Andric     }
10390b57cec5SDimitry Andric }
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric /// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.
10420b57cec5SDimitry Andric ///   OptionalRangeList ::= '<' RangeList '>'
10430b57cec5SDimitry Andric ///   OptionalRangeList ::= /*empty*/
ParseOptionalRangeList(SmallVectorImpl<unsigned> & Ranges)10440b57cec5SDimitry Andric bool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) {
10450b57cec5SDimitry Andric   SMLoc StartLoc = Lex.getLoc();
10465ffd83dbSDimitry Andric   if (!consume(tgtok::less))
10475ffd83dbSDimitry Andric     return false;
10480b57cec5SDimitry Andric 
10490b57cec5SDimitry Andric   // Parse the range list.
10500b57cec5SDimitry Andric   ParseRangeList(Ranges);
10510b57cec5SDimitry Andric   if (Ranges.empty()) return true;
10520b57cec5SDimitry Andric 
10535ffd83dbSDimitry Andric   if (!consume(tgtok::greater)) {
10540b57cec5SDimitry Andric     TokError("expected '>' at end of range list");
10550b57cec5SDimitry Andric     return Error(StartLoc, "to match this '<'");
10560b57cec5SDimitry Andric   }
10570b57cec5SDimitry Andric   return false;
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric /// ParseOptionalBitList - Parse either a bit list in {}'s or nothing.
10610b57cec5SDimitry Andric ///   OptionalBitList ::= '{' RangeList '}'
10620b57cec5SDimitry Andric ///   OptionalBitList ::= /*empty*/
ParseOptionalBitList(SmallVectorImpl<unsigned> & Ranges)10630b57cec5SDimitry Andric bool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) {
10640b57cec5SDimitry Andric   SMLoc StartLoc = Lex.getLoc();
10655ffd83dbSDimitry Andric   if (!consume(tgtok::l_brace))
10665ffd83dbSDimitry Andric     return false;
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric   // Parse the range list.
10690b57cec5SDimitry Andric   ParseRangeList(Ranges);
10700b57cec5SDimitry Andric   if (Ranges.empty()) return true;
10710b57cec5SDimitry Andric 
10725ffd83dbSDimitry Andric   if (!consume(tgtok::r_brace)) {
10730b57cec5SDimitry Andric     TokError("expected '}' at end of bit list");
10740b57cec5SDimitry Andric     return Error(StartLoc, "to match this '{'");
10750b57cec5SDimitry Andric   }
10760b57cec5SDimitry Andric   return false;
10770b57cec5SDimitry Andric }
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric /// ParseType - Parse and return a tblgen type.  This returns null on error.
10800b57cec5SDimitry Andric ///
10810b57cec5SDimitry Andric ///   Type ::= STRING                       // string type
10820b57cec5SDimitry Andric ///   Type ::= CODE                         // code type
10830b57cec5SDimitry Andric ///   Type ::= BIT                          // bit type
10840b57cec5SDimitry Andric ///   Type ::= BITS '<' INTVAL '>'          // bits<x> type
10850b57cec5SDimitry Andric ///   Type ::= INT                          // int type
10860b57cec5SDimitry Andric ///   Type ::= LIST '<' Type '>'            // list<x> type
10870b57cec5SDimitry Andric ///   Type ::= DAG                          // dag type
10880b57cec5SDimitry Andric ///   Type ::= ClassID                      // Record Type
10890b57cec5SDimitry Andric ///
ParseType()10900b57cec5SDimitry Andric RecTy *TGParser::ParseType() {
10910b57cec5SDimitry Andric   switch (Lex.getCode()) {
10920b57cec5SDimitry Andric   default: TokError("Unknown token when expecting a type"); return nullptr;
1093e8d8bef9SDimitry Andric   case tgtok::String:
109481ad6265SDimitry Andric   case tgtok::Code:
109581ad6265SDimitry Andric     Lex.Lex();
109681ad6265SDimitry Andric     return StringRecTy::get(Records);
109781ad6265SDimitry Andric   case tgtok::Bit:
109881ad6265SDimitry Andric     Lex.Lex();
109981ad6265SDimitry Andric     return BitRecTy::get(Records);
110081ad6265SDimitry Andric   case tgtok::Int:
110181ad6265SDimitry Andric     Lex.Lex();
110281ad6265SDimitry Andric     return IntRecTy::get(Records);
110381ad6265SDimitry Andric   case tgtok::Dag:
110481ad6265SDimitry Andric     Lex.Lex();
110581ad6265SDimitry Andric     return DagRecTy::get(Records);
1106*0fca6ea1SDimitry Andric   case tgtok::Id: {
1107*0fca6ea1SDimitry Andric     auto I = TypeAliases.find(Lex.getCurStrVal());
1108*0fca6ea1SDimitry Andric     if (I != TypeAliases.end()) {
1109*0fca6ea1SDimitry Andric       Lex.Lex();
1110*0fca6ea1SDimitry Andric       return I->second;
1111*0fca6ea1SDimitry Andric     }
111281ad6265SDimitry Andric     if (Record *R = ParseClassID())
111381ad6265SDimitry Andric       return RecordRecTy::get(R);
11140b57cec5SDimitry Andric     TokError("unknown class name");
11150b57cec5SDimitry Andric     return nullptr;
1116*0fca6ea1SDimitry Andric   }
11170b57cec5SDimitry Andric   case tgtok::Bits: {
11180b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::less) { // Eat 'bits'
11190b57cec5SDimitry Andric       TokError("expected '<' after bits type");
11200b57cec5SDimitry Andric       return nullptr;
11210b57cec5SDimitry Andric     }
11220b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
11230b57cec5SDimitry Andric       TokError("expected integer in bits<n> type");
11240b57cec5SDimitry Andric       return nullptr;
11250b57cec5SDimitry Andric     }
11260b57cec5SDimitry Andric     uint64_t Val = Lex.getCurIntVal();
11270b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::greater) { // Eat count.
11280b57cec5SDimitry Andric       TokError("expected '>' at end of bits<n> type");
11290b57cec5SDimitry Andric       return nullptr;
11300b57cec5SDimitry Andric     }
11310b57cec5SDimitry Andric     Lex.Lex();  // Eat '>'
113281ad6265SDimitry Andric     return BitsRecTy::get(Records, Val);
11330b57cec5SDimitry Andric   }
11340b57cec5SDimitry Andric   case tgtok::List: {
11350b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::less) { // Eat 'bits'
11360b57cec5SDimitry Andric       TokError("expected '<' after list type");
11370b57cec5SDimitry Andric       return nullptr;
11380b57cec5SDimitry Andric     }
11390b57cec5SDimitry Andric     Lex.Lex();  // Eat '<'
11400b57cec5SDimitry Andric     RecTy *SubType = ParseType();
11410b57cec5SDimitry Andric     if (!SubType) return nullptr;
11420b57cec5SDimitry Andric 
11435ffd83dbSDimitry Andric     if (!consume(tgtok::greater)) {
11440b57cec5SDimitry Andric       TokError("expected '>' at end of list<ty> type");
11450b57cec5SDimitry Andric       return nullptr;
11460b57cec5SDimitry Andric     }
11470b57cec5SDimitry Andric     return ListRecTy::get(SubType);
11480b57cec5SDimitry Andric   }
11490b57cec5SDimitry Andric   }
11500b57cec5SDimitry Andric }
11510b57cec5SDimitry Andric 
1152e8d8bef9SDimitry Andric /// ParseIDValue
ParseIDValue(Record * CurRec,StringInit * Name,SMRange NameLoc,IDParseMode Mode)1153bdd1243dSDimitry Andric Init *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMRange NameLoc,
11540b57cec5SDimitry Andric                              IDParseMode Mode) {
115506c3fb27SDimitry Andric   if (Init *I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
115606c3fb27SDimitry Andric                                  TrackReferenceLocs))
1157480093f4SDimitry Andric     return I;
1158480093f4SDimitry Andric 
11590b57cec5SDimitry Andric   if (Mode == ParseNameMode)
11600b57cec5SDimitry Andric     return Name;
11610b57cec5SDimitry Andric 
1162bdd1243dSDimitry Andric   if (Init *I = Records.getGlobal(Name->getValue())) {
1163bdd1243dSDimitry Andric     // Add a reference to the global if it's a record.
1164bdd1243dSDimitry Andric     if (TrackReferenceLocs) {
1165bdd1243dSDimitry Andric       if (auto *Def = dyn_cast<DefInit>(I))
1166bdd1243dSDimitry Andric         Def->getDef()->appendReferenceLoc(NameLoc);
1167bdd1243dSDimitry Andric     }
11680b57cec5SDimitry Andric     return I;
1169bdd1243dSDimitry Andric   }
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric   // Allow self-references of concrete defs, but delay the lookup so that we
11720b57cec5SDimitry Andric   // get the correct type.
11730b57cec5SDimitry Andric   if (CurRec && !CurRec->isClass() && !CurMultiClass &&
11740b57cec5SDimitry Andric       CurRec->getNameInit() == Name)
11750b57cec5SDimitry Andric     return UnOpInit::get(UnOpInit::CAST, Name, CurRec->getType());
11760b57cec5SDimitry Andric 
1177bdd1243dSDimitry Andric   Error(NameLoc.Start, "Variable not defined: '" + Name->getValue() + "'");
11780b57cec5SDimitry Andric   return nullptr;
11790b57cec5SDimitry Andric }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric /// ParseOperation - Parse an operator.  This returns null on error.
11820b57cec5SDimitry Andric ///
11830b57cec5SDimitry Andric /// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
11840b57cec5SDimitry Andric ///
ParseOperation(Record * CurRec,RecTy * ItemType)11850b57cec5SDimitry Andric Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
11860b57cec5SDimitry Andric   switch (Lex.getCode()) {
11870b57cec5SDimitry Andric   default:
1188e8d8bef9SDimitry Andric     TokError("unknown bang operator");
11890b57cec5SDimitry Andric     return nullptr;
1190e8d8bef9SDimitry Andric   case tgtok::XNOT:
119106c3fb27SDimitry Andric   case tgtok::XToLower:
119206c3fb27SDimitry Andric   case tgtok::XToUpper:
1193bdd1243dSDimitry Andric   case tgtok::XLOG2:
11940b57cec5SDimitry Andric   case tgtok::XHead:
11950b57cec5SDimitry Andric   case tgtok::XTail:
11960b57cec5SDimitry Andric   case tgtok::XSize:
11970b57cec5SDimitry Andric   case tgtok::XEmpty:
1198480093f4SDimitry Andric   case tgtok::XCast:
11995f757f3fSDimitry Andric   case tgtok::XRepr:
1200e8d8bef9SDimitry Andric   case tgtok::XGetDagOp: { // Value ::= !unop '(' Value ')'
12010b57cec5SDimitry Andric     UnOpInit::UnaryOp Code;
12020b57cec5SDimitry Andric     RecTy *Type = nullptr;
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric     switch (Lex.getCode()) {
12050b57cec5SDimitry Andric     default: llvm_unreachable("Unhandled code!");
12060b57cec5SDimitry Andric     case tgtok::XCast:
12070b57cec5SDimitry Andric       Lex.Lex();  // eat the operation
12080b57cec5SDimitry Andric       Code = UnOpInit::CAST;
12090b57cec5SDimitry Andric 
12100b57cec5SDimitry Andric       Type = ParseOperatorType();
12110b57cec5SDimitry Andric 
12120b57cec5SDimitry Andric       if (!Type) {
12130b57cec5SDimitry Andric         TokError("did not get type for unary operator");
12140b57cec5SDimitry Andric         return nullptr;
12150b57cec5SDimitry Andric       }
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric       break;
12185f757f3fSDimitry Andric     case tgtok::XRepr:
12195f757f3fSDimitry Andric       Lex.Lex(); // eat the operation
12205f757f3fSDimitry Andric       Code = UnOpInit::REPR;
12215f757f3fSDimitry Andric       Type = StringRecTy::get(Records);
12225f757f3fSDimitry Andric       break;
122306c3fb27SDimitry Andric     case tgtok::XToLower:
122406c3fb27SDimitry Andric       Lex.Lex(); // eat the operation
122506c3fb27SDimitry Andric       Code = UnOpInit::TOLOWER;
122606c3fb27SDimitry Andric       Type = StringRecTy::get(Records);
122706c3fb27SDimitry Andric       break;
122806c3fb27SDimitry Andric     case tgtok::XToUpper:
122906c3fb27SDimitry Andric       Lex.Lex(); // eat the operation
123006c3fb27SDimitry Andric       Code = UnOpInit::TOUPPER;
123106c3fb27SDimitry Andric       Type = StringRecTy::get(Records);
123206c3fb27SDimitry Andric       break;
1233e8d8bef9SDimitry Andric     case tgtok::XNOT:
1234e8d8bef9SDimitry Andric       Lex.Lex();  // eat the operation
1235e8d8bef9SDimitry Andric       Code = UnOpInit::NOT;
123681ad6265SDimitry Andric       Type = IntRecTy::get(Records);
1237e8d8bef9SDimitry Andric       break;
1238bdd1243dSDimitry Andric     case tgtok::XLOG2:
1239bdd1243dSDimitry Andric       Lex.Lex();  // eat the operation
1240bdd1243dSDimitry Andric       Code = UnOpInit::LOG2;
1241bdd1243dSDimitry Andric       Type = IntRecTy::get(Records);
1242bdd1243dSDimitry Andric       break;
12430b57cec5SDimitry Andric     case tgtok::XHead:
12440b57cec5SDimitry Andric       Lex.Lex();  // eat the operation
12450b57cec5SDimitry Andric       Code = UnOpInit::HEAD;
12460b57cec5SDimitry Andric       break;
12470b57cec5SDimitry Andric     case tgtok::XTail:
12480b57cec5SDimitry Andric       Lex.Lex();  // eat the operation
12490b57cec5SDimitry Andric       Code = UnOpInit::TAIL;
12500b57cec5SDimitry Andric       break;
12510b57cec5SDimitry Andric     case tgtok::XSize:
12520b57cec5SDimitry Andric       Lex.Lex();
12530b57cec5SDimitry Andric       Code = UnOpInit::SIZE;
125481ad6265SDimitry Andric       Type = IntRecTy::get(Records);
12550b57cec5SDimitry Andric       break;
12560b57cec5SDimitry Andric     case tgtok::XEmpty:
12570b57cec5SDimitry Andric       Lex.Lex();  // eat the operation
12580b57cec5SDimitry Andric       Code = UnOpInit::EMPTY;
125981ad6265SDimitry Andric       Type = IntRecTy::get(Records);
12600b57cec5SDimitry Andric       break;
1261e8d8bef9SDimitry Andric     case tgtok::XGetDagOp:
1262480093f4SDimitry Andric       Lex.Lex();  // eat the operation
1263480093f4SDimitry Andric       if (Lex.getCode() == tgtok::less) {
1264480093f4SDimitry Andric         // Parse an optional type suffix, so that you can say
1265e8d8bef9SDimitry Andric         // !getdagop<BaseClass>(someDag) as a shorthand for
1266e8d8bef9SDimitry Andric         // !cast<BaseClass>(!getdagop(someDag)).
1267480093f4SDimitry Andric         Type = ParseOperatorType();
1268480093f4SDimitry Andric 
1269480093f4SDimitry Andric         if (!Type) {
1270480093f4SDimitry Andric           TokError("did not get type for unary operator");
1271480093f4SDimitry Andric           return nullptr;
1272480093f4SDimitry Andric         }
1273480093f4SDimitry Andric 
1274480093f4SDimitry Andric         if (!isa<RecordRecTy>(Type)) {
1275e8d8bef9SDimitry Andric           TokError("type for !getdagop must be a record type");
1276480093f4SDimitry Andric           // but keep parsing, to consume the operand
1277480093f4SDimitry Andric         }
1278480093f4SDimitry Andric       } else {
127981ad6265SDimitry Andric         Type = RecordRecTy::get(Records, {});
1280480093f4SDimitry Andric       }
1281e8d8bef9SDimitry Andric       Code = UnOpInit::GETDAGOP;
1282480093f4SDimitry Andric       break;
12830b57cec5SDimitry Andric     }
12845ffd83dbSDimitry Andric     if (!consume(tgtok::l_paren)) {
12850b57cec5SDimitry Andric       TokError("expected '(' after unary operator");
12860b57cec5SDimitry Andric       return nullptr;
12870b57cec5SDimitry Andric     }
12880b57cec5SDimitry Andric 
12890b57cec5SDimitry Andric     Init *LHS = ParseValue(CurRec);
12900b57cec5SDimitry Andric     if (!LHS) return nullptr;
12910b57cec5SDimitry Andric 
1292e8d8bef9SDimitry Andric     if (Code == UnOpInit::EMPTY || Code == UnOpInit::SIZE) {
12930b57cec5SDimitry Andric       ListInit *LHSl = dyn_cast<ListInit>(LHS);
12940b57cec5SDimitry Andric       StringInit *LHSs = dyn_cast<StringInit>(LHS);
1295e8d8bef9SDimitry Andric       DagInit *LHSd = dyn_cast<DagInit>(LHS);
12960b57cec5SDimitry Andric       TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
1297e8d8bef9SDimitry Andric       if (!LHSl && !LHSs && !LHSd && !LHSt) {
1298e8d8bef9SDimitry Andric         TokError("expected string, list, or dag type argument in unary operator");
12990b57cec5SDimitry Andric         return nullptr;
13000b57cec5SDimitry Andric       }
13010b57cec5SDimitry Andric       if (LHSt) {
13020b57cec5SDimitry Andric         ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
13030b57cec5SDimitry Andric         StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType());
1304e8d8bef9SDimitry Andric         DagRecTy *DType = dyn_cast<DagRecTy>(LHSt->getType());
1305e8d8bef9SDimitry Andric         if (!LType && !SType && !DType) {
1306e8d8bef9SDimitry Andric           TokError("expected string, list, or dag type argument in unary operator");
13070b57cec5SDimitry Andric           return nullptr;
13080b57cec5SDimitry Andric         }
13090b57cec5SDimitry Andric       }
1310e8d8bef9SDimitry Andric     }
13110b57cec5SDimitry Andric 
1312e8d8bef9SDimitry Andric     if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) {
1313e8d8bef9SDimitry Andric       ListInit *LHSl = dyn_cast<ListInit>(LHS);
1314e8d8bef9SDimitry Andric       TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
13150b57cec5SDimitry Andric       if (!LHSl && !LHSt) {
13160b57cec5SDimitry Andric         TokError("expected list type argument in unary operator");
13170b57cec5SDimitry Andric         return nullptr;
13180b57cec5SDimitry Andric       }
1319e8d8bef9SDimitry Andric       if (LHSt) {
1320e8d8bef9SDimitry Andric         ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
1321e8d8bef9SDimitry Andric         if (!LType) {
1322e8d8bef9SDimitry Andric           TokError("expected list type argument in unary operator");
1323e8d8bef9SDimitry Andric           return nullptr;
1324e8d8bef9SDimitry Andric         }
13250b57cec5SDimitry Andric       }
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric       if (LHSl && LHSl->empty()) {
13280b57cec5SDimitry Andric         TokError("empty list argument in unary operator");
13290b57cec5SDimitry Andric         return nullptr;
13300b57cec5SDimitry Andric       }
13310b57cec5SDimitry Andric       if (LHSl) {
13320b57cec5SDimitry Andric         Init *Item = LHSl->getElement(0);
13330b57cec5SDimitry Andric         TypedInit *Itemt = dyn_cast<TypedInit>(Item);
13340b57cec5SDimitry Andric         if (!Itemt) {
13350b57cec5SDimitry Andric           TokError("untyped list element in unary operator");
13360b57cec5SDimitry Andric           return nullptr;
13370b57cec5SDimitry Andric         }
13380b57cec5SDimitry Andric         Type = (Code == UnOpInit::HEAD) ? Itemt->getType()
13390b57cec5SDimitry Andric                                         : ListRecTy::get(Itemt->getType());
13400b57cec5SDimitry Andric       } else {
13410b57cec5SDimitry Andric         assert(LHSt && "expected list type argument in unary operator");
13420b57cec5SDimitry Andric         ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType());
13430b57cec5SDimitry Andric         Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType;
13440b57cec5SDimitry Andric       }
13450b57cec5SDimitry Andric     }
13460b57cec5SDimitry Andric 
13475ffd83dbSDimitry Andric     if (!consume(tgtok::r_paren)) {
13480b57cec5SDimitry Andric       TokError("expected ')' in unary operator");
13490b57cec5SDimitry Andric       return nullptr;
13500b57cec5SDimitry Andric     }
13510b57cec5SDimitry Andric     return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec);
13520b57cec5SDimitry Andric   }
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric   case tgtok::XIsA: {
13550b57cec5SDimitry Andric     // Value ::= !isa '<' Type '>' '(' Value ')'
13560b57cec5SDimitry Andric     Lex.Lex(); // eat the operation
13570b57cec5SDimitry Andric 
13580b57cec5SDimitry Andric     RecTy *Type = ParseOperatorType();
13590b57cec5SDimitry Andric     if (!Type)
13600b57cec5SDimitry Andric       return nullptr;
13610b57cec5SDimitry Andric 
13625ffd83dbSDimitry Andric     if (!consume(tgtok::l_paren)) {
13630b57cec5SDimitry Andric       TokError("expected '(' after type of !isa");
13640b57cec5SDimitry Andric       return nullptr;
13650b57cec5SDimitry Andric     }
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric     Init *LHS = ParseValue(CurRec);
13680b57cec5SDimitry Andric     if (!LHS)
13690b57cec5SDimitry Andric       return nullptr;
13700b57cec5SDimitry Andric 
13715ffd83dbSDimitry Andric     if (!consume(tgtok::r_paren)) {
13720b57cec5SDimitry Andric       TokError("expected ')' in !isa");
13730b57cec5SDimitry Andric       return nullptr;
13740b57cec5SDimitry Andric     }
13750b57cec5SDimitry Andric 
13760b57cec5SDimitry Andric     return (IsAOpInit::get(Type, LHS))->Fold();
13770b57cec5SDimitry Andric   }
13780b57cec5SDimitry Andric 
137981ad6265SDimitry Andric   case tgtok::XExists: {
138081ad6265SDimitry Andric     // Value ::= !exists '<' Type '>' '(' Value ')'
138181ad6265SDimitry Andric     Lex.Lex(); // eat the operation
138281ad6265SDimitry Andric 
138381ad6265SDimitry Andric     RecTy *Type = ParseOperatorType();
138481ad6265SDimitry Andric     if (!Type)
138581ad6265SDimitry Andric       return nullptr;
138681ad6265SDimitry Andric 
138781ad6265SDimitry Andric     if (!consume(tgtok::l_paren)) {
138881ad6265SDimitry Andric       TokError("expected '(' after type of !exists");
138981ad6265SDimitry Andric       return nullptr;
139081ad6265SDimitry Andric     }
139181ad6265SDimitry Andric 
139281ad6265SDimitry Andric     SMLoc ExprLoc = Lex.getLoc();
139381ad6265SDimitry Andric     Init *Expr = ParseValue(CurRec);
139481ad6265SDimitry Andric     if (!Expr)
139581ad6265SDimitry Andric       return nullptr;
139681ad6265SDimitry Andric 
139781ad6265SDimitry Andric     TypedInit *ExprType = dyn_cast<TypedInit>(Expr);
139881ad6265SDimitry Andric     if (!ExprType) {
139981ad6265SDimitry Andric       Error(ExprLoc, "expected string type argument in !exists operator");
140081ad6265SDimitry Andric       return nullptr;
140181ad6265SDimitry Andric     }
140281ad6265SDimitry Andric 
140381ad6265SDimitry Andric     RecordRecTy *RecType = dyn_cast<RecordRecTy>(ExprType->getType());
140481ad6265SDimitry Andric     if (RecType) {
140581ad6265SDimitry Andric       Error(ExprLoc,
140681ad6265SDimitry Andric             "expected string type argument in !exists operator, please "
140781ad6265SDimitry Andric             "use !isa instead");
140881ad6265SDimitry Andric       return nullptr;
140981ad6265SDimitry Andric     }
141081ad6265SDimitry Andric 
141181ad6265SDimitry Andric     StringRecTy *SType = dyn_cast<StringRecTy>(ExprType->getType());
141281ad6265SDimitry Andric     if (!SType) {
141381ad6265SDimitry Andric       Error(ExprLoc, "expected string type argument in !exists operator");
141481ad6265SDimitry Andric       return nullptr;
141581ad6265SDimitry Andric     }
141681ad6265SDimitry Andric 
141781ad6265SDimitry Andric     if (!consume(tgtok::r_paren)) {
141881ad6265SDimitry Andric       TokError("expected ')' in !exists");
141981ad6265SDimitry Andric       return nullptr;
142081ad6265SDimitry Andric     }
142181ad6265SDimitry Andric 
142281ad6265SDimitry Andric     return (ExistsOpInit::get(Type, Expr))->Fold(CurRec);
142381ad6265SDimitry Andric   }
142481ad6265SDimitry Andric 
14250b57cec5SDimitry Andric   case tgtok::XConcat:
14260b57cec5SDimitry Andric   case tgtok::XADD:
1427e8d8bef9SDimitry Andric   case tgtok::XSUB:
14280b57cec5SDimitry Andric   case tgtok::XMUL:
1429bdd1243dSDimitry Andric   case tgtok::XDIV:
14300b57cec5SDimitry Andric   case tgtok::XAND:
14310b57cec5SDimitry Andric   case tgtok::XOR:
1432e8d8bef9SDimitry Andric   case tgtok::XXOR:
14330b57cec5SDimitry Andric   case tgtok::XSRA:
14340b57cec5SDimitry Andric   case tgtok::XSRL:
14350b57cec5SDimitry Andric   case tgtok::XSHL:
14360b57cec5SDimitry Andric   case tgtok::XEq:
14370b57cec5SDimitry Andric   case tgtok::XNe:
14380b57cec5SDimitry Andric   case tgtok::XLe:
14390b57cec5SDimitry Andric   case tgtok::XLt:
14400b57cec5SDimitry Andric   case tgtok::XGe:
14410b57cec5SDimitry Andric   case tgtok::XGt:
14420b57cec5SDimitry Andric   case tgtok::XListConcat:
14430b57cec5SDimitry Andric   case tgtok::XListSplat:
1444bdd1243dSDimitry Andric   case tgtok::XListRemove:
1445480093f4SDimitry Andric   case tgtok::XStrConcat:
1446e8d8bef9SDimitry Andric   case tgtok::XInterleave:
144706c3fb27SDimitry Andric   case tgtok::XGetDagArg:
144806c3fb27SDimitry Andric   case tgtok::XGetDagName:
1449e8d8bef9SDimitry Andric   case tgtok::XSetDagOp: { // Value ::= !binop '(' Value ',' Value ')'
14500b57cec5SDimitry Andric     tgtok::TokKind OpTok = Lex.getCode();
14510b57cec5SDimitry Andric     SMLoc OpLoc = Lex.getLoc();
14520b57cec5SDimitry Andric     Lex.Lex();  // eat the operation
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric     BinOpInit::BinaryOp Code;
14550b57cec5SDimitry Andric     switch (OpTok) {
14560b57cec5SDimitry Andric     default: llvm_unreachable("Unhandled code!");
14570b57cec5SDimitry Andric     case tgtok::XConcat: Code = BinOpInit::CONCAT; break;
14580b57cec5SDimitry Andric     case tgtok::XADD:    Code = BinOpInit::ADD; break;
1459e8d8bef9SDimitry Andric     case tgtok::XSUB:    Code = BinOpInit::SUB; break;
14600b57cec5SDimitry Andric     case tgtok::XMUL:    Code = BinOpInit::MUL; break;
1461bdd1243dSDimitry Andric     case tgtok::XDIV:    Code = BinOpInit::DIV; break;
14620b57cec5SDimitry Andric     case tgtok::XAND:    Code = BinOpInit::AND; break;
14630b57cec5SDimitry Andric     case tgtok::XOR:     Code = BinOpInit::OR; break;
1464e8d8bef9SDimitry Andric     case tgtok::XXOR:    Code = BinOpInit::XOR; break;
14650b57cec5SDimitry Andric     case tgtok::XSRA:    Code = BinOpInit::SRA; break;
14660b57cec5SDimitry Andric     case tgtok::XSRL:    Code = BinOpInit::SRL; break;
14670b57cec5SDimitry Andric     case tgtok::XSHL:    Code = BinOpInit::SHL; break;
14680b57cec5SDimitry Andric     case tgtok::XEq:     Code = BinOpInit::EQ; break;
14690b57cec5SDimitry Andric     case tgtok::XNe:     Code = BinOpInit::NE; break;
14700b57cec5SDimitry Andric     case tgtok::XLe:     Code = BinOpInit::LE; break;
14710b57cec5SDimitry Andric     case tgtok::XLt:     Code = BinOpInit::LT; break;
14720b57cec5SDimitry Andric     case tgtok::XGe:     Code = BinOpInit::GE; break;
14730b57cec5SDimitry Andric     case tgtok::XGt:     Code = BinOpInit::GT; break;
14740b57cec5SDimitry Andric     case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
14750b57cec5SDimitry Andric     case tgtok::XListSplat:  Code = BinOpInit::LISTSPLAT; break;
14765f757f3fSDimitry Andric     case tgtok::XListRemove:
14775f757f3fSDimitry Andric       Code = BinOpInit::LISTREMOVE;
14785f757f3fSDimitry Andric       break;
14790b57cec5SDimitry Andric     case tgtok::XStrConcat:  Code = BinOpInit::STRCONCAT; break;
1480e8d8bef9SDimitry Andric     case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break;
1481e8d8bef9SDimitry Andric     case tgtok::XSetDagOp:   Code = BinOpInit::SETDAGOP; break;
148206c3fb27SDimitry Andric     case tgtok::XGetDagArg:
148306c3fb27SDimitry Andric       Code = BinOpInit::GETDAGARG;
148406c3fb27SDimitry Andric       break;
148506c3fb27SDimitry Andric     case tgtok::XGetDagName:
148606c3fb27SDimitry Andric       Code = BinOpInit::GETDAGNAME;
148706c3fb27SDimitry Andric       break;
14880b57cec5SDimitry Andric     }
14890b57cec5SDimitry Andric 
14900b57cec5SDimitry Andric     RecTy *Type = nullptr;
14910b57cec5SDimitry Andric     RecTy *ArgType = nullptr;
14920b57cec5SDimitry Andric     switch (OpTok) {
14930b57cec5SDimitry Andric     default:
14940b57cec5SDimitry Andric       llvm_unreachable("Unhandled code!");
14950b57cec5SDimitry Andric     case tgtok::XConcat:
1496e8d8bef9SDimitry Andric     case tgtok::XSetDagOp:
149781ad6265SDimitry Andric       Type = DagRecTy::get(Records);
149881ad6265SDimitry Andric       ArgType = DagRecTy::get(Records);
14990b57cec5SDimitry Andric       break;
150006c3fb27SDimitry Andric     case tgtok::XGetDagArg:
150106c3fb27SDimitry Andric       Type = ParseOperatorType();
150206c3fb27SDimitry Andric       if (!Type) {
150306c3fb27SDimitry Andric         TokError("did not get type for !getdagarg operator");
150406c3fb27SDimitry Andric         return nullptr;
150506c3fb27SDimitry Andric       }
150606c3fb27SDimitry Andric       ArgType = DagRecTy::get(Records);
150706c3fb27SDimitry Andric       break;
150806c3fb27SDimitry Andric     case tgtok::XGetDagName:
150906c3fb27SDimitry Andric       Type = StringRecTy::get(Records);
151006c3fb27SDimitry Andric       ArgType = DagRecTy::get(Records);
151106c3fb27SDimitry Andric       break;
15120b57cec5SDimitry Andric     case tgtok::XAND:
15130b57cec5SDimitry Andric     case tgtok::XOR:
1514e8d8bef9SDimitry Andric     case tgtok::XXOR:
15150b57cec5SDimitry Andric     case tgtok::XSRA:
15160b57cec5SDimitry Andric     case tgtok::XSRL:
15170b57cec5SDimitry Andric     case tgtok::XSHL:
15180b57cec5SDimitry Andric     case tgtok::XADD:
1519e8d8bef9SDimitry Andric     case tgtok::XSUB:
15200b57cec5SDimitry Andric     case tgtok::XMUL:
1521bdd1243dSDimitry Andric     case tgtok::XDIV:
152281ad6265SDimitry Andric       Type = IntRecTy::get(Records);
152381ad6265SDimitry Andric       ArgType = IntRecTy::get(Records);
15240b57cec5SDimitry Andric       break;
15250b57cec5SDimitry Andric     case tgtok::XEq:
15260b57cec5SDimitry Andric     case tgtok::XNe:
15270b57cec5SDimitry Andric     case tgtok::XLe:
15280b57cec5SDimitry Andric     case tgtok::XLt:
15290b57cec5SDimitry Andric     case tgtok::XGe:
15300b57cec5SDimitry Andric     case tgtok::XGt:
153181ad6265SDimitry Andric       Type = BitRecTy::get(Records);
1532e8d8bef9SDimitry Andric       // ArgType for the comparison operators is not yet known.
15330b57cec5SDimitry Andric       break;
15340b57cec5SDimitry Andric     case tgtok::XListConcat:
1535bdd1243dSDimitry Andric       // We don't know the list type until we parse the first argument.
15360b57cec5SDimitry Andric       ArgType = ItemType;
15370b57cec5SDimitry Andric       break;
15380b57cec5SDimitry Andric     case tgtok::XListSplat:
15390b57cec5SDimitry Andric       // Can't do any typechecking until we parse the first argument.
15400b57cec5SDimitry Andric       break;
1541bdd1243dSDimitry Andric     case tgtok::XListRemove:
1542bdd1243dSDimitry Andric       // We don't know the list type until we parse the first argument.
1543bdd1243dSDimitry Andric       ArgType = ItemType;
1544bdd1243dSDimitry Andric       break;
15450b57cec5SDimitry Andric     case tgtok::XStrConcat:
154681ad6265SDimitry Andric       Type = StringRecTy::get(Records);
154781ad6265SDimitry Andric       ArgType = StringRecTy::get(Records);
15480b57cec5SDimitry Andric       break;
1549e8d8bef9SDimitry Andric     case tgtok::XInterleave:
155081ad6265SDimitry Andric       Type = StringRecTy::get(Records);
1551e8d8bef9SDimitry Andric       // The first argument type is not yet known.
15520b57cec5SDimitry Andric     }
15530b57cec5SDimitry Andric 
15540b57cec5SDimitry Andric     if (Type && ItemType && !Type->typeIsConvertibleTo(ItemType)) {
15550b57cec5SDimitry Andric       Error(OpLoc, Twine("expected value of type '") +
15560b57cec5SDimitry Andric                    ItemType->getAsString() + "', got '" +
15570b57cec5SDimitry Andric                    Type->getAsString() + "'");
15580b57cec5SDimitry Andric       return nullptr;
15590b57cec5SDimitry Andric     }
15600b57cec5SDimitry Andric 
15615ffd83dbSDimitry Andric     if (!consume(tgtok::l_paren)) {
15620b57cec5SDimitry Andric       TokError("expected '(' after binary operator");
15630b57cec5SDimitry Andric       return nullptr;
15640b57cec5SDimitry Andric     }
15650b57cec5SDimitry Andric 
15660b57cec5SDimitry Andric     SmallVector<Init*, 2> InitList;
15670b57cec5SDimitry Andric 
1568e8d8bef9SDimitry Andric     // Note that this loop consumes an arbitrary number of arguments.
1569e8d8bef9SDimitry Andric     // The actual count is checked later.
15700b57cec5SDimitry Andric     for (;;) {
15710b57cec5SDimitry Andric       SMLoc InitLoc = Lex.getLoc();
15720b57cec5SDimitry Andric       InitList.push_back(ParseValue(CurRec, ArgType));
15730b57cec5SDimitry Andric       if (!InitList.back()) return nullptr;
15740b57cec5SDimitry Andric 
15755ffd83dbSDimitry Andric       TypedInit *InitListBack = dyn_cast<TypedInit>(InitList.back());
15765ffd83dbSDimitry Andric       if (!InitListBack) {
15775ffd83dbSDimitry Andric         Error(OpLoc, Twine("expected value to be a typed value, got '" +
15785ffd83dbSDimitry Andric                            InitList.back()->getAsString() + "'"));
15795ffd83dbSDimitry Andric         return nullptr;
15805ffd83dbSDimitry Andric       }
15815ffd83dbSDimitry Andric       RecTy *ListType = InitListBack->getType();
1582e8d8bef9SDimitry Andric 
15830b57cec5SDimitry Andric       if (!ArgType) {
1584e8d8bef9SDimitry Andric         // Argument type must be determined from the argument itself.
15858bcb0991SDimitry Andric         ArgType = ListType;
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric         switch (Code) {
15880b57cec5SDimitry Andric         case BinOpInit::LISTCONCAT:
15890b57cec5SDimitry Andric           if (!isa<ListRecTy>(ArgType)) {
15900b57cec5SDimitry Andric             Error(InitLoc, Twine("expected a list, got value of type '") +
15910b57cec5SDimitry Andric                            ArgType->getAsString() + "'");
15920b57cec5SDimitry Andric             return nullptr;
15930b57cec5SDimitry Andric           }
15940b57cec5SDimitry Andric           break;
15950b57cec5SDimitry Andric         case BinOpInit::LISTSPLAT:
15960b57cec5SDimitry Andric           if (ItemType && InitList.size() == 1) {
15970b57cec5SDimitry Andric             if (!isa<ListRecTy>(ItemType)) {
15980b57cec5SDimitry Andric               Error(OpLoc,
15990b57cec5SDimitry Andric                     Twine("expected output type to be a list, got type '") +
16000b57cec5SDimitry Andric                         ItemType->getAsString() + "'");
16010b57cec5SDimitry Andric               return nullptr;
16020b57cec5SDimitry Andric             }
16030b57cec5SDimitry Andric             if (!ArgType->getListTy()->typeIsConvertibleTo(ItemType)) {
16040b57cec5SDimitry Andric               Error(OpLoc, Twine("expected first arg type to be '") +
16050b57cec5SDimitry Andric                                ArgType->getAsString() +
16060b57cec5SDimitry Andric                                "', got value of type '" +
16070b57cec5SDimitry Andric                                cast<ListRecTy>(ItemType)
16080b57cec5SDimitry Andric                                    ->getElementType()
16090b57cec5SDimitry Andric                                    ->getAsString() +
16100b57cec5SDimitry Andric                                "'");
16110b57cec5SDimitry Andric               return nullptr;
16120b57cec5SDimitry Andric             }
16130b57cec5SDimitry Andric           }
16140b57cec5SDimitry Andric           if (InitList.size() == 2 && !isa<IntRecTy>(ArgType)) {
16150b57cec5SDimitry Andric             Error(InitLoc, Twine("expected second parameter to be an int, got "
16160b57cec5SDimitry Andric                                  "value of type '") +
16170b57cec5SDimitry Andric                                ArgType->getAsString() + "'");
16180b57cec5SDimitry Andric             return nullptr;
16190b57cec5SDimitry Andric           }
16200b57cec5SDimitry Andric           ArgType = nullptr; // Broken invariant: types not identical.
16210b57cec5SDimitry Andric           break;
1622bdd1243dSDimitry Andric         case BinOpInit::LISTREMOVE:
1623bdd1243dSDimitry Andric           if (!isa<ListRecTy>(ArgType)) {
1624bdd1243dSDimitry Andric             Error(InitLoc, Twine("expected a list, got value of type '") +
1625bdd1243dSDimitry Andric                                ArgType->getAsString() + "'");
1626bdd1243dSDimitry Andric             return nullptr;
1627bdd1243dSDimitry Andric           }
1628bdd1243dSDimitry Andric           break;
16290b57cec5SDimitry Andric         case BinOpInit::EQ:
16300b57cec5SDimitry Andric         case BinOpInit::NE:
163181ad6265SDimitry Andric           if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) &&
163281ad6265SDimitry Andric               !ArgType->typeIsConvertibleTo(StringRecTy::get(Records)) &&
163381ad6265SDimitry Andric               !ArgType->typeIsConvertibleTo(RecordRecTy::get(Records, {}))) {
1634e8d8bef9SDimitry Andric             Error(InitLoc, Twine("expected bit, bits, int, string, or record; "
1635e8d8bef9SDimitry Andric                                  "got value of type '") + ArgType->getAsString() +
1636e8d8bef9SDimitry Andric                                  "'");
16370b57cec5SDimitry Andric             return nullptr;
16380b57cec5SDimitry Andric           }
16390b57cec5SDimitry Andric           break;
164006c3fb27SDimitry Andric         case BinOpInit::GETDAGARG: // The 2nd argument of !getdagarg could be
164106c3fb27SDimitry Andric                                    // index or name.
1642e8d8bef9SDimitry Andric         case BinOpInit::LE:
1643e8d8bef9SDimitry Andric         case BinOpInit::LT:
1644e8d8bef9SDimitry Andric         case BinOpInit::GE:
1645e8d8bef9SDimitry Andric         case BinOpInit::GT:
164681ad6265SDimitry Andric           if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) &&
164781ad6265SDimitry Andric               !ArgType->typeIsConvertibleTo(StringRecTy::get(Records))) {
1648e8d8bef9SDimitry Andric             Error(InitLoc, Twine("expected bit, bits, int, or string; "
1649e8d8bef9SDimitry Andric                                  "got value of type '") + ArgType->getAsString() +
1650e8d8bef9SDimitry Andric                                  "'");
1651e8d8bef9SDimitry Andric             return nullptr;
1652e8d8bef9SDimitry Andric           }
1653e8d8bef9SDimitry Andric           break;
1654e8d8bef9SDimitry Andric         case BinOpInit::INTERLEAVE:
1655e8d8bef9SDimitry Andric           switch (InitList.size()) {
1656e8d8bef9SDimitry Andric           case 1: // First argument must be a list of strings or integers.
165781ad6265SDimitry Andric             if (ArgType != StringRecTy::get(Records)->getListTy() &&
165881ad6265SDimitry Andric                 !ArgType->typeIsConvertibleTo(
165981ad6265SDimitry Andric                     IntRecTy::get(Records)->getListTy())) {
1660e8d8bef9SDimitry Andric               Error(InitLoc, Twine("expected list of string, int, bits, or bit; "
1661e8d8bef9SDimitry Andric                                    "got value of type '") +
1662e8d8bef9SDimitry Andric                                    ArgType->getAsString() + "'");
1663e8d8bef9SDimitry Andric               return nullptr;
1664e8d8bef9SDimitry Andric             }
1665e8d8bef9SDimitry Andric             break;
1666e8d8bef9SDimitry Andric           case 2: // Second argument must be a string.
1667e8d8bef9SDimitry Andric             if (!isa<StringRecTy>(ArgType)) {
1668e8d8bef9SDimitry Andric               Error(InitLoc, Twine("expected second argument to be a string, "
1669e8d8bef9SDimitry Andric                                    "got value of type '") +
1670e8d8bef9SDimitry Andric                                  ArgType->getAsString() + "'");
1671e8d8bef9SDimitry Andric               return nullptr;
1672e8d8bef9SDimitry Andric             }
1673e8d8bef9SDimitry Andric             break;
1674e8d8bef9SDimitry Andric           default: ;
1675e8d8bef9SDimitry Andric           }
1676e8d8bef9SDimitry Andric           ArgType = nullptr; // Broken invariant: types not identical.
1677e8d8bef9SDimitry Andric           break;
16780b57cec5SDimitry Andric         default: llvm_unreachable("other ops have fixed argument types");
16790b57cec5SDimitry Andric         }
1680e8d8bef9SDimitry Andric 
16810b57cec5SDimitry Andric       } else {
1682e8d8bef9SDimitry Andric         // Desired argument type is a known and in ArgType.
16838bcb0991SDimitry Andric         RecTy *Resolved = resolveTypes(ArgType, ListType);
16840b57cec5SDimitry Andric         if (!Resolved) {
16850b57cec5SDimitry Andric           Error(InitLoc, Twine("expected value of type '") +
16860b57cec5SDimitry Andric                              ArgType->getAsString() + "', got '" +
16878bcb0991SDimitry Andric                              ListType->getAsString() + "'");
16880b57cec5SDimitry Andric           return nullptr;
16890b57cec5SDimitry Andric         }
1690e8d8bef9SDimitry Andric         if (Code != BinOpInit::ADD && Code != BinOpInit::SUB &&
1691e8d8bef9SDimitry Andric             Code != BinOpInit::AND && Code != BinOpInit::OR &&
1692e8d8bef9SDimitry Andric             Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
16930b57cec5SDimitry Andric             Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
1694bdd1243dSDimitry Andric             Code != BinOpInit::MUL && Code != BinOpInit::DIV)
16950b57cec5SDimitry Andric           ArgType = Resolved;
16960b57cec5SDimitry Andric       }
16970b57cec5SDimitry Andric 
1698480093f4SDimitry Andric       // Deal with BinOps whose arguments have different types, by
1699480093f4SDimitry Andric       // rewriting ArgType in between them.
1700480093f4SDimitry Andric       switch (Code) {
1701e8d8bef9SDimitry Andric         case BinOpInit::SETDAGOP:
1702480093f4SDimitry Andric           // After parsing the first dag argument, switch to expecting
1703480093f4SDimitry Andric           // a record, with no restriction on its superclasses.
170481ad6265SDimitry Andric           ArgType = RecordRecTy::get(Records, {});
1705480093f4SDimitry Andric           break;
170606c3fb27SDimitry Andric         case BinOpInit::GETDAGARG:
170706c3fb27SDimitry Andric           // After parsing the first dag argument, expect an index integer or a
170806c3fb27SDimitry Andric           // name string.
170906c3fb27SDimitry Andric           ArgType = nullptr;
171006c3fb27SDimitry Andric           break;
171106c3fb27SDimitry Andric         case BinOpInit::GETDAGNAME:
171206c3fb27SDimitry Andric           // After parsing the first dag argument, expect an index integer.
171306c3fb27SDimitry Andric           ArgType = IntRecTy::get(Records);
171406c3fb27SDimitry Andric           break;
1715480093f4SDimitry Andric         default:
1716480093f4SDimitry Andric           break;
1717480093f4SDimitry Andric       }
1718480093f4SDimitry Andric 
17195ffd83dbSDimitry Andric       if (!consume(tgtok::comma))
17200b57cec5SDimitry Andric         break;
17210b57cec5SDimitry Andric     }
17220b57cec5SDimitry Andric 
17235ffd83dbSDimitry Andric     if (!consume(tgtok::r_paren)) {
17240b57cec5SDimitry Andric       TokError("expected ')' in operator");
17250b57cec5SDimitry Andric       return nullptr;
17260b57cec5SDimitry Andric     }
17270b57cec5SDimitry Andric 
17280b57cec5SDimitry Andric     // listconcat returns a list with type of the argument.
17290b57cec5SDimitry Andric     if (Code == BinOpInit::LISTCONCAT)
17300b57cec5SDimitry Andric       Type = ArgType;
17310b57cec5SDimitry Andric     // listsplat returns a list of type of the *first* argument.
17320b57cec5SDimitry Andric     if (Code == BinOpInit::LISTSPLAT)
17330b57cec5SDimitry Andric       Type = cast<TypedInit>(InitList.front())->getType()->getListTy();
1734bdd1243dSDimitry Andric     // listremove returns a list with type of the argument.
1735bdd1243dSDimitry Andric     if (Code == BinOpInit::LISTREMOVE)
1736bdd1243dSDimitry Andric       Type = ArgType;
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric     // We allow multiple operands to associative operators like !strconcat as
17390b57cec5SDimitry Andric     // shorthand for nesting them.
17400b57cec5SDimitry Andric     if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT ||
17410b57cec5SDimitry Andric         Code == BinOpInit::CONCAT || Code == BinOpInit::ADD ||
17420b57cec5SDimitry Andric         Code == BinOpInit::AND || Code == BinOpInit::OR ||
1743e8d8bef9SDimitry Andric         Code == BinOpInit::XOR || Code == BinOpInit::MUL) {
17440b57cec5SDimitry Andric       while (InitList.size() > 2) {
17450b57cec5SDimitry Andric         Init *RHS = InitList.pop_back_val();
17460b57cec5SDimitry Andric         RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec);
17470b57cec5SDimitry Andric         InitList.back() = RHS;
17480b57cec5SDimitry Andric       }
17490b57cec5SDimitry Andric     }
17500b57cec5SDimitry Andric 
17510b57cec5SDimitry Andric     if (InitList.size() == 2)
17520b57cec5SDimitry Andric       return (BinOpInit::get(Code, InitList[0], InitList[1], Type))
17530b57cec5SDimitry Andric           ->Fold(CurRec);
17540b57cec5SDimitry Andric 
17550b57cec5SDimitry Andric     Error(OpLoc, "expected two operands to operator");
17560b57cec5SDimitry Andric     return nullptr;
17570b57cec5SDimitry Andric   }
17580b57cec5SDimitry Andric 
1759e8d8bef9SDimitry Andric   case tgtok::XForEach:
1760e8d8bef9SDimitry Andric   case tgtok::XFilter: {
1761e8d8bef9SDimitry Andric     return ParseOperationForEachFilter(CurRec, ItemType);
17620b57cec5SDimitry Andric   }
17630b57cec5SDimitry Andric 
17645f757f3fSDimitry Andric   case tgtok::XRange: {
17655f757f3fSDimitry Andric     SMLoc OpLoc = Lex.getLoc();
17665f757f3fSDimitry Andric     Lex.Lex(); // eat the operation
17675f757f3fSDimitry Andric 
17685f757f3fSDimitry Andric     if (!consume(tgtok::l_paren)) {
17695f757f3fSDimitry Andric       TokError("expected '(' after !range operator");
17705f757f3fSDimitry Andric       return nullptr;
17715f757f3fSDimitry Andric     }
17725f757f3fSDimitry Andric 
17735f757f3fSDimitry Andric     SmallVector<Init *, 2> Args;
17745f757f3fSDimitry Andric     bool FirstArgIsList = false;
17755f757f3fSDimitry Andric     for (;;) {
17765f757f3fSDimitry Andric       if (Args.size() >= 3) {
17775f757f3fSDimitry Andric         TokError("expected at most three values of integer");
17785f757f3fSDimitry Andric         return nullptr;
17795f757f3fSDimitry Andric       }
17805f757f3fSDimitry Andric 
17815f757f3fSDimitry Andric       SMLoc InitLoc = Lex.getLoc();
17825f757f3fSDimitry Andric       Args.push_back(ParseValue(CurRec));
17835f757f3fSDimitry Andric       if (!Args.back())
17845f757f3fSDimitry Andric         return nullptr;
17855f757f3fSDimitry Andric 
17865f757f3fSDimitry Andric       TypedInit *ArgBack = dyn_cast<TypedInit>(Args.back());
17875f757f3fSDimitry Andric       if (!ArgBack) {
17885f757f3fSDimitry Andric         Error(OpLoc, Twine("expected value to be a typed value, got '" +
17895f757f3fSDimitry Andric                            Args.back()->getAsString() + "'"));
17905f757f3fSDimitry Andric         return nullptr;
17915f757f3fSDimitry Andric       }
17925f757f3fSDimitry Andric 
17935f757f3fSDimitry Andric       RecTy *ArgBackType = ArgBack->getType();
17945f757f3fSDimitry Andric       if (!FirstArgIsList || Args.size() == 1) {
17955f757f3fSDimitry Andric         if (Args.size() == 1 && isa<ListRecTy>(ArgBackType)) {
17965f757f3fSDimitry Andric           FirstArgIsList = true; // Detect error if 2nd arg were present.
17975f757f3fSDimitry Andric         } else if (isa<IntRecTy>(ArgBackType)) {
17985f757f3fSDimitry Andric           // Assume 2nd arg should be IntRecTy
17995f757f3fSDimitry Andric         } else {
18005f757f3fSDimitry Andric           if (Args.size() != 1)
18015f757f3fSDimitry Andric             Error(InitLoc, Twine("expected value of type 'int', got '" +
18025f757f3fSDimitry Andric                                  ArgBackType->getAsString() + "'"));
18035f757f3fSDimitry Andric           else
18045f757f3fSDimitry Andric             Error(InitLoc, Twine("expected list or int, got value of type '") +
18055f757f3fSDimitry Andric                                ArgBackType->getAsString() + "'");
18065f757f3fSDimitry Andric           return nullptr;
18075f757f3fSDimitry Andric         }
18085f757f3fSDimitry Andric       } else {
18095f757f3fSDimitry Andric         // Don't come here unless 1st arg is ListRecTy.
18105f757f3fSDimitry Andric         assert(isa<ListRecTy>(cast<TypedInit>(Args[0])->getType()));
18115f757f3fSDimitry Andric         Error(InitLoc, Twine("expected one list, got extra value of type '") +
18125f757f3fSDimitry Andric                            ArgBackType->getAsString() + "'");
18135f757f3fSDimitry Andric         return nullptr;
18145f757f3fSDimitry Andric       }
18155f757f3fSDimitry Andric       if (!consume(tgtok::comma))
18165f757f3fSDimitry Andric         break;
18175f757f3fSDimitry Andric     }
18185f757f3fSDimitry Andric 
18195f757f3fSDimitry Andric     if (!consume(tgtok::r_paren)) {
18205f757f3fSDimitry Andric       TokError("expected ')' in operator");
18215f757f3fSDimitry Andric       return nullptr;
18225f757f3fSDimitry Andric     }
18235f757f3fSDimitry Andric 
18245f757f3fSDimitry Andric     Init *LHS, *MHS, *RHS;
18255f757f3fSDimitry Andric     auto ArgCount = Args.size();
18265f757f3fSDimitry Andric     assert(ArgCount >= 1);
18275f757f3fSDimitry Andric     auto *Arg0 = cast<TypedInit>(Args[0]);
18285f757f3fSDimitry Andric     auto *Arg0Ty = Arg0->getType();
18295f757f3fSDimitry Andric     if (ArgCount == 1) {
18305f757f3fSDimitry Andric       if (isa<ListRecTy>(Arg0Ty)) {
18315f757f3fSDimitry Andric         // (0, !size(arg), 1)
18325f757f3fSDimitry Andric         LHS = IntInit::get(Records, 0);
18335f757f3fSDimitry Andric         MHS = UnOpInit::get(UnOpInit::SIZE, Arg0, IntRecTy::get(Records))
18345f757f3fSDimitry Andric                   ->Fold(CurRec);
18355f757f3fSDimitry Andric         RHS = IntInit::get(Records, 1);
18365f757f3fSDimitry Andric       } else {
18375f757f3fSDimitry Andric         assert(isa<IntRecTy>(Arg0Ty));
18385f757f3fSDimitry Andric         // (0, arg, 1)
18395f757f3fSDimitry Andric         LHS = IntInit::get(Records, 0);
18405f757f3fSDimitry Andric         MHS = Arg0;
18415f757f3fSDimitry Andric         RHS = IntInit::get(Records, 1);
18425f757f3fSDimitry Andric       }
18435f757f3fSDimitry Andric     } else {
18445f757f3fSDimitry Andric       assert(isa<IntRecTy>(Arg0Ty));
18455f757f3fSDimitry Andric       auto *Arg1 = cast<TypedInit>(Args[1]);
18465f757f3fSDimitry Andric       assert(isa<IntRecTy>(Arg1->getType()));
18475f757f3fSDimitry Andric       LHS = Arg0;
18485f757f3fSDimitry Andric       MHS = Arg1;
18495f757f3fSDimitry Andric       if (ArgCount == 3) {
18505f757f3fSDimitry Andric         // (start, end, step)
18515f757f3fSDimitry Andric         auto *Arg2 = cast<TypedInit>(Args[2]);
18525f757f3fSDimitry Andric         assert(isa<IntRecTy>(Arg2->getType()));
18535f757f3fSDimitry Andric         RHS = Arg2;
18545f757f3fSDimitry Andric       } else
18555f757f3fSDimitry Andric         // (start, end, 1)
18565f757f3fSDimitry Andric         RHS = IntInit::get(Records, 1);
18575f757f3fSDimitry Andric     }
18585f757f3fSDimitry Andric     return TernOpInit::get(TernOpInit::RANGE, LHS, MHS, RHS,
18595f757f3fSDimitry Andric                            IntRecTy::get(Records)->getListTy())
18605f757f3fSDimitry Andric         ->Fold(CurRec);
18615f757f3fSDimitry Andric   }
18625f757f3fSDimitry Andric 
186306c3fb27SDimitry Andric   case tgtok::XSetDagArg:
186406c3fb27SDimitry Andric   case tgtok::XSetDagName:
18650b57cec5SDimitry Andric   case tgtok::XDag:
18660b57cec5SDimitry Andric   case tgtok::XIf:
18670b57cec5SDimitry Andric   case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
18680b57cec5SDimitry Andric     TernOpInit::TernaryOp Code;
18690b57cec5SDimitry Andric     RecTy *Type = nullptr;
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric     tgtok::TokKind LexCode = Lex.getCode();
18720b57cec5SDimitry Andric     Lex.Lex();  // eat the operation
18730b57cec5SDimitry Andric     switch (LexCode) {
18740b57cec5SDimitry Andric     default: llvm_unreachable("Unhandled code!");
18750b57cec5SDimitry Andric     case tgtok::XDag:
18760b57cec5SDimitry Andric       Code = TernOpInit::DAG;
187781ad6265SDimitry Andric       Type = DagRecTy::get(Records);
18780b57cec5SDimitry Andric       ItemType = nullptr;
18790b57cec5SDimitry Andric       break;
18800b57cec5SDimitry Andric     case tgtok::XIf:
18810b57cec5SDimitry Andric       Code = TernOpInit::IF;
18820b57cec5SDimitry Andric       break;
18830b57cec5SDimitry Andric     case tgtok::XSubst:
18840b57cec5SDimitry Andric       Code = TernOpInit::SUBST;
18850b57cec5SDimitry Andric       break;
188606c3fb27SDimitry Andric     case tgtok::XSetDagArg:
188706c3fb27SDimitry Andric       Code = TernOpInit::SETDAGARG;
188806c3fb27SDimitry Andric       Type = DagRecTy::get(Records);
188906c3fb27SDimitry Andric       ItemType = nullptr;
189006c3fb27SDimitry Andric       break;
189106c3fb27SDimitry Andric     case tgtok::XSetDagName:
189206c3fb27SDimitry Andric       Code = TernOpInit::SETDAGNAME;
189306c3fb27SDimitry Andric       Type = DagRecTy::get(Records);
189406c3fb27SDimitry Andric       ItemType = nullptr;
189506c3fb27SDimitry Andric       break;
18960b57cec5SDimitry Andric     }
18975ffd83dbSDimitry Andric     if (!consume(tgtok::l_paren)) {
18980b57cec5SDimitry Andric       TokError("expected '(' after ternary operator");
18990b57cec5SDimitry Andric       return nullptr;
19000b57cec5SDimitry Andric     }
19010b57cec5SDimitry Andric 
19020b57cec5SDimitry Andric     Init *LHS = ParseValue(CurRec);
19030b57cec5SDimitry Andric     if (!LHS) return nullptr;
19040b57cec5SDimitry Andric 
19055ffd83dbSDimitry Andric     if (!consume(tgtok::comma)) {
19060b57cec5SDimitry Andric       TokError("expected ',' in ternary operator");
19070b57cec5SDimitry Andric       return nullptr;
19080b57cec5SDimitry Andric     }
19090b57cec5SDimitry Andric 
19100b57cec5SDimitry Andric     SMLoc MHSLoc = Lex.getLoc();
19110b57cec5SDimitry Andric     Init *MHS = ParseValue(CurRec, ItemType);
19120b57cec5SDimitry Andric     if (!MHS)
19130b57cec5SDimitry Andric       return nullptr;
19140b57cec5SDimitry Andric 
19155ffd83dbSDimitry Andric     if (!consume(tgtok::comma)) {
19160b57cec5SDimitry Andric       TokError("expected ',' in ternary operator");
19170b57cec5SDimitry Andric       return nullptr;
19180b57cec5SDimitry Andric     }
19190b57cec5SDimitry Andric 
19200b57cec5SDimitry Andric     SMLoc RHSLoc = Lex.getLoc();
19210b57cec5SDimitry Andric     Init *RHS = ParseValue(CurRec, ItemType);
19220b57cec5SDimitry Andric     if (!RHS)
19230b57cec5SDimitry Andric       return nullptr;
19240b57cec5SDimitry Andric 
19255ffd83dbSDimitry Andric     if (!consume(tgtok::r_paren)) {
19260b57cec5SDimitry Andric       TokError("expected ')' in binary operator");
19270b57cec5SDimitry Andric       return nullptr;
19280b57cec5SDimitry Andric     }
19290b57cec5SDimitry Andric 
19300b57cec5SDimitry Andric     switch (LexCode) {
19310b57cec5SDimitry Andric     default: llvm_unreachable("Unhandled code!");
19320b57cec5SDimitry Andric     case tgtok::XDag: {
19330b57cec5SDimitry Andric       TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
19340b57cec5SDimitry Andric       if (!MHSt && !isa<UnsetInit>(MHS)) {
19350b57cec5SDimitry Andric         Error(MHSLoc, "could not determine type of the child list in !dag");
19360b57cec5SDimitry Andric         return nullptr;
19370b57cec5SDimitry Andric       }
19380b57cec5SDimitry Andric       if (MHSt && !isa<ListRecTy>(MHSt->getType())) {
19390b57cec5SDimitry Andric         Error(MHSLoc, Twine("expected list of children, got type '") +
19400b57cec5SDimitry Andric                           MHSt->getType()->getAsString() + "'");
19410b57cec5SDimitry Andric         return nullptr;
19420b57cec5SDimitry Andric       }
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric       TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
19450b57cec5SDimitry Andric       if (!RHSt && !isa<UnsetInit>(RHS)) {
19460b57cec5SDimitry Andric         Error(RHSLoc, "could not determine type of the name list in !dag");
19470b57cec5SDimitry Andric         return nullptr;
19480b57cec5SDimitry Andric       }
194981ad6265SDimitry Andric       if (RHSt && StringRecTy::get(Records)->getListTy() != RHSt->getType()) {
19500b57cec5SDimitry Andric         Error(RHSLoc, Twine("expected list<string>, got type '") +
19510b57cec5SDimitry Andric                           RHSt->getType()->getAsString() + "'");
19520b57cec5SDimitry Andric         return nullptr;
19530b57cec5SDimitry Andric       }
19540b57cec5SDimitry Andric 
19550b57cec5SDimitry Andric       if (!MHSt && !RHSt) {
19560b57cec5SDimitry Andric         Error(MHSLoc,
19570b57cec5SDimitry Andric               "cannot have both unset children and unset names in !dag");
19580b57cec5SDimitry Andric         return nullptr;
19590b57cec5SDimitry Andric       }
19600b57cec5SDimitry Andric       break;
19610b57cec5SDimitry Andric     }
19620b57cec5SDimitry Andric     case tgtok::XIf: {
19630b57cec5SDimitry Andric       RecTy *MHSTy = nullptr;
19640b57cec5SDimitry Andric       RecTy *RHSTy = nullptr;
19650b57cec5SDimitry Andric 
19660b57cec5SDimitry Andric       if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS))
19670b57cec5SDimitry Andric         MHSTy = MHSt->getType();
19680b57cec5SDimitry Andric       if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS))
196981ad6265SDimitry Andric         MHSTy = BitsRecTy::get(Records, MHSbits->getNumBits());
19700b57cec5SDimitry Andric       if (isa<BitInit>(MHS))
197181ad6265SDimitry Andric         MHSTy = BitRecTy::get(Records);
19720b57cec5SDimitry Andric 
19730b57cec5SDimitry Andric       if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS))
19740b57cec5SDimitry Andric         RHSTy = RHSt->getType();
19750b57cec5SDimitry Andric       if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS))
197681ad6265SDimitry Andric         RHSTy = BitsRecTy::get(Records, RHSbits->getNumBits());
19770b57cec5SDimitry Andric       if (isa<BitInit>(RHS))
197881ad6265SDimitry Andric         RHSTy = BitRecTy::get(Records);
19790b57cec5SDimitry Andric 
19800b57cec5SDimitry Andric       // For UnsetInit, it's typed from the other hand.
19810b57cec5SDimitry Andric       if (isa<UnsetInit>(MHS))
19820b57cec5SDimitry Andric         MHSTy = RHSTy;
19830b57cec5SDimitry Andric       if (isa<UnsetInit>(RHS))
19840b57cec5SDimitry Andric         RHSTy = MHSTy;
19850b57cec5SDimitry Andric 
19860b57cec5SDimitry Andric       if (!MHSTy || !RHSTy) {
19870b57cec5SDimitry Andric         TokError("could not get type for !if");
19880b57cec5SDimitry Andric         return nullptr;
19890b57cec5SDimitry Andric       }
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric       Type = resolveTypes(MHSTy, RHSTy);
19920b57cec5SDimitry Andric       if (!Type) {
19930b57cec5SDimitry Andric         TokError(Twine("inconsistent types '") + MHSTy->getAsString() +
19940b57cec5SDimitry Andric                  "' and '" + RHSTy->getAsString() + "' for !if");
19950b57cec5SDimitry Andric         return nullptr;
19960b57cec5SDimitry Andric       }
19970b57cec5SDimitry Andric       break;
19980b57cec5SDimitry Andric     }
19990b57cec5SDimitry Andric     case tgtok::XSubst: {
20000b57cec5SDimitry Andric       TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
20010b57cec5SDimitry Andric       if (!RHSt) {
20020b57cec5SDimitry Andric         TokError("could not get type for !subst");
20030b57cec5SDimitry Andric         return nullptr;
20040b57cec5SDimitry Andric       }
20050b57cec5SDimitry Andric       Type = RHSt->getType();
20060b57cec5SDimitry Andric       break;
20070b57cec5SDimitry Andric     }
200806c3fb27SDimitry Andric     case tgtok::XSetDagArg: {
200906c3fb27SDimitry Andric       TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
201006c3fb27SDimitry Andric       if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
201106c3fb27SDimitry Andric         Error(MHSLoc, Twine("expected integer index or string name, got ") +
201206c3fb27SDimitry Andric                           (MHSt ? ("type '" + MHSt->getType()->getAsString())
201306c3fb27SDimitry Andric                                 : ("'" + MHS->getAsString())) +
201406c3fb27SDimitry Andric                           "'");
201506c3fb27SDimitry Andric         return nullptr;
201606c3fb27SDimitry Andric       }
201706c3fb27SDimitry Andric       break;
201806c3fb27SDimitry Andric     }
201906c3fb27SDimitry Andric     case tgtok::XSetDagName: {
202006c3fb27SDimitry Andric       TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
202106c3fb27SDimitry Andric       if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
202206c3fb27SDimitry Andric         Error(MHSLoc, Twine("expected integer index or string name, got ") +
202306c3fb27SDimitry Andric                           (MHSt ? ("type '" + MHSt->getType()->getAsString())
202406c3fb27SDimitry Andric                                 : ("'" + MHS->getAsString())) +
202506c3fb27SDimitry Andric                           "'");
202606c3fb27SDimitry Andric         return nullptr;
202706c3fb27SDimitry Andric       }
202806c3fb27SDimitry Andric       TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
202906c3fb27SDimitry Andric       // The name could be a string or unset.
203006c3fb27SDimitry Andric       if (RHSt && !isa<StringRecTy>(RHSt->getType())) {
203106c3fb27SDimitry Andric         Error(RHSLoc, Twine("expected string or unset name, got type '") +
203206c3fb27SDimitry Andric                           RHSt->getType()->getAsString() + "'");
203306c3fb27SDimitry Andric         return nullptr;
203406c3fb27SDimitry Andric       }
203506c3fb27SDimitry Andric       break;
203606c3fb27SDimitry Andric     }
20370b57cec5SDimitry Andric     }
20380b57cec5SDimitry Andric     return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
20390b57cec5SDimitry Andric   }
20400b57cec5SDimitry Andric 
2041e8d8bef9SDimitry Andric   case tgtok::XSubstr:
2042e8d8bef9SDimitry Andric     return ParseOperationSubstr(CurRec, ItemType);
2043e8d8bef9SDimitry Andric 
2044fe6060f1SDimitry Andric   case tgtok::XFind:
2045fe6060f1SDimitry Andric     return ParseOperationFind(CurRec, ItemType);
2046fe6060f1SDimitry Andric 
20470b57cec5SDimitry Andric   case tgtok::XCond:
20480b57cec5SDimitry Andric     return ParseOperationCond(CurRec, ItemType);
20490b57cec5SDimitry Andric 
20500b57cec5SDimitry Andric   case tgtok::XFoldl: {
2051e8d8bef9SDimitry Andric     // Value ::= !foldl '(' Value ',' Value ',' Id ',' Id ',' Expr ')'
20520b57cec5SDimitry Andric     Lex.Lex(); // eat the operation
20535ffd83dbSDimitry Andric     if (!consume(tgtok::l_paren)) {
20540b57cec5SDimitry Andric       TokError("expected '(' after !foldl");
20550b57cec5SDimitry Andric       return nullptr;
20560b57cec5SDimitry Andric     }
20570b57cec5SDimitry Andric 
20580b57cec5SDimitry Andric     Init *StartUntyped = ParseValue(CurRec);
20590b57cec5SDimitry Andric     if (!StartUntyped)
20600b57cec5SDimitry Andric       return nullptr;
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric     TypedInit *Start = dyn_cast<TypedInit>(StartUntyped);
20630b57cec5SDimitry Andric     if (!Start) {
20640b57cec5SDimitry Andric       TokError(Twine("could not get type of !foldl start: '") +
20650b57cec5SDimitry Andric                StartUntyped->getAsString() + "'");
20660b57cec5SDimitry Andric       return nullptr;
20670b57cec5SDimitry Andric     }
20680b57cec5SDimitry Andric 
20695ffd83dbSDimitry Andric     if (!consume(tgtok::comma)) {
20700b57cec5SDimitry Andric       TokError("expected ',' in !foldl");
20710b57cec5SDimitry Andric       return nullptr;
20720b57cec5SDimitry Andric     }
20730b57cec5SDimitry Andric 
20740b57cec5SDimitry Andric     Init *ListUntyped = ParseValue(CurRec);
20750b57cec5SDimitry Andric     if (!ListUntyped)
20760b57cec5SDimitry Andric       return nullptr;
20770b57cec5SDimitry Andric 
20780b57cec5SDimitry Andric     TypedInit *List = dyn_cast<TypedInit>(ListUntyped);
20790b57cec5SDimitry Andric     if (!List) {
20800b57cec5SDimitry Andric       TokError(Twine("could not get type of !foldl list: '") +
20810b57cec5SDimitry Andric                ListUntyped->getAsString() + "'");
20820b57cec5SDimitry Andric       return nullptr;
20830b57cec5SDimitry Andric     }
20840b57cec5SDimitry Andric 
20850b57cec5SDimitry Andric     ListRecTy *ListType = dyn_cast<ListRecTy>(List->getType());
20860b57cec5SDimitry Andric     if (!ListType) {
20870b57cec5SDimitry Andric       TokError(Twine("!foldl list must be a list, but is of type '") +
20880b57cec5SDimitry Andric                List->getType()->getAsString());
20890b57cec5SDimitry Andric       return nullptr;
20900b57cec5SDimitry Andric     }
20910b57cec5SDimitry Andric 
20920b57cec5SDimitry Andric     if (Lex.getCode() != tgtok::comma) {
20930b57cec5SDimitry Andric       TokError("expected ',' in !foldl");
20940b57cec5SDimitry Andric       return nullptr;
20950b57cec5SDimitry Andric     }
20960b57cec5SDimitry Andric 
20970b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::Id) { // eat the ','
20980b57cec5SDimitry Andric       TokError("third argument of !foldl must be an identifier");
20990b57cec5SDimitry Andric       return nullptr;
21000b57cec5SDimitry Andric     }
21010b57cec5SDimitry Andric 
210281ad6265SDimitry Andric     Init *A = StringInit::get(Records, Lex.getCurStrVal());
21030b57cec5SDimitry Andric     if (CurRec && CurRec->getValue(A)) {
21040b57cec5SDimitry Andric       TokError((Twine("left !foldl variable '") + A->getAsString() +
21050b57cec5SDimitry Andric                 "' already defined")
21060b57cec5SDimitry Andric                    .str());
21070b57cec5SDimitry Andric       return nullptr;
21080b57cec5SDimitry Andric     }
21090b57cec5SDimitry Andric 
21100b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::comma) { // eat the id
21110b57cec5SDimitry Andric       TokError("expected ',' in !foldl");
21120b57cec5SDimitry Andric       return nullptr;
21130b57cec5SDimitry Andric     }
21140b57cec5SDimitry Andric 
21150b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::Id) { // eat the ','
21160b57cec5SDimitry Andric       TokError("fourth argument of !foldl must be an identifier");
21170b57cec5SDimitry Andric       return nullptr;
21180b57cec5SDimitry Andric     }
21190b57cec5SDimitry Andric 
212081ad6265SDimitry Andric     Init *B = StringInit::get(Records, Lex.getCurStrVal());
21210b57cec5SDimitry Andric     if (CurRec && CurRec->getValue(B)) {
21220b57cec5SDimitry Andric       TokError((Twine("right !foldl variable '") + B->getAsString() +
21230b57cec5SDimitry Andric                 "' already defined")
21240b57cec5SDimitry Andric                    .str());
21250b57cec5SDimitry Andric       return nullptr;
21260b57cec5SDimitry Andric     }
21270b57cec5SDimitry Andric 
21280b57cec5SDimitry Andric     if (Lex.Lex() != tgtok::comma) { // eat the id
21290b57cec5SDimitry Andric       TokError("expected ',' in !foldl");
21300b57cec5SDimitry Andric       return nullptr;
21310b57cec5SDimitry Andric     }
21320b57cec5SDimitry Andric     Lex.Lex(); // eat the ','
21330b57cec5SDimitry Andric 
2134e8d8bef9SDimitry Andric     // We need to create a temporary record to provide a scope for the
2135e8d8bef9SDimitry Andric     // two variables.
21360b57cec5SDimitry Andric     std::unique_ptr<Record> ParseRecTmp;
21370b57cec5SDimitry Andric     Record *ParseRec = CurRec;
21380b57cec5SDimitry Andric     if (!ParseRec) {
21398bcb0991SDimitry Andric       ParseRecTmp = std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);
21400b57cec5SDimitry Andric       ParseRec = ParseRecTmp.get();
21410b57cec5SDimitry Andric     }
21420b57cec5SDimitry Andric 
214306c3fb27SDimitry Andric     TGVarScope *FoldScope = PushScope(ParseRec);
2144e8d8bef9SDimitry Andric     ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal));
214506c3fb27SDimitry Andric     ParseRec->addValue(
214606c3fb27SDimitry Andric         RecordVal(B, ListType->getElementType(), RecordVal::FK_Normal));
21470b57cec5SDimitry Andric     Init *ExprUntyped = ParseValue(ParseRec);
21480b57cec5SDimitry Andric     ParseRec->removeValue(A);
21490b57cec5SDimitry Andric     ParseRec->removeValue(B);
215006c3fb27SDimitry Andric     PopScope(FoldScope);
21510b57cec5SDimitry Andric     if (!ExprUntyped)
21520b57cec5SDimitry Andric       return nullptr;
21530b57cec5SDimitry Andric 
21540b57cec5SDimitry Andric     TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped);
21550b57cec5SDimitry Andric     if (!Expr) {
21560b57cec5SDimitry Andric       TokError("could not get type of !foldl expression");
21570b57cec5SDimitry Andric       return nullptr;
21580b57cec5SDimitry Andric     }
21590b57cec5SDimitry Andric 
21600b57cec5SDimitry Andric     if (Expr->getType() != Start->getType()) {
21610b57cec5SDimitry Andric       TokError(Twine("!foldl expression must be of same type as start (") +
21620b57cec5SDimitry Andric                Start->getType()->getAsString() + "), but is of type " +
21630b57cec5SDimitry Andric                Expr->getType()->getAsString());
21640b57cec5SDimitry Andric       return nullptr;
21650b57cec5SDimitry Andric     }
21660b57cec5SDimitry Andric 
21675ffd83dbSDimitry Andric     if (!consume(tgtok::r_paren)) {
21680b57cec5SDimitry Andric       TokError("expected ')' in fold operator");
21690b57cec5SDimitry Andric       return nullptr;
21700b57cec5SDimitry Andric     }
21710b57cec5SDimitry Andric 
21720b57cec5SDimitry Andric     return FoldOpInit::get(Start, List, A, B, Expr, Start->getType())
21730b57cec5SDimitry Andric         ->Fold(CurRec);
21740b57cec5SDimitry Andric   }
21750b57cec5SDimitry Andric   }
21760b57cec5SDimitry Andric }
21770b57cec5SDimitry Andric 
21780b57cec5SDimitry Andric /// ParseOperatorType - Parse a type for an operator.  This returns
21790b57cec5SDimitry Andric /// null on error.
21800b57cec5SDimitry Andric ///
21810b57cec5SDimitry Andric /// OperatorType ::= '<' Type '>'
21820b57cec5SDimitry Andric ///
ParseOperatorType()21830b57cec5SDimitry Andric RecTy *TGParser::ParseOperatorType() {
21840b57cec5SDimitry Andric   RecTy *Type = nullptr;
21850b57cec5SDimitry Andric 
21865ffd83dbSDimitry Andric   if (!consume(tgtok::less)) {
21870b57cec5SDimitry Andric     TokError("expected type name for operator");
21880b57cec5SDimitry Andric     return nullptr;
21890b57cec5SDimitry Andric   }
21900b57cec5SDimitry Andric 
2191e8d8bef9SDimitry Andric   if (Lex.getCode() == tgtok::Code)
2192e8d8bef9SDimitry Andric     TokError("the 'code' type is not allowed in bang operators; use 'string'");
2193e8d8bef9SDimitry Andric 
21940b57cec5SDimitry Andric   Type = ParseType();
21950b57cec5SDimitry Andric 
21960b57cec5SDimitry Andric   if (!Type) {
21970b57cec5SDimitry Andric     TokError("expected type name for operator");
21980b57cec5SDimitry Andric     return nullptr;
21990b57cec5SDimitry Andric   }
22000b57cec5SDimitry Andric 
22015ffd83dbSDimitry Andric   if (!consume(tgtok::greater)) {
22020b57cec5SDimitry Andric     TokError("expected type name for operator");
22030b57cec5SDimitry Andric     return nullptr;
22040b57cec5SDimitry Andric   }
22050b57cec5SDimitry Andric 
22060b57cec5SDimitry Andric   return Type;
22070b57cec5SDimitry Andric }
22080b57cec5SDimitry Andric 
2209e8d8bef9SDimitry Andric /// Parse the !substr operation. Return null on error.
2210e8d8bef9SDimitry Andric ///
2211e8d8bef9SDimitry Andric /// Substr ::= !substr(string, start-int [, length-int]) => string
ParseOperationSubstr(Record * CurRec,RecTy * ItemType)2212e8d8bef9SDimitry Andric Init *TGParser::ParseOperationSubstr(Record *CurRec, RecTy *ItemType) {
2213e8d8bef9SDimitry Andric   TernOpInit::TernaryOp Code = TernOpInit::SUBSTR;
221481ad6265SDimitry Andric   RecTy *Type = StringRecTy::get(Records);
2215e8d8bef9SDimitry Andric 
2216e8d8bef9SDimitry Andric   Lex.Lex(); // eat the operation
2217e8d8bef9SDimitry Andric 
2218e8d8bef9SDimitry Andric   if (!consume(tgtok::l_paren)) {
2219e8d8bef9SDimitry Andric     TokError("expected '(' after !substr operator");
2220e8d8bef9SDimitry Andric     return nullptr;
2221e8d8bef9SDimitry Andric   }
2222e8d8bef9SDimitry Andric 
2223e8d8bef9SDimitry Andric   Init *LHS = ParseValue(CurRec);
2224e8d8bef9SDimitry Andric   if (!LHS)
2225e8d8bef9SDimitry Andric     return nullptr;
2226e8d8bef9SDimitry Andric 
2227e8d8bef9SDimitry Andric   if (!consume(tgtok::comma)) {
2228e8d8bef9SDimitry Andric     TokError("expected ',' in !substr operator");
2229e8d8bef9SDimitry Andric     return nullptr;
2230e8d8bef9SDimitry Andric   }
2231e8d8bef9SDimitry Andric 
2232e8d8bef9SDimitry Andric   SMLoc MHSLoc = Lex.getLoc();
2233e8d8bef9SDimitry Andric   Init *MHS = ParseValue(CurRec);
2234e8d8bef9SDimitry Andric   if (!MHS)
2235e8d8bef9SDimitry Andric     return nullptr;
2236e8d8bef9SDimitry Andric 
2237e8d8bef9SDimitry Andric   SMLoc RHSLoc = Lex.getLoc();
2238e8d8bef9SDimitry Andric   Init *RHS;
2239e8d8bef9SDimitry Andric   if (consume(tgtok::comma)) {
2240e8d8bef9SDimitry Andric     RHSLoc = Lex.getLoc();
2241e8d8bef9SDimitry Andric     RHS = ParseValue(CurRec);
2242e8d8bef9SDimitry Andric     if (!RHS)
2243e8d8bef9SDimitry Andric       return nullptr;
2244e8d8bef9SDimitry Andric   } else {
224581ad6265SDimitry Andric     RHS = IntInit::get(Records, std::numeric_limits<int64_t>::max());
2246e8d8bef9SDimitry Andric   }
2247e8d8bef9SDimitry Andric 
2248e8d8bef9SDimitry Andric   if (!consume(tgtok::r_paren)) {
2249e8d8bef9SDimitry Andric     TokError("expected ')' in !substr operator");
2250e8d8bef9SDimitry Andric     return nullptr;
2251e8d8bef9SDimitry Andric   }
2252e8d8bef9SDimitry Andric 
2253e8d8bef9SDimitry Andric   if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {
2254e8d8bef9SDimitry Andric     Error(RHSLoc, Twine("expected value of type '") +
2255e8d8bef9SDimitry Andric                   ItemType->getAsString() + "', got '" +
2256e8d8bef9SDimitry Andric                   Type->getAsString() + "'");
2257e8d8bef9SDimitry Andric   }
2258e8d8bef9SDimitry Andric 
2259e8d8bef9SDimitry Andric   TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
2260e8d8bef9SDimitry Andric   if (!LHSt && !isa<UnsetInit>(LHS)) {
2261e8d8bef9SDimitry Andric     TokError("could not determine type of the string in !substr");
2262e8d8bef9SDimitry Andric     return nullptr;
2263e8d8bef9SDimitry Andric   }
2264e8d8bef9SDimitry Andric   if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
2265e8d8bef9SDimitry Andric     TokError(Twine("expected string, got type '") +
2266e8d8bef9SDimitry Andric              LHSt->getType()->getAsString() + "'");
2267e8d8bef9SDimitry Andric     return nullptr;
2268e8d8bef9SDimitry Andric   }
2269e8d8bef9SDimitry Andric 
2270e8d8bef9SDimitry Andric   TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2271e8d8bef9SDimitry Andric   if (!MHSt && !isa<UnsetInit>(MHS)) {
2272e8d8bef9SDimitry Andric     TokError("could not determine type of the start position in !substr");
2273e8d8bef9SDimitry Andric     return nullptr;
2274e8d8bef9SDimitry Andric   }
2275e8d8bef9SDimitry Andric   if (MHSt && !isa<IntRecTy>(MHSt->getType())) {
2276e8d8bef9SDimitry Andric     Error(MHSLoc, Twine("expected int, got type '") +
2277e8d8bef9SDimitry Andric                       MHSt->getType()->getAsString() + "'");
2278e8d8bef9SDimitry Andric     return nullptr;
2279e8d8bef9SDimitry Andric   }
2280e8d8bef9SDimitry Andric 
2281e8d8bef9SDimitry Andric   if (RHS) {
2282e8d8bef9SDimitry Andric     TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2283e8d8bef9SDimitry Andric     if (!RHSt && !isa<UnsetInit>(RHS)) {
2284e8d8bef9SDimitry Andric       TokError("could not determine type of the length in !substr");
2285e8d8bef9SDimitry Andric       return nullptr;
2286e8d8bef9SDimitry Andric     }
2287e8d8bef9SDimitry Andric     if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
2288e8d8bef9SDimitry Andric       TokError(Twine("expected int, got type '") +
2289e8d8bef9SDimitry Andric                RHSt->getType()->getAsString() + "'");
2290e8d8bef9SDimitry Andric       return nullptr;
2291e8d8bef9SDimitry Andric     }
2292e8d8bef9SDimitry Andric   }
2293e8d8bef9SDimitry Andric 
2294e8d8bef9SDimitry Andric   return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
2295e8d8bef9SDimitry Andric }
2296e8d8bef9SDimitry Andric 
2297fe6060f1SDimitry Andric /// Parse the !find operation. Return null on error.
2298fe6060f1SDimitry Andric ///
2299fe6060f1SDimitry Andric /// Substr ::= !find(string, string [, start-int]) => int
ParseOperationFind(Record * CurRec,RecTy * ItemType)2300fe6060f1SDimitry Andric Init *TGParser::ParseOperationFind(Record *CurRec, RecTy *ItemType) {
2301fe6060f1SDimitry Andric   TernOpInit::TernaryOp Code = TernOpInit::FIND;
230281ad6265SDimitry Andric   RecTy *Type = IntRecTy::get(Records);
2303fe6060f1SDimitry Andric 
2304fe6060f1SDimitry Andric   Lex.Lex(); // eat the operation
2305fe6060f1SDimitry Andric 
2306fe6060f1SDimitry Andric   if (!consume(tgtok::l_paren)) {
2307fe6060f1SDimitry Andric     TokError("expected '(' after !find operator");
2308fe6060f1SDimitry Andric     return nullptr;
2309fe6060f1SDimitry Andric   }
2310fe6060f1SDimitry Andric 
2311fe6060f1SDimitry Andric   Init *LHS = ParseValue(CurRec);
2312fe6060f1SDimitry Andric   if (!LHS)
2313fe6060f1SDimitry Andric     return nullptr;
2314fe6060f1SDimitry Andric 
2315fe6060f1SDimitry Andric   if (!consume(tgtok::comma)) {
2316fe6060f1SDimitry Andric     TokError("expected ',' in !find operator");
2317fe6060f1SDimitry Andric     return nullptr;
2318fe6060f1SDimitry Andric   }
2319fe6060f1SDimitry Andric 
2320fe6060f1SDimitry Andric   SMLoc MHSLoc = Lex.getLoc();
2321fe6060f1SDimitry Andric   Init *MHS = ParseValue(CurRec);
2322fe6060f1SDimitry Andric   if (!MHS)
2323fe6060f1SDimitry Andric     return nullptr;
2324fe6060f1SDimitry Andric 
2325fe6060f1SDimitry Andric   SMLoc RHSLoc = Lex.getLoc();
2326fe6060f1SDimitry Andric   Init *RHS;
2327fe6060f1SDimitry Andric   if (consume(tgtok::comma)) {
2328fe6060f1SDimitry Andric     RHSLoc = Lex.getLoc();
2329fe6060f1SDimitry Andric     RHS = ParseValue(CurRec);
2330fe6060f1SDimitry Andric     if (!RHS)
2331fe6060f1SDimitry Andric       return nullptr;
2332fe6060f1SDimitry Andric   } else {
233381ad6265SDimitry Andric     RHS = IntInit::get(Records, 0);
2334fe6060f1SDimitry Andric   }
2335fe6060f1SDimitry Andric 
2336fe6060f1SDimitry Andric   if (!consume(tgtok::r_paren)) {
2337fe6060f1SDimitry Andric     TokError("expected ')' in !find operator");
2338fe6060f1SDimitry Andric     return nullptr;
2339fe6060f1SDimitry Andric   }
2340fe6060f1SDimitry Andric 
2341fe6060f1SDimitry Andric   if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {
2342fe6060f1SDimitry Andric     Error(RHSLoc, Twine("expected value of type '") +
2343fe6060f1SDimitry Andric                   ItemType->getAsString() + "', got '" +
2344fe6060f1SDimitry Andric                   Type->getAsString() + "'");
2345fe6060f1SDimitry Andric   }
2346fe6060f1SDimitry Andric 
2347fe6060f1SDimitry Andric   TypedInit *LHSt = dyn_cast<TypedInit>(LHS);
2348fe6060f1SDimitry Andric   if (!LHSt && !isa<UnsetInit>(LHS)) {
2349fe6060f1SDimitry Andric     TokError("could not determine type of the source string in !find");
2350fe6060f1SDimitry Andric     return nullptr;
2351fe6060f1SDimitry Andric   }
2352fe6060f1SDimitry Andric   if (LHSt && !isa<StringRecTy>(LHSt->getType())) {
2353fe6060f1SDimitry Andric     TokError(Twine("expected string, got type '") +
2354fe6060f1SDimitry Andric              LHSt->getType()->getAsString() + "'");
2355fe6060f1SDimitry Andric     return nullptr;
2356fe6060f1SDimitry Andric   }
2357fe6060f1SDimitry Andric 
2358fe6060f1SDimitry Andric   TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2359fe6060f1SDimitry Andric   if (!MHSt && !isa<UnsetInit>(MHS)) {
2360fe6060f1SDimitry Andric     TokError("could not determine type of the target string in !find");
2361fe6060f1SDimitry Andric     return nullptr;
2362fe6060f1SDimitry Andric   }
2363fe6060f1SDimitry Andric   if (MHSt && !isa<StringRecTy>(MHSt->getType())) {
2364fe6060f1SDimitry Andric     Error(MHSLoc, Twine("expected string, got type '") +
2365fe6060f1SDimitry Andric                       MHSt->getType()->getAsString() + "'");
2366fe6060f1SDimitry Andric     return nullptr;
2367fe6060f1SDimitry Andric   }
2368fe6060f1SDimitry Andric 
2369fe6060f1SDimitry Andric   if (RHS) {
2370fe6060f1SDimitry Andric     TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2371fe6060f1SDimitry Andric     if (!RHSt && !isa<UnsetInit>(RHS)) {
2372fe6060f1SDimitry Andric       TokError("could not determine type of the start position in !find");
2373fe6060f1SDimitry Andric       return nullptr;
2374fe6060f1SDimitry Andric     }
2375fe6060f1SDimitry Andric     if (RHSt && !isa<IntRecTy>(RHSt->getType())) {
2376fe6060f1SDimitry Andric       TokError(Twine("expected int, got type '") +
2377fe6060f1SDimitry Andric                RHSt->getType()->getAsString() + "'");
2378fe6060f1SDimitry Andric       return nullptr;
2379fe6060f1SDimitry Andric     }
2380fe6060f1SDimitry Andric   }
2381fe6060f1SDimitry Andric 
2382fe6060f1SDimitry Andric   return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);
2383fe6060f1SDimitry Andric }
2384fe6060f1SDimitry Andric 
2385e8d8bef9SDimitry Andric /// Parse the !foreach and !filter operations. Return null on error.
2386e8d8bef9SDimitry Andric ///
2387e8d8bef9SDimitry Andric /// ForEach ::= !foreach(ID, list-or-dag, expr) => list<expr type>
2388e8d8bef9SDimitry Andric /// Filter  ::= !foreach(ID, list, predicate) ==> list<list type>
ParseOperationForEachFilter(Record * CurRec,RecTy * ItemType)2389e8d8bef9SDimitry Andric Init *TGParser::ParseOperationForEachFilter(Record *CurRec, RecTy *ItemType) {
2390e8d8bef9SDimitry Andric   SMLoc OpLoc = Lex.getLoc();
2391e8d8bef9SDimitry Andric   tgtok::TokKind Operation = Lex.getCode();
2392e8d8bef9SDimitry Andric   Lex.Lex(); // eat the operation
2393e8d8bef9SDimitry Andric   if (Lex.getCode() != tgtok::l_paren) {
2394e8d8bef9SDimitry Andric     TokError("expected '(' after !foreach/!filter");
2395e8d8bef9SDimitry Andric     return nullptr;
2396e8d8bef9SDimitry Andric   }
2397e8d8bef9SDimitry Andric 
2398e8d8bef9SDimitry Andric   if (Lex.Lex() != tgtok::Id) { // eat the '('
2399e8d8bef9SDimitry Andric     TokError("first argument of !foreach/!filter must be an identifier");
2400e8d8bef9SDimitry Andric     return nullptr;
2401e8d8bef9SDimitry Andric   }
2402e8d8bef9SDimitry Andric 
240381ad6265SDimitry Andric   Init *LHS = StringInit::get(Records, Lex.getCurStrVal());
2404e8d8bef9SDimitry Andric   Lex.Lex(); // eat the ID.
2405e8d8bef9SDimitry Andric 
2406e8d8bef9SDimitry Andric   if (CurRec && CurRec->getValue(LHS)) {
2407e8d8bef9SDimitry Andric     TokError((Twine("iteration variable '") + LHS->getAsString() +
2408e8d8bef9SDimitry Andric               "' is already defined")
2409e8d8bef9SDimitry Andric                  .str());
2410e8d8bef9SDimitry Andric     return nullptr;
2411e8d8bef9SDimitry Andric   }
2412e8d8bef9SDimitry Andric 
2413e8d8bef9SDimitry Andric   if (!consume(tgtok::comma)) {
2414e8d8bef9SDimitry Andric     TokError("expected ',' in !foreach/!filter");
2415e8d8bef9SDimitry Andric     return nullptr;
2416e8d8bef9SDimitry Andric   }
2417e8d8bef9SDimitry Andric 
2418e8d8bef9SDimitry Andric   Init *MHS = ParseValue(CurRec);
2419e8d8bef9SDimitry Andric   if (!MHS)
2420e8d8bef9SDimitry Andric     return nullptr;
2421e8d8bef9SDimitry Andric 
2422e8d8bef9SDimitry Andric   if (!consume(tgtok::comma)) {
2423e8d8bef9SDimitry Andric     TokError("expected ',' in !foreach/!filter");
2424e8d8bef9SDimitry Andric     return nullptr;
2425e8d8bef9SDimitry Andric   }
2426e8d8bef9SDimitry Andric 
2427e8d8bef9SDimitry Andric   TypedInit *MHSt = dyn_cast<TypedInit>(MHS);
2428e8d8bef9SDimitry Andric   if (!MHSt) {
2429e8d8bef9SDimitry Andric     TokError("could not get type of !foreach/!filter list or dag");
2430e8d8bef9SDimitry Andric     return nullptr;
2431e8d8bef9SDimitry Andric   }
2432e8d8bef9SDimitry Andric 
2433e8d8bef9SDimitry Andric   RecTy *InEltType = nullptr;
2434e8d8bef9SDimitry Andric   RecTy *ExprEltType = nullptr;
2435e8d8bef9SDimitry Andric   bool IsDAG = false;
2436e8d8bef9SDimitry Andric 
2437e8d8bef9SDimitry Andric   if (ListRecTy *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) {
2438e8d8bef9SDimitry Andric     InEltType = InListTy->getElementType();
2439e8d8bef9SDimitry Andric     if (ItemType) {
2440e8d8bef9SDimitry Andric       if (ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) {
2441e8d8bef9SDimitry Andric         ExprEltType = (Operation == tgtok::XForEach)
2442e8d8bef9SDimitry Andric                           ? OutListTy->getElementType()
244381ad6265SDimitry Andric                           : IntRecTy::get(Records);
2444e8d8bef9SDimitry Andric       } else {
2445e8d8bef9SDimitry Andric         Error(OpLoc,
2446e8d8bef9SDimitry Andric               "expected value of type '" +
2447e8d8bef9SDimitry Andric                   Twine(ItemType->getAsString()) +
2448e8d8bef9SDimitry Andric                   "', but got list type");
2449e8d8bef9SDimitry Andric         return nullptr;
2450e8d8bef9SDimitry Andric       }
2451e8d8bef9SDimitry Andric     }
2452e8d8bef9SDimitry Andric   } else if (DagRecTy *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) {
2453e8d8bef9SDimitry Andric     if (Operation == tgtok::XFilter) {
2454e8d8bef9SDimitry Andric       TokError("!filter must have a list argument");
2455e8d8bef9SDimitry Andric       return nullptr;
2456e8d8bef9SDimitry Andric     }
2457e8d8bef9SDimitry Andric     InEltType = InDagTy;
2458e8d8bef9SDimitry Andric     if (ItemType && !isa<DagRecTy>(ItemType)) {
2459e8d8bef9SDimitry Andric       Error(OpLoc,
2460e8d8bef9SDimitry Andric             "expected value of type '" + Twine(ItemType->getAsString()) +
2461e8d8bef9SDimitry Andric                 "', but got dag type");
2462e8d8bef9SDimitry Andric       return nullptr;
2463e8d8bef9SDimitry Andric     }
2464e8d8bef9SDimitry Andric     IsDAG = true;
2465e8d8bef9SDimitry Andric   } else {
2466e8d8bef9SDimitry Andric     if (Operation == tgtok::XForEach)
2467e8d8bef9SDimitry Andric       TokError("!foreach must have a list or dag argument");
2468e8d8bef9SDimitry Andric     else
2469e8d8bef9SDimitry Andric       TokError("!filter must have a list argument");
2470e8d8bef9SDimitry Andric     return nullptr;
2471e8d8bef9SDimitry Andric   }
2472e8d8bef9SDimitry Andric 
2473e8d8bef9SDimitry Andric   // We need to create a temporary record to provide a scope for the
2474e8d8bef9SDimitry Andric   // iteration variable.
2475e8d8bef9SDimitry Andric   std::unique_ptr<Record> ParseRecTmp;
2476e8d8bef9SDimitry Andric   Record *ParseRec = CurRec;
2477e8d8bef9SDimitry Andric   if (!ParseRec) {
2478e8d8bef9SDimitry Andric     ParseRecTmp =
2479e8d8bef9SDimitry Andric         std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);
2480e8d8bef9SDimitry Andric     ParseRec = ParseRecTmp.get();
2481e8d8bef9SDimitry Andric   }
248206c3fb27SDimitry Andric   TGVarScope *TempScope = PushScope(ParseRec);
2483e8d8bef9SDimitry Andric   ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal));
2484e8d8bef9SDimitry Andric   Init *RHS = ParseValue(ParseRec, ExprEltType);
2485e8d8bef9SDimitry Andric   ParseRec->removeValue(LHS);
248606c3fb27SDimitry Andric   PopScope(TempScope);
2487e8d8bef9SDimitry Andric   if (!RHS)
2488e8d8bef9SDimitry Andric     return nullptr;
2489e8d8bef9SDimitry Andric 
2490e8d8bef9SDimitry Andric   if (!consume(tgtok::r_paren)) {
2491e8d8bef9SDimitry Andric     TokError("expected ')' in !foreach/!filter");
2492e8d8bef9SDimitry Andric     return nullptr;
2493e8d8bef9SDimitry Andric   }
2494e8d8bef9SDimitry Andric 
2495e8d8bef9SDimitry Andric   RecTy *OutType = InEltType;
2496e8d8bef9SDimitry Andric   if (Operation == tgtok::XForEach && !IsDAG) {
2497e8d8bef9SDimitry Andric     TypedInit *RHSt = dyn_cast<TypedInit>(RHS);
2498e8d8bef9SDimitry Andric     if (!RHSt) {
2499e8d8bef9SDimitry Andric       TokError("could not get type of !foreach result expression");
2500e8d8bef9SDimitry Andric       return nullptr;
2501e8d8bef9SDimitry Andric     }
2502e8d8bef9SDimitry Andric     OutType = RHSt->getType()->getListTy();
2503e8d8bef9SDimitry Andric   } else if (Operation == tgtok::XFilter) {
2504e8d8bef9SDimitry Andric     OutType = InEltType->getListTy();
2505e8d8bef9SDimitry Andric   }
2506e8d8bef9SDimitry Andric 
2507e8d8bef9SDimitry Andric   return (TernOpInit::get((Operation == tgtok::XForEach) ? TernOpInit::FOREACH
2508e8d8bef9SDimitry Andric                                                          : TernOpInit::FILTER,
2509e8d8bef9SDimitry Andric                           LHS, MHS, RHS, OutType))
2510e8d8bef9SDimitry Andric       ->Fold(CurRec);
2511e8d8bef9SDimitry Andric }
2512e8d8bef9SDimitry Andric 
ParseOperationCond(Record * CurRec,RecTy * ItemType)25130b57cec5SDimitry Andric Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
25140b57cec5SDimitry Andric   Lex.Lex();  // eat the operation 'cond'
25150b57cec5SDimitry Andric 
25165ffd83dbSDimitry Andric   if (!consume(tgtok::l_paren)) {
25170b57cec5SDimitry Andric     TokError("expected '(' after !cond operator");
25180b57cec5SDimitry Andric     return nullptr;
25190b57cec5SDimitry Andric   }
25200b57cec5SDimitry Andric 
25210b57cec5SDimitry Andric   // Parse through '[Case: Val,]+'
25220b57cec5SDimitry Andric   SmallVector<Init *, 4> Case;
25230b57cec5SDimitry Andric   SmallVector<Init *, 4> Val;
25240b57cec5SDimitry Andric   while (true) {
25255ffd83dbSDimitry Andric     if (consume(tgtok::r_paren))
25260b57cec5SDimitry Andric       break;
25270b57cec5SDimitry Andric 
25280b57cec5SDimitry Andric     Init *V = ParseValue(CurRec);
25290b57cec5SDimitry Andric     if (!V)
25300b57cec5SDimitry Andric       return nullptr;
25310b57cec5SDimitry Andric     Case.push_back(V);
25320b57cec5SDimitry Andric 
25335ffd83dbSDimitry Andric     if (!consume(tgtok::colon)) {
25340b57cec5SDimitry Andric       TokError("expected ':'  following a condition in !cond operator");
25350b57cec5SDimitry Andric       return nullptr;
25360b57cec5SDimitry Andric     }
25370b57cec5SDimitry Andric 
25380b57cec5SDimitry Andric     V = ParseValue(CurRec, ItemType);
25390b57cec5SDimitry Andric     if (!V)
25400b57cec5SDimitry Andric       return nullptr;
25410b57cec5SDimitry Andric     Val.push_back(V);
25420b57cec5SDimitry Andric 
25435ffd83dbSDimitry Andric     if (consume(tgtok::r_paren))
25440b57cec5SDimitry Andric       break;
25450b57cec5SDimitry Andric 
25465ffd83dbSDimitry Andric     if (!consume(tgtok::comma)) {
25470b57cec5SDimitry Andric       TokError("expected ',' or ')' following a value in !cond operator");
25480b57cec5SDimitry Andric       return nullptr;
25490b57cec5SDimitry Andric     }
25500b57cec5SDimitry Andric   }
25510b57cec5SDimitry Andric 
25520b57cec5SDimitry Andric   if (Case.size() < 1) {
25530b57cec5SDimitry Andric     TokError("there should be at least 1 'condition : value' in the !cond operator");
25540b57cec5SDimitry Andric     return nullptr;
25550b57cec5SDimitry Andric   }
25560b57cec5SDimitry Andric 
25570b57cec5SDimitry Andric   // resolve type
25580b57cec5SDimitry Andric   RecTy *Type = nullptr;
25590b57cec5SDimitry Andric   for (Init *V : Val) {
25600b57cec5SDimitry Andric     RecTy *VTy = nullptr;
25610b57cec5SDimitry Andric     if (TypedInit *Vt = dyn_cast<TypedInit>(V))
25620b57cec5SDimitry Andric       VTy = Vt->getType();
25630b57cec5SDimitry Andric     if (BitsInit *Vbits = dyn_cast<BitsInit>(V))
256481ad6265SDimitry Andric       VTy = BitsRecTy::get(Records, Vbits->getNumBits());
25650b57cec5SDimitry Andric     if (isa<BitInit>(V))
256681ad6265SDimitry Andric       VTy = BitRecTy::get(Records);
25670b57cec5SDimitry Andric 
25680b57cec5SDimitry Andric     if (Type == nullptr) {
25690b57cec5SDimitry Andric       if (!isa<UnsetInit>(V))
25700b57cec5SDimitry Andric         Type = VTy;
25710b57cec5SDimitry Andric     } else {
25720b57cec5SDimitry Andric       if (!isa<UnsetInit>(V)) {
25730b57cec5SDimitry Andric         RecTy *RType = resolveTypes(Type, VTy);
25740b57cec5SDimitry Andric         if (!RType) {
25750b57cec5SDimitry Andric           TokError(Twine("inconsistent types '") + Type->getAsString() +
25760b57cec5SDimitry Andric                          "' and '" + VTy->getAsString() + "' for !cond");
25770b57cec5SDimitry Andric           return nullptr;
25780b57cec5SDimitry Andric         }
25790b57cec5SDimitry Andric         Type = RType;
25800b57cec5SDimitry Andric       }
25810b57cec5SDimitry Andric     }
25820b57cec5SDimitry Andric   }
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric   if (!Type) {
25850b57cec5SDimitry Andric     TokError("could not determine type for !cond from its arguments");
25860b57cec5SDimitry Andric     return nullptr;
25870b57cec5SDimitry Andric   }
25880b57cec5SDimitry Andric   return CondOpInit::get(Case, Val, Type)->Fold(CurRec);
25890b57cec5SDimitry Andric }
25900b57cec5SDimitry Andric 
25910b57cec5SDimitry Andric /// ParseSimpleValue - Parse a tblgen value.  This returns null on error.
25920b57cec5SDimitry Andric ///
25930b57cec5SDimitry Andric ///   SimpleValue ::= IDValue
25940b57cec5SDimitry Andric ///   SimpleValue ::= INTVAL
25950b57cec5SDimitry Andric ///   SimpleValue ::= STRVAL+
25960b57cec5SDimitry Andric ///   SimpleValue ::= CODEFRAGMENT
25970b57cec5SDimitry Andric ///   SimpleValue ::= '?'
25980b57cec5SDimitry Andric ///   SimpleValue ::= '{' ValueList '}'
25990b57cec5SDimitry Andric ///   SimpleValue ::= ID '<' ValueListNE '>'
26000b57cec5SDimitry Andric ///   SimpleValue ::= '[' ValueList ']'
26010b57cec5SDimitry Andric ///   SimpleValue ::= '(' IDValue DagArgList ')'
26020b57cec5SDimitry Andric ///   SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
26030b57cec5SDimitry Andric ///   SimpleValue ::= ADDTOK '(' Value ',' Value ')'
2604bdd1243dSDimitry Andric ///   SimpleValue ::= DIVTOK '(' Value ',' Value ')'
2605e8d8bef9SDimitry Andric ///   SimpleValue ::= SUBTOK '(' Value ',' Value ')'
26060b57cec5SDimitry Andric ///   SimpleValue ::= SHLTOK '(' Value ',' Value ')'
26070b57cec5SDimitry Andric ///   SimpleValue ::= SRATOK '(' Value ',' Value ')'
26080b57cec5SDimitry Andric ///   SimpleValue ::= SRLTOK '(' Value ',' Value ')'
26090b57cec5SDimitry Andric ///   SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
26100b57cec5SDimitry Andric ///   SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')'
2611bdd1243dSDimitry Andric ///   SimpleValue ::= LISTREMOVETOK '(' Value ',' Value ')'
261206c3fb27SDimitry Andric ///   SimpleValue ::= RANGE '(' Value ')'
261306c3fb27SDimitry Andric ///   SimpleValue ::= RANGE '(' Value ',' Value ')'
26145f757f3fSDimitry Andric ///   SimpleValue ::= RANGE '(' Value ',' Value ',' Value ')'
26150b57cec5SDimitry Andric ///   SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
26160b57cec5SDimitry Andric ///   SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
26170b57cec5SDimitry Andric ///
ParseSimpleValue(Record * CurRec,RecTy * ItemType,IDParseMode Mode)26180b57cec5SDimitry Andric Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
26190b57cec5SDimitry Andric                                  IDParseMode Mode) {
26200b57cec5SDimitry Andric   Init *R = nullptr;
26215f757f3fSDimitry Andric   tgtok::TokKind Code = Lex.getCode();
26225f757f3fSDimitry Andric 
26235f757f3fSDimitry Andric   // Parse bang operators.
26245f757f3fSDimitry Andric   if (tgtok::isBangOperator(Code))
26255f757f3fSDimitry Andric     return ParseOperation(CurRec, ItemType);
26265f757f3fSDimitry Andric 
26275f757f3fSDimitry Andric   switch (Code) {
2628e8d8bef9SDimitry Andric   default: TokError("Unknown or reserved token when parsing a value"); break;
2629e8d8bef9SDimitry Andric 
2630e8d8bef9SDimitry Andric   case tgtok::TrueVal:
263181ad6265SDimitry Andric     R = IntInit::get(Records, 1);
2632e8d8bef9SDimitry Andric     Lex.Lex();
2633e8d8bef9SDimitry Andric     break;
2634e8d8bef9SDimitry Andric   case tgtok::FalseVal:
263581ad6265SDimitry Andric     R = IntInit::get(Records, 0);
2636e8d8bef9SDimitry Andric     Lex.Lex();
2637e8d8bef9SDimitry Andric     break;
2638e8d8bef9SDimitry Andric   case tgtok::IntVal:
263981ad6265SDimitry Andric     R = IntInit::get(Records, Lex.getCurIntVal());
2640e8d8bef9SDimitry Andric     Lex.Lex();
2641e8d8bef9SDimitry Andric     break;
26420b57cec5SDimitry Andric   case tgtok::BinaryIntVal: {
26430b57cec5SDimitry Andric     auto BinaryVal = Lex.getCurBinaryIntVal();
26440b57cec5SDimitry Andric     SmallVector<Init*, 16> Bits(BinaryVal.second);
26450b57cec5SDimitry Andric     for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)
264681ad6265SDimitry Andric       Bits[i] = BitInit::get(Records, BinaryVal.first & (1LL << i));
264781ad6265SDimitry Andric     R = BitsInit::get(Records, Bits);
26480b57cec5SDimitry Andric     Lex.Lex();
26490b57cec5SDimitry Andric     break;
26500b57cec5SDimitry Andric   }
26510b57cec5SDimitry Andric   case tgtok::StrVal: {
26520b57cec5SDimitry Andric     std::string Val = Lex.getCurStrVal();
26530b57cec5SDimitry Andric     Lex.Lex();
26540b57cec5SDimitry Andric 
26550b57cec5SDimitry Andric     // Handle multiple consecutive concatenated strings.
26560b57cec5SDimitry Andric     while (Lex.getCode() == tgtok::StrVal) {
26570b57cec5SDimitry Andric       Val += Lex.getCurStrVal();
26580b57cec5SDimitry Andric       Lex.Lex();
26590b57cec5SDimitry Andric     }
26600b57cec5SDimitry Andric 
266181ad6265SDimitry Andric     R = StringInit::get(Records, Val);
26620b57cec5SDimitry Andric     break;
26630b57cec5SDimitry Andric   }
26640b57cec5SDimitry Andric   case tgtok::CodeFragment:
266581ad6265SDimitry Andric     R = StringInit::get(Records, Lex.getCurStrVal(), StringInit::SF_Code);
26660b57cec5SDimitry Andric     Lex.Lex();
26670b57cec5SDimitry Andric     break;
26680b57cec5SDimitry Andric   case tgtok::question:
266981ad6265SDimitry Andric     R = UnsetInit::get(Records);
26700b57cec5SDimitry Andric     Lex.Lex();
26710b57cec5SDimitry Andric     break;
26720b57cec5SDimitry Andric   case tgtok::Id: {
2673bdd1243dSDimitry Andric     SMRange NameLoc = Lex.getLocRange();
267481ad6265SDimitry Andric     StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
267506c3fb27SDimitry Andric     tgtok::TokKind Next = Lex.Lex();
267606c3fb27SDimitry Andric     if (Next == tgtok::equal) // Named argument.
267706c3fb27SDimitry Andric       return Name;
267806c3fb27SDimitry Andric     if (Next != tgtok::less)                            // consume the Id.
26790b57cec5SDimitry Andric       return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue
26800b57cec5SDimitry Andric 
268106c3fb27SDimitry Andric     // Value ::= CLASSID '<' ArgValueList '>' (CLASSID has been consumed)
2682fe6060f1SDimitry Andric     // This is supposed to synthesize a new anonymous definition, deriving
2683fe6060f1SDimitry Andric     // from the class with the template arguments, but no body.
26840b57cec5SDimitry Andric     Record *Class = Records.getClass(Name->getValue());
26850b57cec5SDimitry Andric     if (!Class) {
2686bdd1243dSDimitry Andric       Error(NameLoc.Start,
2687bdd1243dSDimitry Andric             "Expected a class name, got '" + Name->getValue() + "'");
26880b57cec5SDimitry Andric       return nullptr;
26890b57cec5SDimitry Andric     }
26900b57cec5SDimitry Andric 
269106c3fb27SDimitry Andric     SmallVector<ArgumentInit *, 8> Args;
2692fe6060f1SDimitry Andric     Lex.Lex(); // consume the <
2693fe6060f1SDimitry Andric     if (ParseTemplateArgValueList(Args, CurRec, Class))
2694fe6060f1SDimitry Andric       return nullptr; // Error parsing value list.
26950b57cec5SDimitry Andric 
2696bdd1243dSDimitry Andric     if (CheckTemplateArgValues(Args, NameLoc.Start, Class))
2697fe6060f1SDimitry Andric       return nullptr; // Error checking template argument values.
26980b57cec5SDimitry Andric 
269906c3fb27SDimitry Andric     if (resolveArguments(Class, Args, NameLoc.Start))
270006c3fb27SDimitry Andric       return nullptr;
27010b57cec5SDimitry Andric 
2702bdd1243dSDimitry Andric     if (TrackReferenceLocs)
2703bdd1243dSDimitry Andric       Class->appendReferenceLoc(NameLoc);
27040b57cec5SDimitry Andric     return VarDefInit::get(Class, Args)->Fold();
27050b57cec5SDimitry Andric   }
27060b57cec5SDimitry Andric   case tgtok::l_brace: {           // Value ::= '{' ValueList '}'
27070b57cec5SDimitry Andric     SMLoc BraceLoc = Lex.getLoc();
27080b57cec5SDimitry Andric     Lex.Lex(); // eat the '{'
27090b57cec5SDimitry Andric     SmallVector<Init*, 16> Vals;
27100b57cec5SDimitry Andric 
27110b57cec5SDimitry Andric     if (Lex.getCode() != tgtok::r_brace) {
27120b57cec5SDimitry Andric       ParseValueList(Vals, CurRec);
27130b57cec5SDimitry Andric       if (Vals.empty()) return nullptr;
27140b57cec5SDimitry Andric     }
27155ffd83dbSDimitry Andric     if (!consume(tgtok::r_brace)) {
27160b57cec5SDimitry Andric       TokError("expected '}' at end of bit list value");
27170b57cec5SDimitry Andric       return nullptr;
27180b57cec5SDimitry Andric     }
27190b57cec5SDimitry Andric 
27200b57cec5SDimitry Andric     SmallVector<Init *, 16> NewBits;
27210b57cec5SDimitry Andric 
27220b57cec5SDimitry Andric     // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it
27230b57cec5SDimitry Andric     // first.  We'll first read everything in to a vector, then we can reverse
27240b57cec5SDimitry Andric     // it to get the bits in the correct order for the BitsInit value.
27250b57cec5SDimitry Andric     for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
27260b57cec5SDimitry Andric       // FIXME: The following two loops would not be duplicated
27270b57cec5SDimitry Andric       //        if the API was a little more orthogonal.
27280b57cec5SDimitry Andric 
27290b57cec5SDimitry Andric       // bits<n> values are allowed to initialize n bits.
27300b57cec5SDimitry Andric       if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) {
27310b57cec5SDimitry Andric         for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
27320b57cec5SDimitry Andric           NewBits.push_back(BI->getBit((e - i) - 1));
27330b57cec5SDimitry Andric         continue;
27340b57cec5SDimitry Andric       }
27350b57cec5SDimitry Andric       // bits<n> can also come from variable initializers.
27360b57cec5SDimitry Andric       if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) {
27370b57cec5SDimitry Andric         if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) {
27380b57cec5SDimitry Andric           for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
27390b57cec5SDimitry Andric             NewBits.push_back(VI->getBit((e - i) - 1));
27400b57cec5SDimitry Andric           continue;
27410b57cec5SDimitry Andric         }
27420b57cec5SDimitry Andric         // Fallthrough to try convert this to a bit.
27430b57cec5SDimitry Andric       }
27440b57cec5SDimitry Andric       // All other values must be convertible to just a single bit.
274581ad6265SDimitry Andric       Init *Bit = Vals[i]->getCastTo(BitRecTy::get(Records));
27460b57cec5SDimitry Andric       if (!Bit) {
27470b57cec5SDimitry Andric         Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
27480b57cec5SDimitry Andric               ") is not convertable to a bit");
27490b57cec5SDimitry Andric         return nullptr;
27500b57cec5SDimitry Andric       }
27510b57cec5SDimitry Andric       NewBits.push_back(Bit);
27520b57cec5SDimitry Andric     }
27530b57cec5SDimitry Andric     std::reverse(NewBits.begin(), NewBits.end());
275481ad6265SDimitry Andric     return BitsInit::get(Records, NewBits);
27550b57cec5SDimitry Andric   }
27560b57cec5SDimitry Andric   case tgtok::l_square: {          // Value ::= '[' ValueList ']'
27570b57cec5SDimitry Andric     Lex.Lex(); // eat the '['
27580b57cec5SDimitry Andric     SmallVector<Init*, 16> Vals;
27590b57cec5SDimitry Andric 
27600b57cec5SDimitry Andric     RecTy *DeducedEltTy = nullptr;
27610b57cec5SDimitry Andric     ListRecTy *GivenListTy = nullptr;
27620b57cec5SDimitry Andric 
27630b57cec5SDimitry Andric     if (ItemType) {
27640b57cec5SDimitry Andric       ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType);
27650b57cec5SDimitry Andric       if (!ListType) {
2766e8d8bef9SDimitry Andric         TokError(Twine("Encountered a list when expecting a ") +
27670b57cec5SDimitry Andric                  ItemType->getAsString());
27680b57cec5SDimitry Andric         return nullptr;
27690b57cec5SDimitry Andric       }
27700b57cec5SDimitry Andric       GivenListTy = ListType;
27710b57cec5SDimitry Andric     }
27720b57cec5SDimitry Andric 
27730b57cec5SDimitry Andric     if (Lex.getCode() != tgtok::r_square) {
2774fe6060f1SDimitry Andric       ParseValueList(Vals, CurRec,
27750b57cec5SDimitry Andric                      GivenListTy ? GivenListTy->getElementType() : nullptr);
27760b57cec5SDimitry Andric       if (Vals.empty()) return nullptr;
27770b57cec5SDimitry Andric     }
27785ffd83dbSDimitry Andric     if (!consume(tgtok::r_square)) {
27790b57cec5SDimitry Andric       TokError("expected ']' at end of list value");
27800b57cec5SDimitry Andric       return nullptr;
27810b57cec5SDimitry Andric     }
27820b57cec5SDimitry Andric 
27830b57cec5SDimitry Andric     RecTy *GivenEltTy = nullptr;
27845ffd83dbSDimitry Andric     if (consume(tgtok::less)) {
27850b57cec5SDimitry Andric       // Optional list element type
27860b57cec5SDimitry Andric       GivenEltTy = ParseType();
27870b57cec5SDimitry Andric       if (!GivenEltTy) {
27880b57cec5SDimitry Andric         // Couldn't parse element type
27890b57cec5SDimitry Andric         return nullptr;
27900b57cec5SDimitry Andric       }
27910b57cec5SDimitry Andric 
27925ffd83dbSDimitry Andric       if (!consume(tgtok::greater)) {
27930b57cec5SDimitry Andric         TokError("expected '>' at end of list element type");
27940b57cec5SDimitry Andric         return nullptr;
27950b57cec5SDimitry Andric       }
27960b57cec5SDimitry Andric     }
27970b57cec5SDimitry Andric 
27980b57cec5SDimitry Andric     // Check elements
27990b57cec5SDimitry Andric     RecTy *EltTy = nullptr;
28000b57cec5SDimitry Andric     for (Init *V : Vals) {
28010b57cec5SDimitry Andric       TypedInit *TArg = dyn_cast<TypedInit>(V);
28020b57cec5SDimitry Andric       if (TArg) {
28030b57cec5SDimitry Andric         if (EltTy) {
28040b57cec5SDimitry Andric           EltTy = resolveTypes(EltTy, TArg->getType());
28050b57cec5SDimitry Andric           if (!EltTy) {
28060b57cec5SDimitry Andric             TokError("Incompatible types in list elements");
28070b57cec5SDimitry Andric             return nullptr;
28080b57cec5SDimitry Andric           }
28090b57cec5SDimitry Andric         } else {
28100b57cec5SDimitry Andric           EltTy = TArg->getType();
28110b57cec5SDimitry Andric         }
28120b57cec5SDimitry Andric       }
28130b57cec5SDimitry Andric     }
28140b57cec5SDimitry Andric 
28150b57cec5SDimitry Andric     if (GivenEltTy) {
28160b57cec5SDimitry Andric       if (EltTy) {
28170b57cec5SDimitry Andric         // Verify consistency
28180b57cec5SDimitry Andric         if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
28190b57cec5SDimitry Andric           TokError("Incompatible types in list elements");
28200b57cec5SDimitry Andric           return nullptr;
28210b57cec5SDimitry Andric         }
28220b57cec5SDimitry Andric       }
28230b57cec5SDimitry Andric       EltTy = GivenEltTy;
28240b57cec5SDimitry Andric     }
28250b57cec5SDimitry Andric 
28260b57cec5SDimitry Andric     if (!EltTy) {
28270b57cec5SDimitry Andric       if (!ItemType) {
28280b57cec5SDimitry Andric         TokError("No type for list");
28290b57cec5SDimitry Andric         return nullptr;
28300b57cec5SDimitry Andric       }
28310b57cec5SDimitry Andric       DeducedEltTy = GivenListTy->getElementType();
28320b57cec5SDimitry Andric     } else {
28330b57cec5SDimitry Andric       // Make sure the deduced type is compatible with the given type
28340b57cec5SDimitry Andric       if (GivenListTy) {
28350b57cec5SDimitry Andric         if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
28360b57cec5SDimitry Andric           TokError(Twine("Element type mismatch for list: element type '") +
28370b57cec5SDimitry Andric                    EltTy->getAsString() + "' not convertible to '" +
28380b57cec5SDimitry Andric                    GivenListTy->getElementType()->getAsString());
28390b57cec5SDimitry Andric           return nullptr;
28400b57cec5SDimitry Andric         }
28410b57cec5SDimitry Andric       }
28420b57cec5SDimitry Andric       DeducedEltTy = EltTy;
28430b57cec5SDimitry Andric     }
28440b57cec5SDimitry Andric 
28450b57cec5SDimitry Andric     return ListInit::get(Vals, DeducedEltTy);
28460b57cec5SDimitry Andric   }
28470b57cec5SDimitry Andric   case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
28480b57cec5SDimitry Andric     Lex.Lex();   // eat the '('
2849480093f4SDimitry Andric     if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&
2850e8d8bef9SDimitry Andric         Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp) {
28510b57cec5SDimitry Andric       TokError("expected identifier in dag init");
28520b57cec5SDimitry Andric       return nullptr;
28530b57cec5SDimitry Andric     }
28540b57cec5SDimitry Andric 
28550b57cec5SDimitry Andric     Init *Operator = ParseValue(CurRec);
28560b57cec5SDimitry Andric     if (!Operator) return nullptr;
28570b57cec5SDimitry Andric 
28580b57cec5SDimitry Andric     // If the operator name is present, parse it.
28590b57cec5SDimitry Andric     StringInit *OperatorName = nullptr;
28605ffd83dbSDimitry Andric     if (consume(tgtok::colon)) {
28615ffd83dbSDimitry Andric       if (Lex.getCode() != tgtok::VarName) { // eat the ':'
28620b57cec5SDimitry Andric         TokError("expected variable name in dag operator");
28630b57cec5SDimitry Andric         return nullptr;
28640b57cec5SDimitry Andric       }
286581ad6265SDimitry Andric       OperatorName = StringInit::get(Records, Lex.getCurStrVal());
28660b57cec5SDimitry Andric       Lex.Lex();  // eat the VarName.
28670b57cec5SDimitry Andric     }
28680b57cec5SDimitry Andric 
28690b57cec5SDimitry Andric     SmallVector<std::pair<llvm::Init*, StringInit*>, 8> DagArgs;
28700b57cec5SDimitry Andric     if (Lex.getCode() != tgtok::r_paren) {
28710b57cec5SDimitry Andric       ParseDagArgList(DagArgs, CurRec);
28720b57cec5SDimitry Andric       if (DagArgs.empty()) return nullptr;
28730b57cec5SDimitry Andric     }
28740b57cec5SDimitry Andric 
28755ffd83dbSDimitry Andric     if (!consume(tgtok::r_paren)) {
28760b57cec5SDimitry Andric       TokError("expected ')' in dag init");
28770b57cec5SDimitry Andric       return nullptr;
28780b57cec5SDimitry Andric     }
28790b57cec5SDimitry Andric 
28800b57cec5SDimitry Andric     return DagInit::get(Operator, OperatorName, DagArgs);
28810b57cec5SDimitry Andric   }
28820b57cec5SDimitry Andric   }
28830b57cec5SDimitry Andric 
28840b57cec5SDimitry Andric   return R;
28850b57cec5SDimitry Andric }
28860b57cec5SDimitry Andric 
2887e8d8bef9SDimitry Andric /// ParseValue - Parse a TableGen value. This returns null on error.
28880b57cec5SDimitry Andric ///
28890b57cec5SDimitry Andric ///   Value       ::= SimpleValue ValueSuffix*
28900b57cec5SDimitry Andric ///   ValueSuffix ::= '{' BitList '}'
289106c3fb27SDimitry Andric ///   ValueSuffix ::= '[' SliceElements ']'
28920b57cec5SDimitry Andric ///   ValueSuffix ::= '.' ID
28930b57cec5SDimitry Andric ///
ParseValue(Record * CurRec,RecTy * ItemType,IDParseMode Mode)28940b57cec5SDimitry Andric Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
289506c3fb27SDimitry Andric   SMLoc LHSLoc = Lex.getLoc();
28960b57cec5SDimitry Andric   Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
28970b57cec5SDimitry Andric   if (!Result) return nullptr;
28980b57cec5SDimitry Andric 
28990b57cec5SDimitry Andric   // Parse the suffixes now if present.
29000b57cec5SDimitry Andric   while (true) {
29010b57cec5SDimitry Andric     switch (Lex.getCode()) {
29020b57cec5SDimitry Andric     default: return Result;
29030b57cec5SDimitry Andric     case tgtok::l_brace: {
29040b57cec5SDimitry Andric       if (Mode == ParseNameMode)
29050b57cec5SDimitry Andric         // This is the beginning of the object body.
29060b57cec5SDimitry Andric         return Result;
29070b57cec5SDimitry Andric 
29080b57cec5SDimitry Andric       SMLoc CurlyLoc = Lex.getLoc();
29090b57cec5SDimitry Andric       Lex.Lex(); // eat the '{'
29100b57cec5SDimitry Andric       SmallVector<unsigned, 16> Ranges;
29110b57cec5SDimitry Andric       ParseRangeList(Ranges);
29120b57cec5SDimitry Andric       if (Ranges.empty()) return nullptr;
29130b57cec5SDimitry Andric 
29140b57cec5SDimitry Andric       // Reverse the bitlist.
29150b57cec5SDimitry Andric       std::reverse(Ranges.begin(), Ranges.end());
29160b57cec5SDimitry Andric       Result = Result->convertInitializerBitRange(Ranges);
29170b57cec5SDimitry Andric       if (!Result) {
29180b57cec5SDimitry Andric         Error(CurlyLoc, "Invalid bit range for value");
29190b57cec5SDimitry Andric         return nullptr;
29200b57cec5SDimitry Andric       }
29210b57cec5SDimitry Andric 
29220b57cec5SDimitry Andric       // Eat the '}'.
29235ffd83dbSDimitry Andric       if (!consume(tgtok::r_brace)) {
29240b57cec5SDimitry Andric         TokError("expected '}' at end of bit range list");
29250b57cec5SDimitry Andric         return nullptr;
29260b57cec5SDimitry Andric       }
29270b57cec5SDimitry Andric       break;
29280b57cec5SDimitry Andric     }
29290b57cec5SDimitry Andric     case tgtok::l_square: {
293006c3fb27SDimitry Andric       auto *LHS = dyn_cast<TypedInit>(Result);
293106c3fb27SDimitry Andric       if (!LHS) {
293206c3fb27SDimitry Andric         Error(LHSLoc, "Invalid value, list expected");
29330b57cec5SDimitry Andric         return nullptr;
29340b57cec5SDimitry Andric       }
29350b57cec5SDimitry Andric 
293606c3fb27SDimitry Andric       auto *LHSTy = dyn_cast<ListRecTy>(LHS->getType());
293706c3fb27SDimitry Andric       if (!LHSTy) {
293806c3fb27SDimitry Andric         Error(LHSLoc, "Type '" + Twine(LHS->getType()->getAsString()) +
293906c3fb27SDimitry Andric                           "' is invalid, list expected");
294006c3fb27SDimitry Andric         return nullptr;
294106c3fb27SDimitry Andric       }
294206c3fb27SDimitry Andric 
294306c3fb27SDimitry Andric       Lex.Lex(); // eat the '['
294406c3fb27SDimitry Andric       TypedInit *RHS = ParseSliceElements(CurRec, /*Single=*/true);
294506c3fb27SDimitry Andric       if (!RHS)
294606c3fb27SDimitry Andric         return nullptr;
294706c3fb27SDimitry Andric 
294806c3fb27SDimitry Andric       if (isa<ListRecTy>(RHS->getType())) {
294906c3fb27SDimitry Andric         Result =
295006c3fb27SDimitry Andric             BinOpInit::get(BinOpInit::LISTSLICE, LHS, RHS, LHSTy)->Fold(CurRec);
295106c3fb27SDimitry Andric       } else {
295206c3fb27SDimitry Andric         Result = BinOpInit::get(BinOpInit::LISTELEM, LHS, RHS,
295306c3fb27SDimitry Andric                                 LHSTy->getElementType())
295406c3fb27SDimitry Andric                      ->Fold(CurRec);
295506c3fb27SDimitry Andric       }
295606c3fb27SDimitry Andric 
295706c3fb27SDimitry Andric       assert(Result);
295806c3fb27SDimitry Andric 
29590b57cec5SDimitry Andric       // Eat the ']'.
29605ffd83dbSDimitry Andric       if (!consume(tgtok::r_square)) {
29610b57cec5SDimitry Andric         TokError("expected ']' at end of list slice");
29620b57cec5SDimitry Andric         return nullptr;
29630b57cec5SDimitry Andric       }
29640b57cec5SDimitry Andric       break;
29650b57cec5SDimitry Andric     }
2966e8d8bef9SDimitry Andric     case tgtok::dot: {
29670b57cec5SDimitry Andric       if (Lex.Lex() != tgtok::Id) { // eat the .
29680b57cec5SDimitry Andric         TokError("expected field identifier after '.'");
29690b57cec5SDimitry Andric         return nullptr;
29700b57cec5SDimitry Andric       }
2971bdd1243dSDimitry Andric       SMRange FieldNameLoc = Lex.getLocRange();
297281ad6265SDimitry Andric       StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
29730b57cec5SDimitry Andric       if (!Result->getFieldType(FieldName)) {
29740b57cec5SDimitry Andric         TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
29750b57cec5SDimitry Andric                  Result->getAsString() + "'");
29760b57cec5SDimitry Andric         return nullptr;
29770b57cec5SDimitry Andric       }
2978bdd1243dSDimitry Andric 
2979bdd1243dSDimitry Andric       // Add a reference to this field if we know the record class.
2980bdd1243dSDimitry Andric       if (TrackReferenceLocs) {
2981bdd1243dSDimitry Andric         if (auto *DI = dyn_cast<DefInit>(Result)) {
2982bdd1243dSDimitry Andric           DI->getDef()->getValue(FieldName)->addReferenceLoc(FieldNameLoc);
2983bdd1243dSDimitry Andric         } else if (auto *TI = dyn_cast<TypedInit>(Result)) {
2984bdd1243dSDimitry Andric           if (auto *RecTy = dyn_cast<RecordRecTy>(TI->getType())) {
2985bdd1243dSDimitry Andric             for (Record *R : RecTy->getClasses())
2986bdd1243dSDimitry Andric               if (auto *RV = R->getValue(FieldName))
2987bdd1243dSDimitry Andric                 RV->addReferenceLoc(FieldNameLoc);
2988bdd1243dSDimitry Andric           }
2989bdd1243dSDimitry Andric         }
2990bdd1243dSDimitry Andric       }
2991bdd1243dSDimitry Andric 
29920b57cec5SDimitry Andric       Result = FieldInit::get(Result, FieldName)->Fold(CurRec);
29930b57cec5SDimitry Andric       Lex.Lex();  // eat field name
29940b57cec5SDimitry Andric       break;
29950b57cec5SDimitry Andric     }
29960b57cec5SDimitry Andric 
29970b57cec5SDimitry Andric     case tgtok::paste:
29980b57cec5SDimitry Andric       SMLoc PasteLoc = Lex.getLoc();
29990b57cec5SDimitry Andric       TypedInit *LHS = dyn_cast<TypedInit>(Result);
30000b57cec5SDimitry Andric       if (!LHS) {
30010b57cec5SDimitry Andric         Error(PasteLoc, "LHS of paste is not typed!");
30020b57cec5SDimitry Andric         return nullptr;
30030b57cec5SDimitry Andric       }
30040b57cec5SDimitry Andric 
30050b57cec5SDimitry Andric       // Check if it's a 'listA # listB'
30060b57cec5SDimitry Andric       if (isa<ListRecTy>(LHS->getType())) {
30070b57cec5SDimitry Andric         Lex.Lex();  // Eat the '#'.
30080b57cec5SDimitry Andric 
3009e8d8bef9SDimitry Andric         assert(Mode == ParseValueMode && "encountered paste of lists in name");
3010e8d8bef9SDimitry Andric 
30110b57cec5SDimitry Andric         switch (Lex.getCode()) {
30120b57cec5SDimitry Andric         case tgtok::colon:
30130b57cec5SDimitry Andric         case tgtok::semi:
30140b57cec5SDimitry Andric         case tgtok::l_brace:
30150b57cec5SDimitry Andric           Result = LHS; // trailing paste, ignore.
30160b57cec5SDimitry Andric           break;
30170b57cec5SDimitry Andric         default:
3018e8d8bef9SDimitry Andric           Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3019e8d8bef9SDimitry Andric           if (!RHSResult)
3020e8d8bef9SDimitry Andric             return nullptr;
30210b57cec5SDimitry Andric           Result = BinOpInit::getListConcat(LHS, RHSResult);
3022e8d8bef9SDimitry Andric           break;
30230b57cec5SDimitry Andric         }
30240b57cec5SDimitry Andric         break;
30250b57cec5SDimitry Andric       }
30260b57cec5SDimitry Andric 
30270b57cec5SDimitry Andric       // Create a !strconcat() operation, first casting each operand to
30280b57cec5SDimitry Andric       // a string if necessary.
302981ad6265SDimitry Andric       if (LHS->getType() != StringRecTy::get(Records)) {
30300b57cec5SDimitry Andric         auto CastLHS = dyn_cast<TypedInit>(
303181ad6265SDimitry Andric             UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get(Records))
30320b57cec5SDimitry Andric                 ->Fold(CurRec));
30330b57cec5SDimitry Andric         if (!CastLHS) {
30340b57cec5SDimitry Andric           Error(PasteLoc,
30350b57cec5SDimitry Andric                 Twine("can't cast '") + LHS->getAsString() + "' to string");
30360b57cec5SDimitry Andric           return nullptr;
30370b57cec5SDimitry Andric         }
30380b57cec5SDimitry Andric         LHS = CastLHS;
30390b57cec5SDimitry Andric       }
30400b57cec5SDimitry Andric 
30410b57cec5SDimitry Andric       TypedInit *RHS = nullptr;
30420b57cec5SDimitry Andric 
30430b57cec5SDimitry Andric       Lex.Lex();  // Eat the '#'.
30440b57cec5SDimitry Andric       switch (Lex.getCode()) {
30450b57cec5SDimitry Andric       case tgtok::colon:
30460b57cec5SDimitry Andric       case tgtok::semi:
30470b57cec5SDimitry Andric       case tgtok::l_brace:
30480b57cec5SDimitry Andric         // These are all of the tokens that can begin an object body.
30490b57cec5SDimitry Andric         // Some of these can also begin values but we disallow those cases
30500b57cec5SDimitry Andric         // because they are unlikely to be useful.
30510b57cec5SDimitry Andric 
30520b57cec5SDimitry Andric         // Trailing paste, concat with an empty string.
305381ad6265SDimitry Andric         RHS = StringInit::get(Records, "");
30540b57cec5SDimitry Andric         break;
30550b57cec5SDimitry Andric 
30560b57cec5SDimitry Andric       default:
30570b57cec5SDimitry Andric         Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
3058e8d8bef9SDimitry Andric         if (!RHSResult)
3059e8d8bef9SDimitry Andric           return nullptr;
30600b57cec5SDimitry Andric         RHS = dyn_cast<TypedInit>(RHSResult);
30610b57cec5SDimitry Andric         if (!RHS) {
30620b57cec5SDimitry Andric           Error(PasteLoc, "RHS of paste is not typed!");
30630b57cec5SDimitry Andric           return nullptr;
30640b57cec5SDimitry Andric         }
30650b57cec5SDimitry Andric 
306681ad6265SDimitry Andric         if (RHS->getType() != StringRecTy::get(Records)) {
30670b57cec5SDimitry Andric           auto CastRHS = dyn_cast<TypedInit>(
306881ad6265SDimitry Andric               UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get(Records))
30690b57cec5SDimitry Andric                   ->Fold(CurRec));
30700b57cec5SDimitry Andric           if (!CastRHS) {
30710b57cec5SDimitry Andric             Error(PasteLoc,
30720b57cec5SDimitry Andric                   Twine("can't cast '") + RHS->getAsString() + "' to string");
30730b57cec5SDimitry Andric             return nullptr;
30740b57cec5SDimitry Andric           }
30750b57cec5SDimitry Andric           RHS = CastRHS;
30760b57cec5SDimitry Andric         }
30770b57cec5SDimitry Andric 
30780b57cec5SDimitry Andric         break;
30790b57cec5SDimitry Andric       }
30800b57cec5SDimitry Andric 
30810b57cec5SDimitry Andric       Result = BinOpInit::getStrConcat(LHS, RHS);
30820b57cec5SDimitry Andric       break;
30830b57cec5SDimitry Andric     }
30840b57cec5SDimitry Andric   }
30850b57cec5SDimitry Andric }
30860b57cec5SDimitry Andric 
30870b57cec5SDimitry Andric /// ParseDagArgList - Parse the argument list for a dag literal expression.
30880b57cec5SDimitry Andric ///
30890b57cec5SDimitry Andric ///    DagArg     ::= Value (':' VARNAME)?
30900b57cec5SDimitry Andric ///    DagArg     ::= VARNAME
30910b57cec5SDimitry Andric ///    DagArgList ::= DagArg
30920b57cec5SDimitry Andric ///    DagArgList ::= DagArgList ',' DagArg
ParseDagArgList(SmallVectorImpl<std::pair<llvm::Init *,StringInit * >> & Result,Record * CurRec)30930b57cec5SDimitry Andric void TGParser::ParseDagArgList(
30940b57cec5SDimitry Andric     SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result,
30950b57cec5SDimitry Andric     Record *CurRec) {
30960b57cec5SDimitry Andric 
30970b57cec5SDimitry Andric   while (true) {
30980b57cec5SDimitry Andric     // DagArg ::= VARNAME
30990b57cec5SDimitry Andric     if (Lex.getCode() == tgtok::VarName) {
31000b57cec5SDimitry Andric       // A missing value is treated like '?'.
310181ad6265SDimitry Andric       StringInit *VarName = StringInit::get(Records, Lex.getCurStrVal());
310281ad6265SDimitry Andric       Result.emplace_back(UnsetInit::get(Records), VarName);
31030b57cec5SDimitry Andric       Lex.Lex();
31040b57cec5SDimitry Andric     } else {
31050b57cec5SDimitry Andric       // DagArg ::= Value (':' VARNAME)?
31060b57cec5SDimitry Andric       Init *Val = ParseValue(CurRec);
31070b57cec5SDimitry Andric       if (!Val) {
31080b57cec5SDimitry Andric         Result.clear();
31090b57cec5SDimitry Andric         return;
31100b57cec5SDimitry Andric       }
31110b57cec5SDimitry Andric 
31120b57cec5SDimitry Andric       // If the variable name is present, add it.
31130b57cec5SDimitry Andric       StringInit *VarName = nullptr;
31140b57cec5SDimitry Andric       if (Lex.getCode() == tgtok::colon) {
31150b57cec5SDimitry Andric         if (Lex.Lex() != tgtok::VarName) { // eat the ':'
31160b57cec5SDimitry Andric           TokError("expected variable name in dag literal");
31170b57cec5SDimitry Andric           Result.clear();
31180b57cec5SDimitry Andric           return;
31190b57cec5SDimitry Andric         }
312081ad6265SDimitry Andric         VarName = StringInit::get(Records, Lex.getCurStrVal());
31210b57cec5SDimitry Andric         Lex.Lex();  // eat the VarName.
31220b57cec5SDimitry Andric       }
31230b57cec5SDimitry Andric 
31240b57cec5SDimitry Andric       Result.push_back(std::make_pair(Val, VarName));
31250b57cec5SDimitry Andric     }
31265ffd83dbSDimitry Andric     if (!consume(tgtok::comma))
31275ffd83dbSDimitry Andric       break;
31280b57cec5SDimitry Andric   }
31290b57cec5SDimitry Andric }
31300b57cec5SDimitry Andric 
3131fe6060f1SDimitry Andric /// ParseValueList - Parse a comma separated list of values, returning them
3132fe6060f1SDimitry Andric /// in a vector. Note that this always expects to be able to parse at least one
31330b57cec5SDimitry Andric /// value. It returns an empty list if this is not possible.
31340b57cec5SDimitry Andric ///
31350b57cec5SDimitry Andric ///   ValueList ::= Value (',' Value)
31360b57cec5SDimitry Andric ///
ParseValueList(SmallVectorImpl<Init * > & Result,Record * CurRec,RecTy * ItemType)31370b57cec5SDimitry Andric void TGParser::ParseValueList(SmallVectorImpl<Init *> &Result, Record *CurRec,
3138fe6060f1SDimitry Andric                               RecTy *ItemType) {
3139fe6060f1SDimitry Andric 
31400b57cec5SDimitry Andric   Result.push_back(ParseValue(CurRec, ItemType));
31410b57cec5SDimitry Andric   if (!Result.back()) {
31420b57cec5SDimitry Andric     Result.clear();
31430b57cec5SDimitry Andric     return;
31440b57cec5SDimitry Andric   }
31450b57cec5SDimitry Andric 
31465ffd83dbSDimitry Andric   while (consume(tgtok::comma)) {
31470b57cec5SDimitry Andric     // ignore trailing comma for lists
31480b57cec5SDimitry Andric     if (Lex.getCode() == tgtok::r_square)
31490b57cec5SDimitry Andric       return;
31500b57cec5SDimitry Andric     Result.push_back(ParseValue(CurRec, ItemType));
31510b57cec5SDimitry Andric     if (!Result.back()) {
31520b57cec5SDimitry Andric       Result.clear();
31530b57cec5SDimitry Andric       return;
31540b57cec5SDimitry Andric     }
31550b57cec5SDimitry Andric   }
31560b57cec5SDimitry Andric }
31570b57cec5SDimitry Andric 
3158fe6060f1SDimitry Andric // ParseTemplateArgValueList - Parse a template argument list with the syntax
3159fe6060f1SDimitry Andric // shown, filling in the Result vector. The open angle has been consumed.
3160fe6060f1SDimitry Andric // An empty argument list is allowed. Return false if okay, true if an
3161fe6060f1SDimitry Andric // error was detected.
3162fe6060f1SDimitry Andric //
316306c3fb27SDimitry Andric //   ArgValueList ::= '<' PostionalArgValueList [','] NamedArgValueList '>'
316406c3fb27SDimitry Andric //   PostionalArgValueList ::= [Value {',' Value}*]
316506c3fb27SDimitry Andric //   NamedArgValueList ::= [NameValue '=' Value {',' NameValue '=' Value}*]
ParseTemplateArgValueList(SmallVectorImpl<ArgumentInit * > & Result,Record * CurRec,Record * ArgsRec)316606c3fb27SDimitry Andric bool TGParser::ParseTemplateArgValueList(
31675f757f3fSDimitry Andric     SmallVectorImpl<ArgumentInit *> &Result, Record *CurRec, Record *ArgsRec) {
3168fe6060f1SDimitry Andric   assert(Result.empty() && "Result vector is not empty");
3169fe6060f1SDimitry Andric   ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
3170fe6060f1SDimitry Andric 
3171fe6060f1SDimitry Andric   if (consume(tgtok::greater)) // empty value list
3172fe6060f1SDimitry Andric     return false;
3173fe6060f1SDimitry Andric 
317406c3fb27SDimitry Andric   bool HasNamedArg = false;
317506c3fb27SDimitry Andric   unsigned ArgIndex = 0;
3176fe6060f1SDimitry Andric   while (true) {
3177fe6060f1SDimitry Andric     if (ArgIndex >= TArgs.size()) {
3178fe6060f1SDimitry Andric       TokError("Too many template arguments: " + utostr(ArgIndex + 1));
3179fe6060f1SDimitry Andric       return true;
3180fe6060f1SDimitry Andric     }
3181fe6060f1SDimitry Andric 
318206c3fb27SDimitry Andric     SMLoc ValueLoc = Lex.getLoc();
318306c3fb27SDimitry Andric     // If we are parsing named argument, we don't need to know the argument name
318406c3fb27SDimitry Andric     // and argument type will be resolved after we know the name.
318506c3fb27SDimitry Andric     Init *Value = ParseValue(
318606c3fb27SDimitry Andric         CurRec,
318706c3fb27SDimitry Andric         HasNamedArg ? nullptr : ArgsRec->getValue(TArgs[ArgIndex])->getType());
3188fe6060f1SDimitry Andric     if (!Value)
3189fe6060f1SDimitry Andric       return true;
319006c3fb27SDimitry Andric 
319106c3fb27SDimitry Andric     // If we meet '=', then we are parsing named arguments.
319206c3fb27SDimitry Andric     if (Lex.getCode() == tgtok::equal) {
319306c3fb27SDimitry Andric       if (!isa<StringInit>(Value))
319406c3fb27SDimitry Andric         return Error(ValueLoc,
319506c3fb27SDimitry Andric                      "The name of named argument should be a valid identifier");
319606c3fb27SDimitry Andric 
319706c3fb27SDimitry Andric       auto *Name = cast<StringInit>(Value);
31985f757f3fSDimitry Andric       Init *QualifiedName = QualifyName(*ArgsRec, Name);
319906c3fb27SDimitry Andric       auto *NamedArg = ArgsRec->getValue(QualifiedName);
320006c3fb27SDimitry Andric       if (!NamedArg)
320106c3fb27SDimitry Andric         return Error(ValueLoc,
320206c3fb27SDimitry Andric                      "Argument " + Name->getAsString() + " doesn't exist");
320306c3fb27SDimitry Andric 
320406c3fb27SDimitry Andric       Lex.Lex(); // eat the '='.
320506c3fb27SDimitry Andric       ValueLoc = Lex.getLoc();
320606c3fb27SDimitry Andric       Value = ParseValue(CurRec, NamedArg->getType());
320706c3fb27SDimitry Andric       // Named value can't be uninitialized.
320806c3fb27SDimitry Andric       if (isa<UnsetInit>(Value))
320906c3fb27SDimitry Andric         return Error(ValueLoc,
321006c3fb27SDimitry Andric                      "The value of named argument should be initialized, "
321106c3fb27SDimitry Andric                      "but we got '" +
321206c3fb27SDimitry Andric                          Value->getAsString() + "'");
321306c3fb27SDimitry Andric 
321406c3fb27SDimitry Andric       Result.push_back(ArgumentInit::get(Value, QualifiedName));
321506c3fb27SDimitry Andric       HasNamedArg = true;
321606c3fb27SDimitry Andric     } else {
321706c3fb27SDimitry Andric       // Positional arguments should be put before named arguments.
321806c3fb27SDimitry Andric       if (HasNamedArg)
321906c3fb27SDimitry Andric         return Error(ValueLoc,
322006c3fb27SDimitry Andric                      "Positional argument should be put before named argument");
322106c3fb27SDimitry Andric 
322206c3fb27SDimitry Andric       Result.push_back(ArgumentInit::get(Value, ArgIndex));
322306c3fb27SDimitry Andric     }
3224fe6060f1SDimitry Andric 
3225fe6060f1SDimitry Andric     if (consume(tgtok::greater)) // end of argument list?
3226fe6060f1SDimitry Andric       return false;
3227fe6060f1SDimitry Andric     if (!consume(tgtok::comma))
3228fe6060f1SDimitry Andric       return TokError("Expected comma before next argument");
3229fe6060f1SDimitry Andric     ++ArgIndex;
3230fe6060f1SDimitry Andric   }
3231fe6060f1SDimitry Andric }
3232fe6060f1SDimitry Andric 
32330b57cec5SDimitry Andric /// ParseDeclaration - Read a declaration, returning the name of field ID, or an
3234fe6060f1SDimitry Andric /// empty string on error.  This can happen in a number of different contexts,
3235fe6060f1SDimitry Andric /// including within a def or in the template args for a class (in which case
32360b57cec5SDimitry Andric /// CurRec will be non-null) and within the template args for a multiclass (in
32370b57cec5SDimitry Andric /// which case CurRec will be null, but CurMultiClass will be set).  This can
32380b57cec5SDimitry Andric /// also happen within a def that is within a multiclass, which will set both
32390b57cec5SDimitry Andric /// CurRec and CurMultiClass.
32400b57cec5SDimitry Andric ///
32410b57cec5SDimitry Andric ///  Declaration ::= FIELD? Type ID ('=' Value)?
32420b57cec5SDimitry Andric ///
ParseDeclaration(Record * CurRec,bool ParsingTemplateArgs)32430b57cec5SDimitry Andric Init *TGParser::ParseDeclaration(Record *CurRec,
32440b57cec5SDimitry Andric                                        bool ParsingTemplateArgs) {
32450b57cec5SDimitry Andric   // Read the field prefix if present.
32465ffd83dbSDimitry Andric   bool HasField = consume(tgtok::Field);
32470b57cec5SDimitry Andric 
32480b57cec5SDimitry Andric   RecTy *Type = ParseType();
32490b57cec5SDimitry Andric   if (!Type) return nullptr;
32500b57cec5SDimitry Andric 
32510b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Id) {
32520b57cec5SDimitry Andric     TokError("Expected identifier in declaration");
32530b57cec5SDimitry Andric     return nullptr;
32540b57cec5SDimitry Andric   }
32550b57cec5SDimitry Andric 
32560b57cec5SDimitry Andric   std::string Str = Lex.getCurStrVal();
32570b57cec5SDimitry Andric   if (Str == "NAME") {
32580b57cec5SDimitry Andric     TokError("'" + Str + "' is a reserved variable name");
32590b57cec5SDimitry Andric     return nullptr;
32600b57cec5SDimitry Andric   }
32610b57cec5SDimitry Andric 
326206c3fb27SDimitry Andric   if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {
326306c3fb27SDimitry Andric     TokError("local variable of this name already exists");
326406c3fb27SDimitry Andric     return nullptr;
326506c3fb27SDimitry Andric   }
326606c3fb27SDimitry Andric 
32670b57cec5SDimitry Andric   SMLoc IdLoc = Lex.getLoc();
326881ad6265SDimitry Andric   Init *DeclName = StringInit::get(Records, Str);
32690b57cec5SDimitry Andric   Lex.Lex();
32700b57cec5SDimitry Andric 
3271fe6060f1SDimitry Andric   bool BadField;
3272fe6060f1SDimitry Andric   if (!ParsingTemplateArgs) { // def, possibly in a multiclass
3273fe6060f1SDimitry Andric     BadField = AddValue(CurRec, IdLoc,
3274fe6060f1SDimitry Andric                         RecordVal(DeclName, IdLoc, Type,
3275e8d8bef9SDimitry Andric                                   HasField ? RecordVal::FK_NonconcreteOK
3276fe6060f1SDimitry Andric                                            : RecordVal::FK_Normal));
3277fe6060f1SDimitry Andric   } else if (CurRec) { // class template argument
32785f757f3fSDimitry Andric     DeclName = QualifyName(*CurRec, DeclName);
32795f757f3fSDimitry Andric     BadField =
32805f757f3fSDimitry Andric         AddValue(CurRec, IdLoc,
32815f757f3fSDimitry Andric                  RecordVal(DeclName, IdLoc, Type, RecordVal::FK_TemplateArg));
3282fe6060f1SDimitry Andric   } else { // multiclass template argument
3283fe6060f1SDimitry Andric     assert(CurMultiClass && "invalid context for template argument");
32845f757f3fSDimitry Andric     DeclName = QualifyName(CurMultiClass, DeclName);
32855f757f3fSDimitry Andric     BadField =
32865f757f3fSDimitry Andric         AddValue(CurRec, IdLoc,
32875f757f3fSDimitry Andric                  RecordVal(DeclName, IdLoc, Type, RecordVal::FK_TemplateArg));
3288fe6060f1SDimitry Andric   }
3289fe6060f1SDimitry Andric   if (BadField)
32900b57cec5SDimitry Andric     return nullptr;
32910b57cec5SDimitry Andric 
3292fe6060f1SDimitry Andric   // If a value is present, parse it and set new field's value.
32935ffd83dbSDimitry Andric   if (consume(tgtok::equal)) {
32940b57cec5SDimitry Andric     SMLoc ValLoc = Lex.getLoc();
32950b57cec5SDimitry Andric     Init *Val = ParseValue(CurRec, Type);
32960b57cec5SDimitry Andric     if (!Val ||
3297bdd1243dSDimitry Andric         SetValue(CurRec, ValLoc, DeclName, std::nullopt, Val,
3298bdd1243dSDimitry Andric                  /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/false)) {
32990b57cec5SDimitry Andric       // Return the name, even if an error is thrown.  This is so that we can
33000b57cec5SDimitry Andric       // continue to make some progress, even without the value having been
33010b57cec5SDimitry Andric       // initialized.
33020b57cec5SDimitry Andric       return DeclName;
33030b57cec5SDimitry Andric     }
3304bdd1243dSDimitry Andric   }
33050b57cec5SDimitry Andric 
33060b57cec5SDimitry Andric   return DeclName;
33070b57cec5SDimitry Andric }
33080b57cec5SDimitry Andric 
33090b57cec5SDimitry Andric /// ParseForeachDeclaration - Read a foreach declaration, returning
33100b57cec5SDimitry Andric /// the name of the declared object or a NULL Init on error.  Return
33110b57cec5SDimitry Andric /// the name of the parsed initializer list through ForeachListName.
33120b57cec5SDimitry Andric ///
33130b57cec5SDimitry Andric ///  ForeachDeclaration ::= ID '=' '{' RangeList '}'
33140b57cec5SDimitry Andric ///  ForeachDeclaration ::= ID '=' RangePiece
33150b57cec5SDimitry Andric ///  ForeachDeclaration ::= ID '=' Value
33160b57cec5SDimitry Andric ///
ParseForeachDeclaration(Init * & ForeachListValue)33170b57cec5SDimitry Andric VarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) {
33180b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Id) {
33190b57cec5SDimitry Andric     TokError("Expected identifier in foreach declaration");
33200b57cec5SDimitry Andric     return nullptr;
33210b57cec5SDimitry Andric   }
33220b57cec5SDimitry Andric 
332381ad6265SDimitry Andric   Init *DeclName = StringInit::get(Records, Lex.getCurStrVal());
33240b57cec5SDimitry Andric   Lex.Lex();
33250b57cec5SDimitry Andric 
33260b57cec5SDimitry Andric   // If a value is present, parse it.
33275ffd83dbSDimitry Andric   if (!consume(tgtok::equal)) {
33280b57cec5SDimitry Andric     TokError("Expected '=' in foreach declaration");
33290b57cec5SDimitry Andric     return nullptr;
33300b57cec5SDimitry Andric   }
33310b57cec5SDimitry Andric 
33320b57cec5SDimitry Andric   RecTy *IterType = nullptr;
33330b57cec5SDimitry Andric   SmallVector<unsigned, 16> Ranges;
33340b57cec5SDimitry Andric 
33350b57cec5SDimitry Andric   switch (Lex.getCode()) {
33360b57cec5SDimitry Andric   case tgtok::l_brace: { // '{' RangeList '}'
33370b57cec5SDimitry Andric     Lex.Lex(); // eat the '{'
33380b57cec5SDimitry Andric     ParseRangeList(Ranges);
33395ffd83dbSDimitry Andric     if (!consume(tgtok::r_brace)) {
33400b57cec5SDimitry Andric       TokError("expected '}' at end of bit range list");
33410b57cec5SDimitry Andric       return nullptr;
33420b57cec5SDimitry Andric     }
33430b57cec5SDimitry Andric     break;
33440b57cec5SDimitry Andric   }
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric   default: {
33470b57cec5SDimitry Andric     SMLoc ValueLoc = Lex.getLoc();
33480b57cec5SDimitry Andric     Init *I = ParseValue(nullptr);
33490b57cec5SDimitry Andric     if (!I)
33500b57cec5SDimitry Andric       return nullptr;
33510b57cec5SDimitry Andric 
33520b57cec5SDimitry Andric     TypedInit *TI = dyn_cast<TypedInit>(I);
33530b57cec5SDimitry Andric     if (TI && isa<ListRecTy>(TI->getType())) {
33540b57cec5SDimitry Andric       ForeachListValue = I;
33550b57cec5SDimitry Andric       IterType = cast<ListRecTy>(TI->getType())->getElementType();
33560b57cec5SDimitry Andric       break;
33570b57cec5SDimitry Andric     }
33580b57cec5SDimitry Andric 
33590b57cec5SDimitry Andric     if (TI) {
33600b57cec5SDimitry Andric       if (ParseRangePiece(Ranges, TI))
33610b57cec5SDimitry Andric         return nullptr;
33620b57cec5SDimitry Andric       break;
33630b57cec5SDimitry Andric     }
33640b57cec5SDimitry Andric 
3365fe6060f1SDimitry Andric     Error(ValueLoc, "expected a list, got '" + I->getAsString() + "'");
33660b57cec5SDimitry Andric     if (CurMultiClass) {
33670b57cec5SDimitry Andric       PrintNote({}, "references to multiclass template arguments cannot be "
33680b57cec5SDimitry Andric                 "resolved at this time");
33690b57cec5SDimitry Andric     }
33700b57cec5SDimitry Andric     return nullptr;
33710b57cec5SDimitry Andric   }
33720b57cec5SDimitry Andric   }
33730b57cec5SDimitry Andric 
33740b57cec5SDimitry Andric 
33750b57cec5SDimitry Andric   if (!Ranges.empty()) {
33760b57cec5SDimitry Andric     assert(!IterType && "Type already initialized?");
337781ad6265SDimitry Andric     IterType = IntRecTy::get(Records);
33780b57cec5SDimitry Andric     std::vector<Init *> Values;
33790b57cec5SDimitry Andric     for (unsigned R : Ranges)
338081ad6265SDimitry Andric       Values.push_back(IntInit::get(Records, R));
33810b57cec5SDimitry Andric     ForeachListValue = ListInit::get(Values, IterType);
33820b57cec5SDimitry Andric   }
33830b57cec5SDimitry Andric 
33840b57cec5SDimitry Andric   if (!IterType)
33850b57cec5SDimitry Andric     return nullptr;
33860b57cec5SDimitry Andric 
33870b57cec5SDimitry Andric   return VarInit::get(DeclName, IterType);
33880b57cec5SDimitry Andric }
33890b57cec5SDimitry Andric 
33900b57cec5SDimitry Andric /// ParseTemplateArgList - Read a template argument list, which is a non-empty
33910b57cec5SDimitry Andric /// sequence of template-declarations in <>'s.  If CurRec is non-null, these are
3392fe6060f1SDimitry Andric /// template args for a class. If null, these are the template args for a
3393fe6060f1SDimitry Andric /// multiclass.
33940b57cec5SDimitry Andric ///
33950b57cec5SDimitry Andric ///    TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
33960b57cec5SDimitry Andric ///
ParseTemplateArgList(Record * CurRec)33970b57cec5SDimitry Andric bool TGParser::ParseTemplateArgList(Record *CurRec) {
33980b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
33990b57cec5SDimitry Andric   Lex.Lex(); // eat the '<'
34000b57cec5SDimitry Andric 
34010b57cec5SDimitry Andric   Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
34020b57cec5SDimitry Andric 
34030b57cec5SDimitry Andric   // Read the first declaration.
34040b57cec5SDimitry Andric   Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
34050b57cec5SDimitry Andric   if (!TemplArg)
34060b57cec5SDimitry Andric     return true;
34070b57cec5SDimitry Andric 
34080b57cec5SDimitry Andric   TheRecToAddTo->addTemplateArg(TemplArg);
34090b57cec5SDimitry Andric 
34105ffd83dbSDimitry Andric   while (consume(tgtok::comma)) {
34110b57cec5SDimitry Andric     // Read the following declarations.
34120b57cec5SDimitry Andric     SMLoc Loc = Lex.getLoc();
34130b57cec5SDimitry Andric     TemplArg = ParseDeclaration(CurRec, true/*templateargs*/);
34140b57cec5SDimitry Andric     if (!TemplArg)
34150b57cec5SDimitry Andric       return true;
34160b57cec5SDimitry Andric 
34170b57cec5SDimitry Andric     if (TheRecToAddTo->isTemplateArg(TemplArg))
34180b57cec5SDimitry Andric       return Error(Loc, "template argument with the same name has already been "
34190b57cec5SDimitry Andric                         "defined");
34200b57cec5SDimitry Andric 
34210b57cec5SDimitry Andric     TheRecToAddTo->addTemplateArg(TemplArg);
34220b57cec5SDimitry Andric   }
34230b57cec5SDimitry Andric 
34245ffd83dbSDimitry Andric   if (!consume(tgtok::greater))
34250b57cec5SDimitry Andric     return TokError("expected '>' at end of template argument list");
34260b57cec5SDimitry Andric   return false;
34270b57cec5SDimitry Andric }
34280b57cec5SDimitry Andric 
3429e8d8bef9SDimitry Andric /// ParseBodyItem - Parse a single item within the body of a def or class.
34300b57cec5SDimitry Andric ///
34310b57cec5SDimitry Andric ///   BodyItem ::= Declaration ';'
34320b57cec5SDimitry Andric ///   BodyItem ::= LET ID OptionalBitList '=' Value ';'
3433480093f4SDimitry Andric ///   BodyItem ::= Defvar
34345f757f3fSDimitry Andric ///   BodyItem ::= Dump
3435e8d8bef9SDimitry Andric ///   BodyItem ::= Assert
3436fe6060f1SDimitry Andric ///
ParseBodyItem(Record * CurRec)34370b57cec5SDimitry Andric bool TGParser::ParseBodyItem(Record *CurRec) {
3438e8d8bef9SDimitry Andric   if (Lex.getCode() == tgtok::Assert)
3439e8d8bef9SDimitry Andric     return ParseAssert(nullptr, CurRec);
3440e8d8bef9SDimitry Andric 
3441480093f4SDimitry Andric   if (Lex.getCode() == tgtok::Defvar)
344206c3fb27SDimitry Andric     return ParseDefvar(CurRec);
3443480093f4SDimitry Andric 
34445f757f3fSDimitry Andric   if (Lex.getCode() == tgtok::Dump)
34455f757f3fSDimitry Andric     return ParseDump(nullptr, CurRec);
34465f757f3fSDimitry Andric 
34470b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Let) {
34480b57cec5SDimitry Andric     if (!ParseDeclaration(CurRec, false))
34490b57cec5SDimitry Andric       return true;
34500b57cec5SDimitry Andric 
34515ffd83dbSDimitry Andric     if (!consume(tgtok::semi))
34520b57cec5SDimitry Andric       return TokError("expected ';' after declaration");
34530b57cec5SDimitry Andric     return false;
34540b57cec5SDimitry Andric   }
34550b57cec5SDimitry Andric 
34560b57cec5SDimitry Andric   // LET ID OptionalRangeList '=' Value ';'
34570b57cec5SDimitry Andric   if (Lex.Lex() != tgtok::Id)
34580b57cec5SDimitry Andric     return TokError("expected field identifier after let");
34590b57cec5SDimitry Andric 
34600b57cec5SDimitry Andric   SMLoc IdLoc = Lex.getLoc();
346181ad6265SDimitry Andric   StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
34620b57cec5SDimitry Andric   Lex.Lex();  // eat the field name.
34630b57cec5SDimitry Andric 
34640b57cec5SDimitry Andric   SmallVector<unsigned, 16> BitList;
34650b57cec5SDimitry Andric   if (ParseOptionalBitList(BitList))
34660b57cec5SDimitry Andric     return true;
34670b57cec5SDimitry Andric   std::reverse(BitList.begin(), BitList.end());
34680b57cec5SDimitry Andric 
34695ffd83dbSDimitry Andric   if (!consume(tgtok::equal))
34700b57cec5SDimitry Andric     return TokError("expected '=' in let expression");
34710b57cec5SDimitry Andric 
34720b57cec5SDimitry Andric   RecordVal *Field = CurRec->getValue(FieldName);
34730b57cec5SDimitry Andric   if (!Field)
34740b57cec5SDimitry Andric     return TokError("Value '" + FieldName->getValue() + "' unknown!");
34750b57cec5SDimitry Andric 
34760b57cec5SDimitry Andric   RecTy *Type = Field->getType();
34775ffd83dbSDimitry Andric   if (!BitList.empty() && isa<BitsRecTy>(Type)) {
34785ffd83dbSDimitry Andric     // When assigning to a subset of a 'bits' object, expect the RHS to have
34795ffd83dbSDimitry Andric     // the type of that subset instead of the type of the whole object.
348081ad6265SDimitry Andric     Type = BitsRecTy::get(Records, BitList.size());
34815ffd83dbSDimitry Andric   }
34820b57cec5SDimitry Andric 
34830b57cec5SDimitry Andric   Init *Val = ParseValue(CurRec, Type);
34840b57cec5SDimitry Andric   if (!Val) return true;
34850b57cec5SDimitry Andric 
34865ffd83dbSDimitry Andric   if (!consume(tgtok::semi))
34870b57cec5SDimitry Andric     return TokError("expected ';' after let expression");
34880b57cec5SDimitry Andric 
34890b57cec5SDimitry Andric   return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
34900b57cec5SDimitry Andric }
34910b57cec5SDimitry Andric 
34920b57cec5SDimitry Andric /// ParseBody - Read the body of a class or def.  Return true on error, false on
34930b57cec5SDimitry Andric /// success.
34940b57cec5SDimitry Andric ///
34950b57cec5SDimitry Andric ///   Body     ::= ';'
34960b57cec5SDimitry Andric ///   Body     ::= '{' BodyList '}'
34970b57cec5SDimitry Andric ///   BodyList BodyItem*
34980b57cec5SDimitry Andric ///
ParseBody(Record * CurRec)34990b57cec5SDimitry Andric bool TGParser::ParseBody(Record *CurRec) {
35000b57cec5SDimitry Andric   // If this is a null definition, just eat the semi and return.
35015ffd83dbSDimitry Andric   if (consume(tgtok::semi))
35020b57cec5SDimitry Andric     return false;
35030b57cec5SDimitry Andric 
35045ffd83dbSDimitry Andric   if (!consume(tgtok::l_brace))
3505e8d8bef9SDimitry Andric     return TokError("Expected '{' to start body or ';' for declaration only");
35060b57cec5SDimitry Andric 
35070b57cec5SDimitry Andric   while (Lex.getCode() != tgtok::r_brace)
35080b57cec5SDimitry Andric     if (ParseBodyItem(CurRec))
35090b57cec5SDimitry Andric       return true;
35100b57cec5SDimitry Andric 
35110b57cec5SDimitry Andric   // Eat the '}'.
35120b57cec5SDimitry Andric   Lex.Lex();
3513e8d8bef9SDimitry Andric 
3514e8d8bef9SDimitry Andric   // If we have a semicolon, print a gentle error.
3515e8d8bef9SDimitry Andric   SMLoc SemiLoc = Lex.getLoc();
3516e8d8bef9SDimitry Andric   if (consume(tgtok::semi)) {
3517e8d8bef9SDimitry Andric     PrintError(SemiLoc, "A class or def body should not end with a semicolon");
3518e8d8bef9SDimitry Andric     PrintNote("Semicolon ignored; remove to eliminate this error");
3519e8d8bef9SDimitry Andric   }
3520e8d8bef9SDimitry Andric 
35210b57cec5SDimitry Andric   return false;
35220b57cec5SDimitry Andric }
35230b57cec5SDimitry Andric 
35240b57cec5SDimitry Andric /// Apply the current let bindings to \a CurRec.
35250b57cec5SDimitry Andric /// \returns true on error, false otherwise.
ApplyLetStack(Record * CurRec)35260b57cec5SDimitry Andric bool TGParser::ApplyLetStack(Record *CurRec) {
35270b57cec5SDimitry Andric   for (SmallVectorImpl<LetRecord> &LetInfo : LetStack)
35280b57cec5SDimitry Andric     for (LetRecord &LR : LetInfo)
35290b57cec5SDimitry Andric       if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
35300b57cec5SDimitry Andric         return true;
35310b57cec5SDimitry Andric   return false;
35320b57cec5SDimitry Andric }
35330b57cec5SDimitry Andric 
3534fe6060f1SDimitry Andric /// Apply the current let bindings to the RecordsEntry.
ApplyLetStack(RecordsEntry & Entry)35350b57cec5SDimitry Andric bool TGParser::ApplyLetStack(RecordsEntry &Entry) {
35360b57cec5SDimitry Andric   if (Entry.Rec)
35370b57cec5SDimitry Andric     return ApplyLetStack(Entry.Rec.get());
35380b57cec5SDimitry Andric 
3539fe6060f1SDimitry Andric   // Let bindings are not applied to assertions.
3540fe6060f1SDimitry Andric   if (Entry.Assertion)
3541fe6060f1SDimitry Andric     return false;
3542fe6060f1SDimitry Andric 
35435f757f3fSDimitry Andric   // Let bindings are not applied to dumps.
35445f757f3fSDimitry Andric   if (Entry.Dump)
35455f757f3fSDimitry Andric     return false;
35465f757f3fSDimitry Andric 
35470b57cec5SDimitry Andric   for (auto &E : Entry.Loop->Entries) {
35480b57cec5SDimitry Andric     if (ApplyLetStack(E))
35490b57cec5SDimitry Andric       return true;
35500b57cec5SDimitry Andric   }
35510b57cec5SDimitry Andric 
35520b57cec5SDimitry Andric   return false;
35530b57cec5SDimitry Andric }
35540b57cec5SDimitry Andric 
35550b57cec5SDimitry Andric /// ParseObjectBody - Parse the body of a def or class.  This consists of an
35560b57cec5SDimitry Andric /// optional ClassList followed by a Body.  CurRec is the current def or class
35570b57cec5SDimitry Andric /// that is being parsed.
35580b57cec5SDimitry Andric ///
35590b57cec5SDimitry Andric ///   ObjectBody      ::= BaseClassList Body
35600b57cec5SDimitry Andric ///   BaseClassList   ::= /*empty*/
35610b57cec5SDimitry Andric ///   BaseClassList   ::= ':' BaseClassListNE
35620b57cec5SDimitry Andric ///   BaseClassListNE ::= SubClassRef (',' SubClassRef)*
35630b57cec5SDimitry Andric ///
ParseObjectBody(Record * CurRec)35640b57cec5SDimitry Andric bool TGParser::ParseObjectBody(Record *CurRec) {
356506c3fb27SDimitry Andric   // An object body introduces a new scope for local variables.
356606c3fb27SDimitry Andric   TGVarScope *ObjectScope = PushScope(CurRec);
35670b57cec5SDimitry Andric   // If there is a baseclass list, read it.
35685ffd83dbSDimitry Andric   if (consume(tgtok::colon)) {
35690b57cec5SDimitry Andric 
35700b57cec5SDimitry Andric     // Read all of the subclasses.
35710b57cec5SDimitry Andric     SubClassReference SubClass = ParseSubClassReference(CurRec, false);
35720b57cec5SDimitry Andric     while (true) {
35730b57cec5SDimitry Andric       // Check for error.
35740b57cec5SDimitry Andric       if (!SubClass.Rec) return true;
35750b57cec5SDimitry Andric 
35760b57cec5SDimitry Andric       // Add it.
35770b57cec5SDimitry Andric       if (AddSubClass(CurRec, SubClass))
35780b57cec5SDimitry Andric         return true;
35790b57cec5SDimitry Andric 
35805ffd83dbSDimitry Andric       if (!consume(tgtok::comma))
35815ffd83dbSDimitry Andric         break;
35820b57cec5SDimitry Andric       SubClass = ParseSubClassReference(CurRec, false);
35830b57cec5SDimitry Andric     }
35840b57cec5SDimitry Andric   }
35850b57cec5SDimitry Andric 
35860b57cec5SDimitry Andric   if (ApplyLetStack(CurRec))
35870b57cec5SDimitry Andric     return true;
35880b57cec5SDimitry Andric 
358906c3fb27SDimitry Andric   bool Result = ParseBody(CurRec);
359006c3fb27SDimitry Andric   PopScope(ObjectScope);
359106c3fb27SDimitry Andric   return Result;
35920b57cec5SDimitry Andric }
35930b57cec5SDimitry Andric 
3594fe6060f1SDimitry Andric /// ParseDef - Parse and return a top level or multiclass record definition.
3595fe6060f1SDimitry Andric /// Return false if okay, true if error.
35960b57cec5SDimitry Andric ///
35970b57cec5SDimitry Andric ///   DefInst ::= DEF ObjectName ObjectBody
35980b57cec5SDimitry Andric ///
ParseDef(MultiClass * CurMultiClass)35990b57cec5SDimitry Andric bool TGParser::ParseDef(MultiClass *CurMultiClass) {
36000b57cec5SDimitry Andric   SMLoc DefLoc = Lex.getLoc();
36010b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::Def && "Unknown tok");
36020b57cec5SDimitry Andric   Lex.Lex();  // Eat the 'def' token.
36030b57cec5SDimitry Andric 
3604bdd1243dSDimitry Andric   // If the name of the def is an Id token, use that for the location.
3605bdd1243dSDimitry Andric   // Otherwise, the name is more complex and we use the location of the 'def'
3606bdd1243dSDimitry Andric   // token.
3607bdd1243dSDimitry Andric   SMLoc NameLoc = Lex.getCode() == tgtok::Id ? Lex.getLoc() : DefLoc;
3608bdd1243dSDimitry Andric 
36090b57cec5SDimitry Andric   // Parse ObjectName and make a record for it.
36100b57cec5SDimitry Andric   std::unique_ptr<Record> CurRec;
36110b57cec5SDimitry Andric   Init *Name = ParseObjectName(CurMultiClass);
36120b57cec5SDimitry Andric   if (!Name)
36130b57cec5SDimitry Andric     return true;
36140b57cec5SDimitry Andric 
3615bdd1243dSDimitry Andric   if (isa<UnsetInit>(Name)) {
36165f757f3fSDimitry Andric     CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc,
36175f757f3fSDimitry Andric                                       Records, Record::RK_AnonymousDef);
3618bdd1243dSDimitry Andric   } else {
3619bdd1243dSDimitry Andric     CurRec = std::make_unique<Record>(Name, NameLoc, Records);
3620bdd1243dSDimitry Andric   }
36210b57cec5SDimitry Andric 
36220b57cec5SDimitry Andric   if (ParseObjectBody(CurRec.get()))
36230b57cec5SDimitry Andric     return true;
36240b57cec5SDimitry Andric 
36250b57cec5SDimitry Andric   return addEntry(std::move(CurRec));
36260b57cec5SDimitry Andric }
36270b57cec5SDimitry Andric 
36280b57cec5SDimitry Andric /// ParseDefset - Parse a defset statement.
36290b57cec5SDimitry Andric ///
36300b57cec5SDimitry Andric ///   Defset ::= DEFSET Type Id '=' '{' ObjectList '}'
36310b57cec5SDimitry Andric ///
ParseDefset()36320b57cec5SDimitry Andric bool TGParser::ParseDefset() {
36330b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::Defset);
36340b57cec5SDimitry Andric   Lex.Lex(); // Eat the 'defset' token
36350b57cec5SDimitry Andric 
36360b57cec5SDimitry Andric   DefsetRecord Defset;
36370b57cec5SDimitry Andric   Defset.Loc = Lex.getLoc();
36380b57cec5SDimitry Andric   RecTy *Type = ParseType();
36390b57cec5SDimitry Andric   if (!Type)
36400b57cec5SDimitry Andric     return true;
36410b57cec5SDimitry Andric   if (!isa<ListRecTy>(Type))
36420b57cec5SDimitry Andric     return Error(Defset.Loc, "expected list type");
36430b57cec5SDimitry Andric   Defset.EltTy = cast<ListRecTy>(Type)->getElementType();
36440b57cec5SDimitry Andric 
36450b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Id)
36460b57cec5SDimitry Andric     return TokError("expected identifier");
364781ad6265SDimitry Andric   StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
36480b57cec5SDimitry Andric   if (Records.getGlobal(DeclName->getValue()))
36490b57cec5SDimitry Andric     return TokError("def or global variable of this name already exists");
36500b57cec5SDimitry Andric 
36510b57cec5SDimitry Andric   if (Lex.Lex() != tgtok::equal) // Eat the identifier
36520b57cec5SDimitry Andric     return TokError("expected '='");
36530b57cec5SDimitry Andric   if (Lex.Lex() != tgtok::l_brace) // Eat the '='
36540b57cec5SDimitry Andric     return TokError("expected '{'");
36550b57cec5SDimitry Andric   SMLoc BraceLoc = Lex.getLoc();
36560b57cec5SDimitry Andric   Lex.Lex(); // Eat the '{'
36570b57cec5SDimitry Andric 
36580b57cec5SDimitry Andric   Defsets.push_back(&Defset);
36590b57cec5SDimitry Andric   bool Err = ParseObjectList(nullptr);
36600b57cec5SDimitry Andric   Defsets.pop_back();
36610b57cec5SDimitry Andric   if (Err)
36620b57cec5SDimitry Andric     return true;
36630b57cec5SDimitry Andric 
36645ffd83dbSDimitry Andric   if (!consume(tgtok::r_brace)) {
36650b57cec5SDimitry Andric     TokError("expected '}' at end of defset");
36660b57cec5SDimitry Andric     return Error(BraceLoc, "to match this '{'");
36670b57cec5SDimitry Andric   }
36680b57cec5SDimitry Andric 
36690b57cec5SDimitry Andric   Records.addExtraGlobal(DeclName->getValue(),
36700b57cec5SDimitry Andric                          ListInit::get(Defset.Elements, Defset.EltTy));
36710b57cec5SDimitry Andric   return false;
36720b57cec5SDimitry Andric }
36730b57cec5SDimitry Andric 
3674*0fca6ea1SDimitry Andric /// ParseDeftype - Parse a defvar statement.
3675*0fca6ea1SDimitry Andric ///
3676*0fca6ea1SDimitry Andric ///   Deftype ::= DEFTYPE Id '=' Type ';'
3677*0fca6ea1SDimitry Andric ///
ParseDeftype()3678*0fca6ea1SDimitry Andric bool TGParser::ParseDeftype() {
3679*0fca6ea1SDimitry Andric   assert(Lex.getCode() == tgtok::Deftype);
3680*0fca6ea1SDimitry Andric   Lex.Lex(); // Eat the 'deftype' token
3681*0fca6ea1SDimitry Andric 
3682*0fca6ea1SDimitry Andric   if (Lex.getCode() != tgtok::Id)
3683*0fca6ea1SDimitry Andric     return TokError("expected identifier");
3684*0fca6ea1SDimitry Andric 
3685*0fca6ea1SDimitry Andric   const std::string TypeName = Lex.getCurStrVal();
3686*0fca6ea1SDimitry Andric   if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
3687*0fca6ea1SDimitry Andric     return TokError("type of this name '" + TypeName + "' already exists");
3688*0fca6ea1SDimitry Andric 
3689*0fca6ea1SDimitry Andric   Lex.Lex();
3690*0fca6ea1SDimitry Andric   if (!consume(tgtok::equal))
3691*0fca6ea1SDimitry Andric     return TokError("expected '='");
3692*0fca6ea1SDimitry Andric 
3693*0fca6ea1SDimitry Andric   SMLoc Loc = Lex.getLoc();
3694*0fca6ea1SDimitry Andric   RecTy *Type = ParseType();
3695*0fca6ea1SDimitry Andric   if (!Type)
3696*0fca6ea1SDimitry Andric     return true;
3697*0fca6ea1SDimitry Andric 
3698*0fca6ea1SDimitry Andric   if (Type->getRecTyKind() == RecTy::RecordRecTyKind)
3699*0fca6ea1SDimitry Andric     return Error(Loc, "cannot define type alias for class type '" +
3700*0fca6ea1SDimitry Andric                           Type->getAsString() + "'");
3701*0fca6ea1SDimitry Andric 
3702*0fca6ea1SDimitry Andric   TypeAliases[TypeName] = Type;
3703*0fca6ea1SDimitry Andric 
3704*0fca6ea1SDimitry Andric   if (!consume(tgtok::semi))
3705*0fca6ea1SDimitry Andric     return TokError("expected ';'");
3706*0fca6ea1SDimitry Andric 
3707*0fca6ea1SDimitry Andric   return false;
3708*0fca6ea1SDimitry Andric }
3709*0fca6ea1SDimitry Andric 
3710480093f4SDimitry Andric /// ParseDefvar - Parse a defvar statement.
3711480093f4SDimitry Andric ///
3712480093f4SDimitry Andric ///   Defvar ::= DEFVAR Id '=' Value ';'
3713480093f4SDimitry Andric ///
ParseDefvar(Record * CurRec)371406c3fb27SDimitry Andric bool TGParser::ParseDefvar(Record *CurRec) {
3715480093f4SDimitry Andric   assert(Lex.getCode() == tgtok::Defvar);
3716480093f4SDimitry Andric   Lex.Lex(); // Eat the 'defvar' token
3717480093f4SDimitry Andric 
3718480093f4SDimitry Andric   if (Lex.getCode() != tgtok::Id)
3719480093f4SDimitry Andric     return TokError("expected identifier");
372081ad6265SDimitry Andric   StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
372106c3fb27SDimitry Andric   if (CurScope->varAlreadyDefined(DeclName->getValue()))
3722480093f4SDimitry Andric     return TokError("local variable of this name already exists");
372306c3fb27SDimitry Andric 
372406c3fb27SDimitry Andric   // The name should not be conflicted with existed field names.
372506c3fb27SDimitry Andric   if (CurRec) {
372606c3fb27SDimitry Andric     auto *V = CurRec->getValue(DeclName->getValue());
372706c3fb27SDimitry Andric     if (V && !V->isTemplateArg())
372806c3fb27SDimitry Andric       return TokError("field of this name already exists");
3729480093f4SDimitry Andric   }
3730480093f4SDimitry Andric 
373106c3fb27SDimitry Andric   // If this defvar is in the top level, the name should not be conflicted
373206c3fb27SDimitry Andric   // with existed global names.
373306c3fb27SDimitry Andric   if (CurScope->isOutermost() && Records.getGlobal(DeclName->getValue()))
373406c3fb27SDimitry Andric     return TokError("def or global variable of this name already exists");
373506c3fb27SDimitry Andric 
37365ffd83dbSDimitry Andric   Lex.Lex();
37375ffd83dbSDimitry Andric   if (!consume(tgtok::equal))
3738480093f4SDimitry Andric     return TokError("expected '='");
3739480093f4SDimitry Andric 
374006c3fb27SDimitry Andric   Init *Value = ParseValue(CurRec);
3741480093f4SDimitry Andric   if (!Value)
3742480093f4SDimitry Andric     return true;
3743480093f4SDimitry Andric 
37445ffd83dbSDimitry Andric   if (!consume(tgtok::semi))
3745480093f4SDimitry Andric     return TokError("expected ';'");
3746480093f4SDimitry Andric 
374706c3fb27SDimitry Andric   if (!CurScope->isOutermost())
374806c3fb27SDimitry Andric     CurScope->addVar(DeclName->getValue(), Value);
3749480093f4SDimitry Andric   else
3750480093f4SDimitry Andric     Records.addExtraGlobal(DeclName->getValue(), Value);
3751480093f4SDimitry Andric 
3752480093f4SDimitry Andric   return false;
3753480093f4SDimitry Andric }
3754480093f4SDimitry Andric 
37550b57cec5SDimitry Andric /// ParseForeach - Parse a for statement.  Return the record corresponding
37560b57cec5SDimitry Andric /// to it.  This returns true on error.
37570b57cec5SDimitry Andric ///
37580b57cec5SDimitry Andric ///   Foreach ::= FOREACH Declaration IN '{ ObjectList '}'
37590b57cec5SDimitry Andric ///   Foreach ::= FOREACH Declaration IN Object
37600b57cec5SDimitry Andric ///
ParseForeach(MultiClass * CurMultiClass)37610b57cec5SDimitry Andric bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
37620b57cec5SDimitry Andric   SMLoc Loc = Lex.getLoc();
37630b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::Foreach && "Unknown tok");
37640b57cec5SDimitry Andric   Lex.Lex();  // Eat the 'for' token.
37650b57cec5SDimitry Andric 
37660b57cec5SDimitry Andric   // Make a temporary object to record items associated with the for
37670b57cec5SDimitry Andric   // loop.
37680b57cec5SDimitry Andric   Init *ListValue = nullptr;
37690b57cec5SDimitry Andric   VarInit *IterName = ParseForeachDeclaration(ListValue);
37700b57cec5SDimitry Andric   if (!IterName)
37710b57cec5SDimitry Andric     return TokError("expected declaration in for");
37720b57cec5SDimitry Andric 
37735ffd83dbSDimitry Andric   if (!consume(tgtok::In))
37740b57cec5SDimitry Andric     return TokError("Unknown tok");
37750b57cec5SDimitry Andric 
37760b57cec5SDimitry Andric   // Create a loop object and remember it.
377706c3fb27SDimitry Andric   auto TheLoop = std::make_unique<ForeachLoop>(Loc, IterName, ListValue);
3778480093f4SDimitry Andric   // A foreach loop introduces a new scope for local variables.
377906c3fb27SDimitry Andric   TGVarScope *ForeachScope = PushScope(TheLoop.get());
378006c3fb27SDimitry Andric   Loops.push_back(std::move(TheLoop));
3781480093f4SDimitry Andric 
37820b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::l_brace) {
37830b57cec5SDimitry Andric     // FOREACH Declaration IN Object
37840b57cec5SDimitry Andric     if (ParseObject(CurMultiClass))
37850b57cec5SDimitry Andric       return true;
37860b57cec5SDimitry Andric   } else {
37870b57cec5SDimitry Andric     SMLoc BraceLoc = Lex.getLoc();
37880b57cec5SDimitry Andric     // Otherwise, this is a group foreach.
37890b57cec5SDimitry Andric     Lex.Lex();  // eat the '{'.
37900b57cec5SDimitry Andric 
37910b57cec5SDimitry Andric     // Parse the object list.
37920b57cec5SDimitry Andric     if (ParseObjectList(CurMultiClass))
37930b57cec5SDimitry Andric       return true;
37940b57cec5SDimitry Andric 
37955ffd83dbSDimitry Andric     if (!consume(tgtok::r_brace)) {
37960b57cec5SDimitry Andric       TokError("expected '}' at end of foreach command");
37970b57cec5SDimitry Andric       return Error(BraceLoc, "to match this '{'");
37980b57cec5SDimitry Andric     }
37990b57cec5SDimitry Andric   }
38000b57cec5SDimitry Andric 
380106c3fb27SDimitry Andric   PopScope(ForeachScope);
3802480093f4SDimitry Andric 
38030b57cec5SDimitry Andric   // Resolve the loop or store it for later resolution.
38040b57cec5SDimitry Andric   std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
38050b57cec5SDimitry Andric   Loops.pop_back();
38060b57cec5SDimitry Andric 
38070b57cec5SDimitry Andric   return addEntry(std::move(Loop));
38080b57cec5SDimitry Andric }
38090b57cec5SDimitry Andric 
3810480093f4SDimitry Andric /// ParseIf - Parse an if statement.
3811480093f4SDimitry Andric ///
3812480093f4SDimitry Andric ///   If ::= IF Value THEN IfBody
3813480093f4SDimitry Andric ///   If ::= IF Value THEN IfBody ELSE IfBody
3814480093f4SDimitry Andric ///
ParseIf(MultiClass * CurMultiClass)3815480093f4SDimitry Andric bool TGParser::ParseIf(MultiClass *CurMultiClass) {
3816480093f4SDimitry Andric   SMLoc Loc = Lex.getLoc();
3817480093f4SDimitry Andric   assert(Lex.getCode() == tgtok::If && "Unknown tok");
3818480093f4SDimitry Andric   Lex.Lex(); // Eat the 'if' token.
3819480093f4SDimitry Andric 
3820480093f4SDimitry Andric   // Make a temporary object to record items associated with the for
3821480093f4SDimitry Andric   // loop.
3822480093f4SDimitry Andric   Init *Condition = ParseValue(nullptr);
3823480093f4SDimitry Andric   if (!Condition)
3824480093f4SDimitry Andric     return true;
3825480093f4SDimitry Andric 
38265ffd83dbSDimitry Andric   if (!consume(tgtok::Then))
3827480093f4SDimitry Andric     return TokError("Unknown tok");
3828480093f4SDimitry Andric 
3829480093f4SDimitry Andric   // We have to be able to save if statements to execute later, and they have
3830480093f4SDimitry Andric   // to live on the same stack as foreach loops. The simplest implementation
3831480093f4SDimitry Andric   // technique is to convert each 'then' or 'else' clause *into* a foreach
3832480093f4SDimitry Andric   // loop, over a list of length 0 or 1 depending on the condition, and with no
3833480093f4SDimitry Andric   // iteration variable being assigned.
3834480093f4SDimitry Andric 
383581ad6265SDimitry Andric   ListInit *EmptyList = ListInit::get({}, BitRecTy::get(Records));
383604eeddc0SDimitry Andric   ListInit *SingletonList =
383781ad6265SDimitry Andric       ListInit::get({BitInit::get(Records, true)}, BitRecTy::get(Records));
383881ad6265SDimitry Andric   RecTy *BitListTy = ListRecTy::get(BitRecTy::get(Records));
3839480093f4SDimitry Andric 
3840480093f4SDimitry Andric   // The foreach containing the then-clause selects SingletonList if
3841480093f4SDimitry Andric   // the condition is true.
3842480093f4SDimitry Andric   Init *ThenClauseList =
3843480093f4SDimitry Andric       TernOpInit::get(TernOpInit::IF, Condition, SingletonList, EmptyList,
3844480093f4SDimitry Andric                       BitListTy)
3845480093f4SDimitry Andric           ->Fold(nullptr);
3846480093f4SDimitry Andric   Loops.push_back(std::make_unique<ForeachLoop>(Loc, nullptr, ThenClauseList));
3847480093f4SDimitry Andric 
3848480093f4SDimitry Andric   if (ParseIfBody(CurMultiClass, "then"))
3849480093f4SDimitry Andric     return true;
3850480093f4SDimitry Andric 
3851480093f4SDimitry Andric   std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
3852480093f4SDimitry Andric   Loops.pop_back();
3853480093f4SDimitry Andric 
3854480093f4SDimitry Andric   if (addEntry(std::move(Loop)))
3855480093f4SDimitry Andric     return true;
3856480093f4SDimitry Andric 
3857480093f4SDimitry Andric   // Now look for an optional else clause. The if-else syntax has the usual
3858480093f4SDimitry Andric   // dangling-else ambiguity, and by greedily matching an else here if we can,
3859480093f4SDimitry Andric   // we implement the usual resolution of pairing with the innermost unmatched
3860480093f4SDimitry Andric   // if.
38615ffd83dbSDimitry Andric   if (consume(tgtok::ElseKW)) {
3862480093f4SDimitry Andric     // The foreach containing the else-clause uses the same pair of lists as
3863480093f4SDimitry Andric     // above, but this time, selects SingletonList if the condition is *false*.
3864480093f4SDimitry Andric     Init *ElseClauseList =
3865480093f4SDimitry Andric         TernOpInit::get(TernOpInit::IF, Condition, EmptyList, SingletonList,
3866480093f4SDimitry Andric                         BitListTy)
3867480093f4SDimitry Andric             ->Fold(nullptr);
3868480093f4SDimitry Andric     Loops.push_back(
3869480093f4SDimitry Andric         std::make_unique<ForeachLoop>(Loc, nullptr, ElseClauseList));
3870480093f4SDimitry Andric 
3871480093f4SDimitry Andric     if (ParseIfBody(CurMultiClass, "else"))
3872480093f4SDimitry Andric       return true;
3873480093f4SDimitry Andric 
3874480093f4SDimitry Andric     Loop = std::move(Loops.back());
3875480093f4SDimitry Andric     Loops.pop_back();
3876480093f4SDimitry Andric 
3877480093f4SDimitry Andric     if (addEntry(std::move(Loop)))
3878480093f4SDimitry Andric       return true;
3879480093f4SDimitry Andric   }
3880480093f4SDimitry Andric 
3881480093f4SDimitry Andric   return false;
3882480093f4SDimitry Andric }
3883480093f4SDimitry Andric 
3884480093f4SDimitry Andric /// ParseIfBody - Parse the then-clause or else-clause of an if statement.
3885480093f4SDimitry Andric ///
3886480093f4SDimitry Andric ///   IfBody ::= Object
3887480093f4SDimitry Andric ///   IfBody ::= '{' ObjectList '}'
3888480093f4SDimitry Andric ///
ParseIfBody(MultiClass * CurMultiClass,StringRef Kind)3889480093f4SDimitry Andric bool TGParser::ParseIfBody(MultiClass *CurMultiClass, StringRef Kind) {
389006c3fb27SDimitry Andric   // An if-statement introduces a new scope for local variables.
389106c3fb27SDimitry Andric   TGVarScope *BodyScope = PushScope();
3892480093f4SDimitry Andric 
3893480093f4SDimitry Andric   if (Lex.getCode() != tgtok::l_brace) {
3894480093f4SDimitry Andric     // A single object.
3895480093f4SDimitry Andric     if (ParseObject(CurMultiClass))
3896480093f4SDimitry Andric       return true;
3897480093f4SDimitry Andric   } else {
3898480093f4SDimitry Andric     SMLoc BraceLoc = Lex.getLoc();
3899480093f4SDimitry Andric     // A braced block.
3900480093f4SDimitry Andric     Lex.Lex(); // eat the '{'.
3901480093f4SDimitry Andric 
3902480093f4SDimitry Andric     // Parse the object list.
3903480093f4SDimitry Andric     if (ParseObjectList(CurMultiClass))
3904480093f4SDimitry Andric       return true;
3905480093f4SDimitry Andric 
39065ffd83dbSDimitry Andric     if (!consume(tgtok::r_brace)) {
3907480093f4SDimitry Andric       TokError("expected '}' at end of '" + Kind + "' clause");
3908480093f4SDimitry Andric       return Error(BraceLoc, "to match this '{'");
3909480093f4SDimitry Andric     }
3910480093f4SDimitry Andric   }
3911480093f4SDimitry Andric 
391206c3fb27SDimitry Andric   PopScope(BodyScope);
3913480093f4SDimitry Andric   return false;
3914480093f4SDimitry Andric }
3915480093f4SDimitry Andric 
3916e8d8bef9SDimitry Andric /// ParseAssert - Parse an assert statement.
3917e8d8bef9SDimitry Andric ///
3918e8d8bef9SDimitry Andric ///   Assert ::= ASSERT condition , message ;
ParseAssert(MultiClass * CurMultiClass,Record * CurRec)3919e8d8bef9SDimitry Andric bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
3920e8d8bef9SDimitry Andric   assert(Lex.getCode() == tgtok::Assert && "Unknown tok");
3921e8d8bef9SDimitry Andric   Lex.Lex(); // Eat the 'assert' token.
3922e8d8bef9SDimitry Andric 
3923e8d8bef9SDimitry Andric   SMLoc ConditionLoc = Lex.getLoc();
3924e8d8bef9SDimitry Andric   Init *Condition = ParseValue(CurRec);
3925e8d8bef9SDimitry Andric   if (!Condition)
3926e8d8bef9SDimitry Andric     return true;
3927e8d8bef9SDimitry Andric 
3928e8d8bef9SDimitry Andric   if (!consume(tgtok::comma)) {
3929e8d8bef9SDimitry Andric     TokError("expected ',' in assert statement");
3930e8d8bef9SDimitry Andric     return true;
3931e8d8bef9SDimitry Andric   }
3932e8d8bef9SDimitry Andric 
3933e8d8bef9SDimitry Andric   Init *Message = ParseValue(CurRec);
3934e8d8bef9SDimitry Andric   if (!Message)
3935e8d8bef9SDimitry Andric     return true;
3936e8d8bef9SDimitry Andric 
3937e8d8bef9SDimitry Andric   if (!consume(tgtok::semi))
3938e8d8bef9SDimitry Andric     return TokError("expected ';'");
3939e8d8bef9SDimitry Andric 
3940fe6060f1SDimitry Andric   if (CurRec)
3941e8d8bef9SDimitry Andric     CurRec->addAssertion(ConditionLoc, Condition, Message);
3942fe6060f1SDimitry Andric   else
3943fe6060f1SDimitry Andric     addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
3944fe6060f1SDimitry Andric                                                      Message));
3945e8d8bef9SDimitry Andric   return false;
3946e8d8bef9SDimitry Andric }
3947e8d8bef9SDimitry Andric 
39480b57cec5SDimitry Andric /// ParseClass - Parse a tblgen class definition.
39490b57cec5SDimitry Andric ///
39500b57cec5SDimitry Andric ///   ClassInst ::= CLASS ID TemplateArgList? ObjectBody
39510b57cec5SDimitry Andric ///
ParseClass()39520b57cec5SDimitry Andric bool TGParser::ParseClass() {
39530b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::Class && "Unexpected token!");
39540b57cec5SDimitry Andric   Lex.Lex();
39550b57cec5SDimitry Andric 
39560b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Id)
39570b57cec5SDimitry Andric     return TokError("expected class name after 'class' keyword");
39580b57cec5SDimitry Andric 
3959*0fca6ea1SDimitry Andric   const std::string &Name = Lex.getCurStrVal();
3960*0fca6ea1SDimitry Andric   Record *CurRec = Records.getClass(Name);
39610b57cec5SDimitry Andric   if (CurRec) {
39620b57cec5SDimitry Andric     // If the body was previously defined, this is an error.
39630b57cec5SDimitry Andric     if (!CurRec->getValues().empty() ||
39640b57cec5SDimitry Andric         !CurRec->getSuperClasses().empty() ||
39650b57cec5SDimitry Andric         !CurRec->getTemplateArgs().empty())
39660b57cec5SDimitry Andric       return TokError("Class '" + CurRec->getNameInitAsString() +
39670b57cec5SDimitry Andric                       "' already defined");
3968fcaf7f86SDimitry Andric 
3969fcaf7f86SDimitry Andric     CurRec->updateClassLoc(Lex.getLoc());
39700b57cec5SDimitry Andric   } else {
39710b57cec5SDimitry Andric     // If this is the first reference to this class, create and add it.
39725f757f3fSDimitry Andric     auto NewRec = std::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(),
39735f757f3fSDimitry Andric                                            Records, Record::RK_Class);
39740b57cec5SDimitry Andric     CurRec = NewRec.get();
39750b57cec5SDimitry Andric     Records.addClass(std::move(NewRec));
39760b57cec5SDimitry Andric   }
3977*0fca6ea1SDimitry Andric 
3978*0fca6ea1SDimitry Andric   if (TypeAliases.count(Name))
3979*0fca6ea1SDimitry Andric     return TokError("there is already a defined type alias '" + Name + "'");
3980*0fca6ea1SDimitry Andric 
39810b57cec5SDimitry Andric   Lex.Lex(); // eat the name.
39820b57cec5SDimitry Andric 
398306c3fb27SDimitry Andric   // A class definition introduces a new scope.
398406c3fb27SDimitry Andric   TGVarScope *ClassScope = PushScope(CurRec);
39850b57cec5SDimitry Andric   // If there are template args, parse them.
39860b57cec5SDimitry Andric   if (Lex.getCode() == tgtok::less)
39870b57cec5SDimitry Andric     if (ParseTemplateArgList(CurRec))
39880b57cec5SDimitry Andric       return true;
39890b57cec5SDimitry Andric 
3990349cc55cSDimitry Andric   if (ParseObjectBody(CurRec))
3991349cc55cSDimitry Andric     return true;
3992349cc55cSDimitry Andric 
3993349cc55cSDimitry Andric   if (!NoWarnOnUnusedTemplateArgs)
3994349cc55cSDimitry Andric     CurRec->checkUnusedTemplateArgs();
399506c3fb27SDimitry Andric 
399606c3fb27SDimitry Andric   PopScope(ClassScope);
3997349cc55cSDimitry Andric   return false;
39980b57cec5SDimitry Andric }
39990b57cec5SDimitry Andric 
40000b57cec5SDimitry Andric /// ParseLetList - Parse a non-empty list of assignment expressions into a list
40010b57cec5SDimitry Andric /// of LetRecords.
40020b57cec5SDimitry Andric ///
40030b57cec5SDimitry Andric ///   LetList ::= LetItem (',' LetItem)*
40040b57cec5SDimitry Andric ///   LetItem ::= ID OptionalRangeList '=' Value
40050b57cec5SDimitry Andric ///
ParseLetList(SmallVectorImpl<LetRecord> & Result)40060b57cec5SDimitry Andric void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) {
40075ffd83dbSDimitry Andric   do {
40080b57cec5SDimitry Andric     if (Lex.getCode() != tgtok::Id) {
40090b57cec5SDimitry Andric       TokError("expected identifier in let definition");
40100b57cec5SDimitry Andric       Result.clear();
40110b57cec5SDimitry Andric       return;
40120b57cec5SDimitry Andric     }
40130b57cec5SDimitry Andric 
401481ad6265SDimitry Andric     StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
40150b57cec5SDimitry Andric     SMLoc NameLoc = Lex.getLoc();
40160b57cec5SDimitry Andric     Lex.Lex();  // Eat the identifier.
40170b57cec5SDimitry Andric 
40180b57cec5SDimitry Andric     // Check for an optional RangeList.
40190b57cec5SDimitry Andric     SmallVector<unsigned, 16> Bits;
40200b57cec5SDimitry Andric     if (ParseOptionalRangeList(Bits)) {
40210b57cec5SDimitry Andric       Result.clear();
40220b57cec5SDimitry Andric       return;
40230b57cec5SDimitry Andric     }
40240b57cec5SDimitry Andric     std::reverse(Bits.begin(), Bits.end());
40250b57cec5SDimitry Andric 
40265ffd83dbSDimitry Andric     if (!consume(tgtok::equal)) {
40270b57cec5SDimitry Andric       TokError("expected '=' in let expression");
40280b57cec5SDimitry Andric       Result.clear();
40290b57cec5SDimitry Andric       return;
40300b57cec5SDimitry Andric     }
40310b57cec5SDimitry Andric 
40320b57cec5SDimitry Andric     Init *Val = ParseValue(nullptr);
40330b57cec5SDimitry Andric     if (!Val) {
40340b57cec5SDimitry Andric       Result.clear();
40350b57cec5SDimitry Andric       return;
40360b57cec5SDimitry Andric     }
40370b57cec5SDimitry Andric 
40380b57cec5SDimitry Andric     // Now that we have everything, add the record.
40390b57cec5SDimitry Andric     Result.emplace_back(Name, Bits, Val, NameLoc);
40405ffd83dbSDimitry Andric   } while (consume(tgtok::comma));
40410b57cec5SDimitry Andric }
40420b57cec5SDimitry Andric 
40430b57cec5SDimitry Andric /// ParseTopLevelLet - Parse a 'let' at top level.  This can be a couple of
40440b57cec5SDimitry Andric /// different related productions. This works inside multiclasses too.
40450b57cec5SDimitry Andric ///
40460b57cec5SDimitry Andric ///   Object ::= LET LetList IN '{' ObjectList '}'
40470b57cec5SDimitry Andric ///   Object ::= LET LetList IN Object
40480b57cec5SDimitry Andric ///
ParseTopLevelLet(MultiClass * CurMultiClass)40490b57cec5SDimitry Andric bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
40500b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::Let && "Unexpected token");
40510b57cec5SDimitry Andric   Lex.Lex();
40520b57cec5SDimitry Andric 
40530b57cec5SDimitry Andric   // Add this entry to the let stack.
40540b57cec5SDimitry Andric   SmallVector<LetRecord, 8> LetInfo;
40550b57cec5SDimitry Andric   ParseLetList(LetInfo);
40560b57cec5SDimitry Andric   if (LetInfo.empty()) return true;
40570b57cec5SDimitry Andric   LetStack.push_back(std::move(LetInfo));
40580b57cec5SDimitry Andric 
40595ffd83dbSDimitry Andric   if (!consume(tgtok::In))
40600b57cec5SDimitry Andric     return TokError("expected 'in' at end of top-level 'let'");
40610b57cec5SDimitry Andric 
40620b57cec5SDimitry Andric   // If this is a scalar let, just handle it now
40630b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::l_brace) {
40640b57cec5SDimitry Andric     // LET LetList IN Object
40650b57cec5SDimitry Andric     if (ParseObject(CurMultiClass))
40660b57cec5SDimitry Andric       return true;
40670b57cec5SDimitry Andric   } else {   // Object ::= LETCommand '{' ObjectList '}'
40680b57cec5SDimitry Andric     SMLoc BraceLoc = Lex.getLoc();
40690b57cec5SDimitry Andric     // Otherwise, this is a group let.
40700b57cec5SDimitry Andric     Lex.Lex();  // eat the '{'.
40710b57cec5SDimitry Andric 
407206c3fb27SDimitry Andric     // A group let introduces a new scope for local variables.
407306c3fb27SDimitry Andric     TGVarScope *LetScope = PushScope();
407406c3fb27SDimitry Andric 
40750b57cec5SDimitry Andric     // Parse the object list.
40760b57cec5SDimitry Andric     if (ParseObjectList(CurMultiClass))
40770b57cec5SDimitry Andric       return true;
40780b57cec5SDimitry Andric 
40795ffd83dbSDimitry Andric     if (!consume(tgtok::r_brace)) {
40800b57cec5SDimitry Andric       TokError("expected '}' at end of top level let command");
40810b57cec5SDimitry Andric       return Error(BraceLoc, "to match this '{'");
40820b57cec5SDimitry Andric     }
40830b57cec5SDimitry Andric 
408406c3fb27SDimitry Andric     PopScope(LetScope);
408506c3fb27SDimitry Andric   }
4086480093f4SDimitry Andric 
40870b57cec5SDimitry Andric   // Outside this let scope, this let block is not active.
40880b57cec5SDimitry Andric   LetStack.pop_back();
40890b57cec5SDimitry Andric   return false;
40900b57cec5SDimitry Andric }
40910b57cec5SDimitry Andric 
40920b57cec5SDimitry Andric /// ParseMultiClass - Parse a multiclass definition.
40930b57cec5SDimitry Andric ///
40940b57cec5SDimitry Andric ///  MultiClassInst ::= MULTICLASS ID TemplateArgList?
40950b57cec5SDimitry Andric ///                     ':' BaseMultiClassList '{' MultiClassObject+ '}'
4096fe6060f1SDimitry Andric ///  MultiClassObject ::= Assert
40970b57cec5SDimitry Andric ///  MultiClassObject ::= DefInst
40980b57cec5SDimitry Andric ///  MultiClassObject ::= DefMInst
4099fe6060f1SDimitry Andric ///  MultiClassObject ::= Defvar
4100fe6060f1SDimitry Andric ///  MultiClassObject ::= Foreach
4101fe6060f1SDimitry Andric ///  MultiClassObject ::= If
41020b57cec5SDimitry Andric ///  MultiClassObject ::= LETCommand '{' ObjectList '}'
41030b57cec5SDimitry Andric ///  MultiClassObject ::= LETCommand Object
41040b57cec5SDimitry Andric ///
ParseMultiClass()41050b57cec5SDimitry Andric bool TGParser::ParseMultiClass() {
41060b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
41070b57cec5SDimitry Andric   Lex.Lex();  // Eat the multiclass token.
41080b57cec5SDimitry Andric 
41090b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::Id)
41100b57cec5SDimitry Andric     return TokError("expected identifier after multiclass for name");
41110b57cec5SDimitry Andric   std::string Name = Lex.getCurStrVal();
41120b57cec5SDimitry Andric 
41130b57cec5SDimitry Andric   auto Result =
41140b57cec5SDimitry Andric     MultiClasses.insert(std::make_pair(Name,
41158bcb0991SDimitry Andric                     std::make_unique<MultiClass>(Name, Lex.getLoc(),Records)));
41160b57cec5SDimitry Andric 
41170b57cec5SDimitry Andric   if (!Result.second)
41180b57cec5SDimitry Andric     return TokError("multiclass '" + Name + "' already defined");
41190b57cec5SDimitry Andric 
41200b57cec5SDimitry Andric   CurMultiClass = Result.first->second.get();
41210b57cec5SDimitry Andric   Lex.Lex();  // Eat the identifier.
41220b57cec5SDimitry Andric 
412306c3fb27SDimitry Andric   // A multiclass body introduces a new scope for local variables.
412406c3fb27SDimitry Andric   TGVarScope *MulticlassScope = PushScope(CurMultiClass);
412506c3fb27SDimitry Andric 
41260b57cec5SDimitry Andric   // If there are template args, parse them.
41270b57cec5SDimitry Andric   if (Lex.getCode() == tgtok::less)
41280b57cec5SDimitry Andric     if (ParseTemplateArgList(nullptr))
41290b57cec5SDimitry Andric       return true;
41300b57cec5SDimitry Andric 
41310b57cec5SDimitry Andric   bool inherits = false;
41320b57cec5SDimitry Andric 
41330b57cec5SDimitry Andric   // If there are submulticlasses, parse them.
41345ffd83dbSDimitry Andric   if (consume(tgtok::colon)) {
41350b57cec5SDimitry Andric     inherits = true;
41360b57cec5SDimitry Andric 
41370b57cec5SDimitry Andric     // Read all of the submulticlasses.
41380b57cec5SDimitry Andric     SubMultiClassReference SubMultiClass =
41390b57cec5SDimitry Andric       ParseSubMultiClassReference(CurMultiClass);
41400b57cec5SDimitry Andric     while (true) {
41410b57cec5SDimitry Andric       // Check for error.
41420b57cec5SDimitry Andric       if (!SubMultiClass.MC) return true;
41430b57cec5SDimitry Andric 
41440b57cec5SDimitry Andric       // Add it.
41450b57cec5SDimitry Andric       if (AddSubMultiClass(CurMultiClass, SubMultiClass))
41460b57cec5SDimitry Andric         return true;
41470b57cec5SDimitry Andric 
41485ffd83dbSDimitry Andric       if (!consume(tgtok::comma))
41495ffd83dbSDimitry Andric         break;
41500b57cec5SDimitry Andric       SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
41510b57cec5SDimitry Andric     }
41520b57cec5SDimitry Andric   }
41530b57cec5SDimitry Andric 
41540b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::l_brace) {
41550b57cec5SDimitry Andric     if (!inherits)
41560b57cec5SDimitry Andric       return TokError("expected '{' in multiclass definition");
41575ffd83dbSDimitry Andric     if (!consume(tgtok::semi))
41580b57cec5SDimitry Andric       return TokError("expected ';' in multiclass definition");
41590b57cec5SDimitry Andric   } else {
41600b57cec5SDimitry Andric     if (Lex.Lex() == tgtok::r_brace)  // eat the '{'.
41610b57cec5SDimitry Andric       return TokError("multiclass must contain at least one def");
41620b57cec5SDimitry Andric 
41630b57cec5SDimitry Andric     while (Lex.getCode() != tgtok::r_brace) {
41640b57cec5SDimitry Andric       switch (Lex.getCode()) {
41650b57cec5SDimitry Andric       default:
41665f757f3fSDimitry Andric         return TokError("expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4167e8d8bef9SDimitry Andric                         "'foreach', 'if', or 'let' in multiclass body");
4168e8d8bef9SDimitry Andric 
4169fe6060f1SDimitry Andric       case tgtok::Assert:
41700b57cec5SDimitry Andric       case tgtok::Def:
41710b57cec5SDimitry Andric       case tgtok::Defm:
4172480093f4SDimitry Andric       case tgtok::Defvar:
41735f757f3fSDimitry Andric       case tgtok::Dump:
41740b57cec5SDimitry Andric       case tgtok::Foreach:
4175480093f4SDimitry Andric       case tgtok::If:
4176e8d8bef9SDimitry Andric       case tgtok::Let:
41770b57cec5SDimitry Andric         if (ParseObject(CurMultiClass))
41780b57cec5SDimitry Andric           return true;
41790b57cec5SDimitry Andric         break;
41800b57cec5SDimitry Andric       }
41810b57cec5SDimitry Andric     }
41820b57cec5SDimitry Andric     Lex.Lex();  // eat the '}'.
4183480093f4SDimitry Andric 
4184e8d8bef9SDimitry Andric     // If we have a semicolon, print a gentle error.
4185e8d8bef9SDimitry Andric     SMLoc SemiLoc = Lex.getLoc();
4186e8d8bef9SDimitry Andric     if (consume(tgtok::semi)) {
4187e8d8bef9SDimitry Andric       PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
4188e8d8bef9SDimitry Andric       PrintNote("Semicolon ignored; remove to eliminate this error");
4189e8d8bef9SDimitry Andric     }
41900b57cec5SDimitry Andric   }
41910b57cec5SDimitry Andric 
4192349cc55cSDimitry Andric   if (!NoWarnOnUnusedTemplateArgs)
4193349cc55cSDimitry Andric     CurMultiClass->Rec.checkUnusedTemplateArgs();
4194349cc55cSDimitry Andric 
419506c3fb27SDimitry Andric   PopScope(MulticlassScope);
41960b57cec5SDimitry Andric   CurMultiClass = nullptr;
41970b57cec5SDimitry Andric   return false;
41980b57cec5SDimitry Andric }
41990b57cec5SDimitry Andric 
42000b57cec5SDimitry Andric /// ParseDefm - Parse the instantiation of a multiclass.
42010b57cec5SDimitry Andric ///
42020b57cec5SDimitry Andric ///   DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
42030b57cec5SDimitry Andric ///
ParseDefm(MultiClass * CurMultiClass)42040b57cec5SDimitry Andric bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
42050b57cec5SDimitry Andric   assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
42060b57cec5SDimitry Andric   Lex.Lex(); // eat the defm
42070b57cec5SDimitry Andric 
42080b57cec5SDimitry Andric   Init *DefmName = ParseObjectName(CurMultiClass);
42090b57cec5SDimitry Andric   if (!DefmName)
42100b57cec5SDimitry Andric     return true;
42110b57cec5SDimitry Andric   if (isa<UnsetInit>(DefmName)) {
42120b57cec5SDimitry Andric     DefmName = Records.getNewAnonymousName();
42130b57cec5SDimitry Andric     if (CurMultiClass)
42140b57cec5SDimitry Andric       DefmName = BinOpInit::getStrConcat(
42150b57cec5SDimitry Andric           VarInit::get(QualifiedNameOfImplicitName(CurMultiClass),
421681ad6265SDimitry Andric                        StringRecTy::get(Records)),
42170b57cec5SDimitry Andric           DefmName);
42180b57cec5SDimitry Andric   }
42190b57cec5SDimitry Andric 
42200b57cec5SDimitry Andric   if (Lex.getCode() != tgtok::colon)
42210b57cec5SDimitry Andric     return TokError("expected ':' after defm identifier");
42220b57cec5SDimitry Andric 
42230b57cec5SDimitry Andric   // Keep track of the new generated record definitions.
42240b57cec5SDimitry Andric   std::vector<RecordsEntry> NewEntries;
42250b57cec5SDimitry Andric 
42260b57cec5SDimitry Andric   // This record also inherits from a regular class (non-multiclass)?
42270b57cec5SDimitry Andric   bool InheritFromClass = false;
42280b57cec5SDimitry Andric 
42290b57cec5SDimitry Andric   // eat the colon.
42300b57cec5SDimitry Andric   Lex.Lex();
42310b57cec5SDimitry Andric 
42320b57cec5SDimitry Andric   SMLoc SubClassLoc = Lex.getLoc();
42330b57cec5SDimitry Andric   SubClassReference Ref = ParseSubClassReference(nullptr, true);
42340b57cec5SDimitry Andric 
42350b57cec5SDimitry Andric   while (true) {
42360b57cec5SDimitry Andric     if (!Ref.Rec) return true;
42370b57cec5SDimitry Andric 
4238fe6060f1SDimitry Andric     // To instantiate a multiclass, we get the multiclass and then loop
4239fe6060f1SDimitry Andric     // through its template argument names. Substs contains a substitution
4240fe6060f1SDimitry Andric     // value for each argument, either the value specified or the default.
4241fe6060f1SDimitry Andric     // Then we can resolve the template arguments.
42425ffd83dbSDimitry Andric     MultiClass *MC = MultiClasses[std::string(Ref.Rec->getName())].get();
42430b57cec5SDimitry Andric     assert(MC && "Didn't lookup multiclass correctly?");
4244fe6060f1SDimitry Andric 
42450b57cec5SDimitry Andric     SubstStack Substs;
424606c3fb27SDimitry Andric     if (resolveArgumentsOfMultiClass(Substs, MC, Ref.TemplateArgs, DefmName,
424706c3fb27SDimitry Andric                                      SubClassLoc))
424806c3fb27SDimitry Andric       return true;
42490b57cec5SDimitry Andric 
4250fe6060f1SDimitry Andric     if (resolve(MC->Entries, Substs, !CurMultiClass && Loops.empty(),
4251fe6060f1SDimitry Andric                 &NewEntries, &SubClassLoc))
42520b57cec5SDimitry Andric       return true;
42530b57cec5SDimitry Andric 
42545ffd83dbSDimitry Andric     if (!consume(tgtok::comma))
42555ffd83dbSDimitry Andric       break;
42560b57cec5SDimitry Andric 
42570b57cec5SDimitry Andric     if (Lex.getCode() != tgtok::Id)
42580b57cec5SDimitry Andric       return TokError("expected identifier");
42590b57cec5SDimitry Andric 
42600b57cec5SDimitry Andric     SubClassLoc = Lex.getLoc();
42610b57cec5SDimitry Andric 
4262fe6060f1SDimitry Andric     // A defm can inherit from regular classes (non-multiclasses) as
42630b57cec5SDimitry Andric     // long as they come in the end of the inheritance list.
42640b57cec5SDimitry Andric     InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr);
42650b57cec5SDimitry Andric 
42660b57cec5SDimitry Andric     if (InheritFromClass)
42670b57cec5SDimitry Andric       break;
42680b57cec5SDimitry Andric 
42690b57cec5SDimitry Andric     Ref = ParseSubClassReference(nullptr, true);
42700b57cec5SDimitry Andric   }
42710b57cec5SDimitry Andric 
42720b57cec5SDimitry Andric   if (InheritFromClass) {
42730b57cec5SDimitry Andric     // Process all the classes to inherit as if they were part of a
42740b57cec5SDimitry Andric     // regular 'def' and inherit all record values.
42750b57cec5SDimitry Andric     SubClassReference SubClass = ParseSubClassReference(nullptr, false);
42760b57cec5SDimitry Andric     while (true) {
42770b57cec5SDimitry Andric       // Check for error.
42780b57cec5SDimitry Andric       if (!SubClass.Rec) return true;
42790b57cec5SDimitry Andric 
42800b57cec5SDimitry Andric       // Get the expanded definition prototypes and teach them about
42810b57cec5SDimitry Andric       // the record values the current class to inherit has
42820b57cec5SDimitry Andric       for (auto &E : NewEntries) {
42830b57cec5SDimitry Andric         // Add it.
42840b57cec5SDimitry Andric         if (AddSubClass(E, SubClass))
42850b57cec5SDimitry Andric           return true;
42860b57cec5SDimitry Andric       }
42870b57cec5SDimitry Andric 
42885ffd83dbSDimitry Andric       if (!consume(tgtok::comma))
42895ffd83dbSDimitry Andric         break;
42900b57cec5SDimitry Andric       SubClass = ParseSubClassReference(nullptr, false);
42910b57cec5SDimitry Andric     }
42920b57cec5SDimitry Andric   }
42930b57cec5SDimitry Andric 
42940b57cec5SDimitry Andric   for (auto &E : NewEntries) {
42950b57cec5SDimitry Andric     if (ApplyLetStack(E))
42960b57cec5SDimitry Andric       return true;
42970b57cec5SDimitry Andric 
42980b57cec5SDimitry Andric     addEntry(std::move(E));
42990b57cec5SDimitry Andric   }
43000b57cec5SDimitry Andric 
43015ffd83dbSDimitry Andric   if (!consume(tgtok::semi))
43020b57cec5SDimitry Andric     return TokError("expected ';' at end of defm");
43030b57cec5SDimitry Andric 
43040b57cec5SDimitry Andric   return false;
43050b57cec5SDimitry Andric }
43060b57cec5SDimitry Andric 
43070b57cec5SDimitry Andric /// ParseObject
43080b57cec5SDimitry Andric ///   Object ::= ClassInst
43090b57cec5SDimitry Andric ///   Object ::= DefInst
43100b57cec5SDimitry Andric ///   Object ::= MultiClassInst
43110b57cec5SDimitry Andric ///   Object ::= DefMInst
43120b57cec5SDimitry Andric ///   Object ::= LETCommand '{' ObjectList '}'
43130b57cec5SDimitry Andric ///   Object ::= LETCommand Object
4314480093f4SDimitry Andric ///   Object ::= Defset
4315*0fca6ea1SDimitry Andric ///   Object ::= Deftype
4316480093f4SDimitry Andric ///   Object ::= Defvar
4317e8d8bef9SDimitry Andric ///   Object ::= Assert
43185f757f3fSDimitry Andric ///   Object ::= Dump
ParseObject(MultiClass * MC)43190b57cec5SDimitry Andric bool TGParser::ParseObject(MultiClass *MC) {
43200b57cec5SDimitry Andric   switch (Lex.getCode()) {
43210b57cec5SDimitry Andric   default:
4322e8d8bef9SDimitry Andric     return TokError(
43235f757f3fSDimitry Andric         "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4324fe6060f1SDimitry Andric   case tgtok::Assert:  return ParseAssert(MC);
43250b57cec5SDimitry Andric   case tgtok::Def:     return ParseDef(MC);
4326e8d8bef9SDimitry Andric   case tgtok::Defm:    return ParseDefm(MC);
4327*0fca6ea1SDimitry Andric   case tgtok::Deftype:
4328*0fca6ea1SDimitry Andric     return ParseDeftype();
4329e8d8bef9SDimitry Andric   case tgtok::Defvar:  return ParseDefvar();
43305f757f3fSDimitry Andric   case tgtok::Dump:
43315f757f3fSDimitry Andric     return ParseDump(MC);
43320b57cec5SDimitry Andric   case tgtok::Foreach: return ParseForeach(MC);
4333480093f4SDimitry Andric   case tgtok::If:      return ParseIf(MC);
4334e8d8bef9SDimitry Andric   case tgtok::Let:     return ParseTopLevelLet(MC);
43350b57cec5SDimitry Andric   case tgtok::Defset:
43360b57cec5SDimitry Andric     if (MC)
43370b57cec5SDimitry Andric       return TokError("defset is not allowed inside multiclass");
43380b57cec5SDimitry Andric     return ParseDefset();
43390b57cec5SDimitry Andric   case tgtok::Class:
43400b57cec5SDimitry Andric     if (MC)
43410b57cec5SDimitry Andric       return TokError("class is not allowed inside multiclass");
43420b57cec5SDimitry Andric     if (!Loops.empty())
43430b57cec5SDimitry Andric       return TokError("class is not allowed inside foreach loop");
43440b57cec5SDimitry Andric     return ParseClass();
43450b57cec5SDimitry Andric   case tgtok::MultiClass:
43460b57cec5SDimitry Andric     if (!Loops.empty())
43470b57cec5SDimitry Andric       return TokError("multiclass is not allowed inside foreach loop");
43480b57cec5SDimitry Andric     return ParseMultiClass();
43490b57cec5SDimitry Andric   }
43500b57cec5SDimitry Andric }
43510b57cec5SDimitry Andric 
43520b57cec5SDimitry Andric /// ParseObjectList
43530b57cec5SDimitry Andric ///   ObjectList :== Object*
ParseObjectList(MultiClass * MC)43540b57cec5SDimitry Andric bool TGParser::ParseObjectList(MultiClass *MC) {
43555f757f3fSDimitry Andric   while (tgtok::isObjectStart(Lex.getCode())) {
43560b57cec5SDimitry Andric     if (ParseObject(MC))
43570b57cec5SDimitry Andric       return true;
43580b57cec5SDimitry Andric   }
43590b57cec5SDimitry Andric   return false;
43600b57cec5SDimitry Andric }
43610b57cec5SDimitry Andric 
ParseFile()43620b57cec5SDimitry Andric bool TGParser::ParseFile() {
43630b57cec5SDimitry Andric   Lex.Lex(); // Prime the lexer.
436406c3fb27SDimitry Andric   TGVarScope *GlobalScope = PushScope();
436506c3fb27SDimitry Andric   if (ParseObjectList())
436606c3fb27SDimitry Andric     return true;
436706c3fb27SDimitry Andric   PopScope(GlobalScope);
43680b57cec5SDimitry Andric 
43690b57cec5SDimitry Andric   // If we have unread input at the end of the file, report it.
43700b57cec5SDimitry Andric   if (Lex.getCode() == tgtok::Eof)
43710b57cec5SDimitry Andric     return false;
43720b57cec5SDimitry Andric 
4373e8d8bef9SDimitry Andric   return TokError("Unexpected token at top level");
4374e8d8bef9SDimitry Andric }
4375e8d8bef9SDimitry Andric 
4376fe6060f1SDimitry Andric // Check the types of the template argument values for a class
4377fe6060f1SDimitry Andric // inheritance, multiclass invocation, or anonymous class invocation.
4378fe6060f1SDimitry Andric // If necessary, replace an argument with a cast to the required type.
4379fe6060f1SDimitry Andric // The argument count has already been checked.
CheckTemplateArgValues(SmallVectorImpl<llvm::ArgumentInit * > & Values,SMLoc Loc,Record * ArgsRec)438006c3fb27SDimitry Andric bool TGParser::CheckTemplateArgValues(
438106c3fb27SDimitry Andric     SmallVectorImpl<llvm::ArgumentInit *> &Values, SMLoc Loc, Record *ArgsRec) {
4382fe6060f1SDimitry Andric   ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs();
4383fe6060f1SDimitry Andric 
4384*0fca6ea1SDimitry Andric   for (llvm::ArgumentInit *&Value : Values) {
438506c3fb27SDimitry Andric     Init *ArgName = nullptr;
438606c3fb27SDimitry Andric     if (Value->isPositional())
438706c3fb27SDimitry Andric       ArgName = TArgs[Value->getIndex()];
438806c3fb27SDimitry Andric     if (Value->isNamed())
438906c3fb27SDimitry Andric       ArgName = Value->getName();
4390fe6060f1SDimitry Andric 
439106c3fb27SDimitry Andric     RecordVal *Arg = ArgsRec->getValue(ArgName);
439206c3fb27SDimitry Andric     RecTy *ArgType = Arg->getType();
439306c3fb27SDimitry Andric 
439406c3fb27SDimitry Andric     if (TypedInit *ArgValue = dyn_cast<TypedInit>(Value->getValue())) {
4395fe6060f1SDimitry Andric       auto *CastValue = ArgValue->getCastTo(ArgType);
4396fe6060f1SDimitry Andric       if (CastValue) {
4397fe6060f1SDimitry Andric         assert((!isa<TypedInit>(CastValue) ||
4398fe6060f1SDimitry Andric                 cast<TypedInit>(CastValue)->getType()->typeIsA(ArgType)) &&
4399fe6060f1SDimitry Andric                "result of template arg value cast has wrong type");
4400*0fca6ea1SDimitry Andric         Value = Value->cloneWithValue(CastValue);
4401e8d8bef9SDimitry Andric       } else {
440206c3fb27SDimitry Andric         PrintFatalError(Loc, "Value specified for template argument '" +
440306c3fb27SDimitry Andric                                  Arg->getNameInitAsString() + "' is of type " +
440406c3fb27SDimitry Andric                                  ArgValue->getType()->getAsString() +
440506c3fb27SDimitry Andric                                  "; expected type " + ArgType->getAsString() +
440606c3fb27SDimitry Andric                                  ": " + ArgValue->getAsString());
4407fe6060f1SDimitry Andric       }
4408e8d8bef9SDimitry Andric     }
4409e8d8bef9SDimitry Andric   }
4410e8d8bef9SDimitry Andric 
4411fe6060f1SDimitry Andric   return false;
44120b57cec5SDimitry Andric }
44130b57cec5SDimitry Andric 
44140b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const44150b57cec5SDimitry Andric LLVM_DUMP_METHOD void RecordsEntry::dump() const {
44160b57cec5SDimitry Andric   if (Loop)
44170b57cec5SDimitry Andric     Loop->dump();
44180b57cec5SDimitry Andric   if (Rec)
44190b57cec5SDimitry Andric     Rec->dump();
44200b57cec5SDimitry Andric }
44210b57cec5SDimitry Andric 
dump() const44220b57cec5SDimitry Andric LLVM_DUMP_METHOD void ForeachLoop::dump() const {
44230b57cec5SDimitry Andric   errs() << "foreach " << IterVar->getAsString() << " = "
44240b57cec5SDimitry Andric          << ListValue->getAsString() << " in {\n";
44250b57cec5SDimitry Andric 
44260b57cec5SDimitry Andric   for (const auto &E : Entries)
44270b57cec5SDimitry Andric     E.dump();
44280b57cec5SDimitry Andric 
44290b57cec5SDimitry Andric   errs() << "}\n";
44300b57cec5SDimitry Andric }
44310b57cec5SDimitry Andric 
dump() const44320b57cec5SDimitry Andric LLVM_DUMP_METHOD void MultiClass::dump() const {
44330b57cec5SDimitry Andric   errs() << "Record:\n";
44340b57cec5SDimitry Andric   Rec.dump();
44350b57cec5SDimitry Andric 
44360b57cec5SDimitry Andric   errs() << "Defs:\n";
44370b57cec5SDimitry Andric   for (const auto &E : Entries)
44380b57cec5SDimitry Andric     E.dump();
44390b57cec5SDimitry Andric }
44400b57cec5SDimitry Andric #endif
44415f757f3fSDimitry Andric 
ParseDump(MultiClass * CurMultiClass,Record * CurRec)44425f757f3fSDimitry Andric bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {
44435f757f3fSDimitry Andric   // Location of the `dump` statement.
44445f757f3fSDimitry Andric   SMLoc Loc = Lex.getLoc();
44455f757f3fSDimitry Andric   assert(Lex.getCode() == tgtok::Dump && "Unknown tok");
44465f757f3fSDimitry Andric   Lex.Lex(); // eat the operation
44475f757f3fSDimitry Andric 
44485f757f3fSDimitry Andric   Init *Message = ParseValue(CurRec);
44495f757f3fSDimitry Andric   if (!Message)
44505f757f3fSDimitry Andric     return true;
44515f757f3fSDimitry Andric 
44525f757f3fSDimitry Andric   // Allow to use dump directly on `defvar` and `def`, by wrapping
44535f757f3fSDimitry Andric   // them with a `!repl`.
44545f757f3fSDimitry Andric   if (isa<DefInit>(Message))
44555f757f3fSDimitry Andric     Message = UnOpInit::get(UnOpInit::REPR, Message, StringRecTy::get(Records))
44565f757f3fSDimitry Andric                   ->Fold(CurRec);
44575f757f3fSDimitry Andric 
44585f757f3fSDimitry Andric   if (!consume(tgtok::semi))
44595f757f3fSDimitry Andric     return TokError("expected ';'");
44605f757f3fSDimitry Andric 
44615f757f3fSDimitry Andric   if (CurRec)
44625f757f3fSDimitry Andric     CurRec->addDump(Loc, Message);
44635f757f3fSDimitry Andric   else
44645f757f3fSDimitry Andric     addEntry(std::make_unique<Record::DumpInfo>(Loc, Message));
44655f757f3fSDimitry Andric 
44665f757f3fSDimitry Andric   return false;
44675f757f3fSDimitry Andric }
4468