1226584Sdim//===- TGParser.cpp - Parser for TableGen Files ---------------------------===// 2226584Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6226584Sdim// 7226584Sdim//===----------------------------------------------------------------------===// 8226584Sdim// 9226584Sdim// Implement the Parser for TableGen. 10226584Sdim// 11226584Sdim//===----------------------------------------------------------------------===// 12226584Sdim 13226584Sdim#include "TGParser.h" 14314564Sdim#include "llvm/ADT/None.h" 15288943Sdim#include "llvm/ADT/STLExtras.h" 16249423Sdim#include "llvm/ADT/SmallVector.h" 17249423Sdim#include "llvm/ADT/StringExtras.h" 18341825Sdim#include "llvm/Config/llvm-config.h" 19314564Sdim#include "llvm/Support/Casting.h" 20314564Sdim#include "llvm/Support/Compiler.h" 21314564Sdim#include "llvm/Support/ErrorHandling.h" 22314564Sdim#include "llvm/Support/raw_ostream.h" 23226584Sdim#include "llvm/TableGen/Record.h" 24226584Sdim#include <algorithm> 25314564Sdim#include <cassert> 26314564Sdim#include <cstdint> 27314564Sdim 28226584Sdimusing namespace llvm; 29226584Sdim 30226584Sdim//===----------------------------------------------------------------------===// 31226584Sdim// Support Code for the Semantic Actions. 32226584Sdim//===----------------------------------------------------------------------===// 33226584Sdim 34226584Sdimnamespace llvm { 35314564Sdim 36226584Sdimstruct SubClassReference { 37249423Sdim SMRange RefRange; 38226584Sdim Record *Rec; 39314564Sdim SmallVector<Init*, 4> TemplateArgs; 40314564Sdim 41276479Sdim SubClassReference() : Rec(nullptr) {} 42226584Sdim 43276479Sdim bool isInvalid() const { return Rec == nullptr; } 44226584Sdim}; 45226584Sdim 46226584Sdimstruct SubMultiClassReference { 47249423Sdim SMRange RefRange; 48226584Sdim MultiClass *MC; 49314564Sdim SmallVector<Init*, 4> TemplateArgs; 50314564Sdim 51276479Sdim SubMultiClassReference() : MC(nullptr) {} 52226584Sdim 53276479Sdim bool isInvalid() const { return MC == nullptr; } 54226584Sdim void dump() const; 55226584Sdim}; 56226584Sdim 57321369Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 58309124SdimLLVM_DUMP_METHOD void SubMultiClassReference::dump() const { 59226584Sdim errs() << "Multiclass:\n"; 60226584Sdim 61226584Sdim MC->dump(); 62226584Sdim 63226584Sdim errs() << "Template args:\n"; 64288943Sdim for (Init *TA : TemplateArgs) 65288943Sdim TA->dump(); 66226584Sdim} 67321369Sdim#endif 68226584Sdim 69226584Sdim} // end namespace llvm 70226584Sdim 71341825Sdimstatic bool checkBitsConcrete(Record &R, const RecordVal &RV) { 72341825Sdim BitsInit *BV = cast<BitsInit>(RV.getValue()); 73341825Sdim for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) { 74341825Sdim Init *Bit = BV->getBit(i); 75341825Sdim bool IsReference = false; 76341825Sdim if (auto VBI = dyn_cast<VarBitInit>(Bit)) { 77341825Sdim if (auto VI = dyn_cast<VarInit>(VBI->getBitVar())) { 78341825Sdim if (R.getValue(VI->getName())) 79341825Sdim IsReference = true; 80341825Sdim } 81341825Sdim } else if (isa<VarInit>(Bit)) { 82341825Sdim IsReference = true; 83341825Sdim } 84341825Sdim if (!(IsReference || Bit->isConcrete())) 85341825Sdim return false; 86341825Sdim } 87341825Sdim return true; 88341825Sdim} 89341825Sdim 90341825Sdimstatic void checkConcrete(Record &R) { 91341825Sdim for (const RecordVal &RV : R.getValues()) { 92341825Sdim // HACK: Disable this check for variables declared with 'field'. This is 93341825Sdim // done merely because existing targets have legitimate cases of 94341825Sdim // non-concrete variables in helper defs. Ideally, we'd introduce a 95341825Sdim // 'maybe' or 'optional' modifier instead of this. 96341825Sdim if (RV.getPrefix()) 97341825Sdim continue; 98341825Sdim 99341825Sdim if (Init *V = RV.getValue()) { 100341825Sdim bool Ok = isa<BitsInit>(V) ? checkBitsConcrete(R, RV) : V->isConcrete(); 101341825Sdim if (!Ok) { 102341825Sdim PrintError(R.getLoc(), 103341825Sdim Twine("Initializer of '") + RV.getNameInitAsString() + 104341825Sdim "' in '" + R.getNameInitAsString() + 105341825Sdim "' could not be fully resolved: " + 106341825Sdim RV.getValue()->getAsString()); 107341825Sdim } 108341825Sdim } 109341825Sdim } 110341825Sdim} 111341825Sdim 112341825Sdim/// Return an Init with a qualifier prefix referring 113341825Sdim/// to CurRec's name. 114341825Sdimstatic Init *QualifyName(Record &CurRec, MultiClass *CurMultiClass, 115341825Sdim Init *Name, StringRef Scoper) { 116341825Sdim Init *NewName = 117341825Sdim BinOpInit::getStrConcat(CurRec.getNameInit(), StringInit::get(Scoper)); 118341825Sdim NewName = BinOpInit::getStrConcat(NewName, Name); 119341825Sdim if (CurMultiClass && Scoper != "::") { 120341825Sdim Init *Prefix = BinOpInit::getStrConcat(CurMultiClass->Rec.getNameInit(), 121341825Sdim StringInit::get("::")); 122341825Sdim NewName = BinOpInit::getStrConcat(Prefix, NewName); 123341825Sdim } 124341825Sdim 125341825Sdim if (BinOpInit *BinOp = dyn_cast<BinOpInit>(NewName)) 126341825Sdim NewName = BinOp->Fold(&CurRec); 127341825Sdim return NewName; 128341825Sdim} 129341825Sdim 130341825Sdim/// Return the qualified version of the implicit 'NAME' template argument. 131341825Sdimstatic Init *QualifiedNameOfImplicitName(Record &Rec, 132341825Sdim MultiClass *MC = nullptr) { 133341825Sdim return QualifyName(Rec, MC, StringInit::get("NAME"), MC ? "::" : ":"); 134341825Sdim} 135341825Sdim 136341825Sdimstatic Init *QualifiedNameOfImplicitName(MultiClass *MC) { 137341825Sdim return QualifiedNameOfImplicitName(MC->Rec, MC); 138341825Sdim} 139341825Sdim 140226584Sdimbool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) { 141276479Sdim if (!CurRec) 142226584Sdim CurRec = &CurMultiClass->Rec; 143226584Sdim 144234353Sdim if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) { 145226584Sdim // The value already exists in the class, treat this as a set. 146226584Sdim if (ERV->setValue(RV.getValue())) 147226584Sdim return Error(Loc, "New definition of '" + RV.getName() + "' of type '" + 148226584Sdim RV.getType()->getAsString() + "' is incompatible with " + 149226584Sdim "previous definition of type '" + 150226584Sdim ERV->getType()->getAsString() + "'"); 151226584Sdim } else { 152226584Sdim CurRec->addValue(RV); 153226584Sdim } 154226584Sdim return false; 155226584Sdim} 156226584Sdim 157226584Sdim/// SetValue - 158226584Sdim/// Return true on error, false on success. 159234353Sdimbool TGParser::SetValue(Record *CurRec, SMLoc Loc, Init *ValName, 160296417Sdim ArrayRef<unsigned> BitList, Init *V, 161296417Sdim bool AllowSelfAssignment) { 162226584Sdim if (!V) return false; 163226584Sdim 164276479Sdim if (!CurRec) CurRec = &CurMultiClass->Rec; 165226584Sdim 166226584Sdim RecordVal *RV = CurRec->getValue(ValName); 167276479Sdim if (!RV) 168288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 169288943Sdim "' unknown!"); 170226584Sdim 171226584Sdim // Do not allow assignments like 'X = X'. This will just cause infinite loops 172226584Sdim // in the resolution machinery. 173226584Sdim if (BitList.empty()) 174243830Sdim if (VarInit *VI = dyn_cast<VarInit>(V)) 175296417Sdim if (VI->getNameInit() == ValName && !AllowSelfAssignment) 176341825Sdim return Error(Loc, "Recursion / self-assignment forbidden"); 177226584Sdim 178226584Sdim // If we are assigning to a subset of the bits in the value... then we must be 179226584Sdim // assigning to a field of BitsRecTy, which must have a BitsInit 180226584Sdim // initializer. 181226584Sdim // 182226584Sdim if (!BitList.empty()) { 183243830Sdim BitsInit *CurVal = dyn_cast<BitsInit>(RV->getValue()); 184276479Sdim if (!CurVal) 185288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 186288943Sdim "' is not a bits type"); 187226584Sdim 188226584Sdim // Convert the incoming value to a bits type of the appropriate size... 189341825Sdim Init *BI = V->getCastTo(BitsRecTy::get(BitList.size())); 190288943Sdim if (!BI) 191226584Sdim return Error(Loc, "Initializer is not compatible with bit range"); 192226584Sdim 193226584Sdim SmallVector<Init *, 16> NewBits(CurVal->getNumBits()); 194226584Sdim 195226584Sdim // Loop over bits, assigning values as appropriate. 196226584Sdim for (unsigned i = 0, e = BitList.size(); i != e; ++i) { 197226584Sdim unsigned Bit = BitList[i]; 198226584Sdim if (NewBits[Bit]) 199288943Sdim return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" + 200234353Sdim ValName->getAsUnquotedString() + "' more than once"); 201341825Sdim NewBits[Bit] = BI->getBit(i); 202226584Sdim } 203226584Sdim 204226584Sdim for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) 205276479Sdim if (!NewBits[i]) 206226584Sdim NewBits[i] = CurVal->getBit(i); 207226584Sdim 208226584Sdim V = BitsInit::get(NewBits); 209226584Sdim } 210226584Sdim 211280031Sdim if (RV->setValue(V)) { 212314564Sdim std::string InitType; 213288943Sdim if (BitsInit *BI = dyn_cast<BitsInit>(V)) 214280031Sdim InitType = (Twine("' of type bit initializer with length ") + 215280031Sdim Twine(BI->getNumBits())).str(); 216341825Sdim else if (TypedInit *TI = dyn_cast<TypedInit>(V)) 217341825Sdim InitType = (Twine("' of type '") + TI->getType()->getAsString()).str(); 218288943Sdim return Error(Loc, "Value '" + ValName->getAsUnquotedString() + 219341825Sdim "' of type '" + RV->getType()->getAsString() + 220341825Sdim "' is incompatible with initializer '" + 221341825Sdim V->getAsString() + InitType + "'"); 222280031Sdim } 223226584Sdim return false; 224226584Sdim} 225226584Sdim 226226584Sdim/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template 227226584Sdim/// args as SubClass's template arguments. 228226584Sdimbool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) { 229226584Sdim Record *SC = SubClass.Rec; 230226584Sdim // Add all of the values in the subclass into the current class. 231288943Sdim for (const RecordVal &Val : SC->getValues()) 232288943Sdim if (AddValue(CurRec, SubClass.RefRange.Start, Val)) 233226584Sdim return true; 234226584Sdim 235296417Sdim ArrayRef<Init *> TArgs = SC->getTemplateArgs(); 236226584Sdim 237226584Sdim // Ensure that an appropriate number of template arguments are specified. 238226584Sdim if (TArgs.size() < SubClass.TemplateArgs.size()) 239249423Sdim return Error(SubClass.RefRange.Start, 240249423Sdim "More template args specified than expected"); 241226584Sdim 242226584Sdim // Loop over all of the template arguments, setting them to the specified 243226584Sdim // value or leaving them as the default if necessary. 244341825Sdim MapResolver R(CurRec); 245341825Sdim 246226584Sdim for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { 247226584Sdim if (i < SubClass.TemplateArgs.size()) { 248226584Sdim // If a value is specified for this template arg, set it now. 249249423Sdim if (SetValue(CurRec, SubClass.RefRange.Start, TArgs[i], 250296417Sdim None, SubClass.TemplateArgs[i])) 251226584Sdim return true; 252226584Sdim } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { 253249423Sdim return Error(SubClass.RefRange.Start, 254288943Sdim "Value not specified for template argument #" + 255288943Sdim Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + 256288943Sdim ") of subclass '" + SC->getNameInitAsString() + "'!"); 257226584Sdim } 258341825Sdim 259341825Sdim R.set(TArgs[i], CurRec->getValue(TArgs[i])->getValue()); 260341825Sdim 261341825Sdim CurRec->removeValue(TArgs[i]); 262226584Sdim } 263226584Sdim 264341825Sdim Init *Name; 265341825Sdim if (CurRec->isClass()) 266341825Sdim Name = 267341825Sdim VarInit::get(QualifiedNameOfImplicitName(*CurRec), StringRecTy::get()); 268341825Sdim else 269341825Sdim Name = CurRec->getNameInit(); 270341825Sdim R.set(QualifiedNameOfImplicitName(*SC), Name); 271341825Sdim 272341825Sdim CurRec->resolveReferences(R); 273341825Sdim 274226584Sdim // Since everything went well, we can now set the "superclass" list for the 275226584Sdim // current record. 276309124Sdim ArrayRef<std::pair<Record *, SMRange>> SCs = SC->getSuperClasses(); 277309124Sdim for (const auto &SCPair : SCs) { 278309124Sdim if (CurRec->isSubClassOf(SCPair.first)) 279249423Sdim return Error(SubClass.RefRange.Start, 280309124Sdim "Already subclass of '" + SCPair.first->getName() + "'!\n"); 281309124Sdim CurRec->addSuperClass(SCPair.first, SCPair.second); 282226584Sdim } 283226584Sdim 284226584Sdim if (CurRec->isSubClassOf(SC)) 285249423Sdim return Error(SubClass.RefRange.Start, 286226584Sdim "Already subclass of '" + SC->getName() + "'!\n"); 287249423Sdim CurRec->addSuperClass(SC, SubClass.RefRange); 288226584Sdim return false; 289226584Sdim} 290226584Sdim 291341825Sdimbool TGParser::AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass) { 292341825Sdim if (Entry.Rec) 293341825Sdim return AddSubClass(Entry.Rec.get(), SubClass); 294341825Sdim 295341825Sdim for (auto &E : Entry.Loop->Entries) { 296341825Sdim if (AddSubClass(E, SubClass)) 297341825Sdim return true; 298341825Sdim } 299341825Sdim 300341825Sdim return false; 301341825Sdim} 302341825Sdim 303226584Sdim/// AddSubMultiClass - Add SubMultiClass as a subclass to 304226584Sdim/// CurMC, resolving its template args as SubMultiClass's 305226584Sdim/// template arguments. 306226584Sdimbool TGParser::AddSubMultiClass(MultiClass *CurMC, 307226584Sdim SubMultiClassReference &SubMultiClass) { 308226584Sdim MultiClass *SMC = SubMultiClass.MC; 309226584Sdim 310296417Sdim ArrayRef<Init *> SMCTArgs = SMC->Rec.getTemplateArgs(); 311226584Sdim if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size()) 312249423Sdim return Error(SubMultiClass.RefRange.Start, 313226584Sdim "More template args specified than expected"); 314226584Sdim 315341825Sdim // Prepare the mapping of template argument name to value, filling in default 316341825Sdim // values if necessary. 317341825Sdim SubstStack TemplateArgs; 318226584Sdim for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) { 319226584Sdim if (i < SubMultiClass.TemplateArgs.size()) { 320341825Sdim TemplateArgs.emplace_back(SMCTArgs[i], SubMultiClass.TemplateArgs[i]); 321341825Sdim } else { 322341825Sdim Init *Default = SMC->Rec.getValue(SMCTArgs[i])->getValue(); 323341825Sdim if (!Default->isComplete()) { 324341825Sdim return Error(SubMultiClass.RefRange.Start, 325341825Sdim "value not specified for template argument #" + Twine(i) + 326341825Sdim " (" + SMCTArgs[i]->getAsUnquotedString() + 327341825Sdim ") of multiclass '" + SMC->Rec.getNameInitAsString() + 328341825Sdim "'"); 329341825Sdim } 330341825Sdim TemplateArgs.emplace_back(SMCTArgs[i], Default); 331341825Sdim } 332341825Sdim } 333226584Sdim 334341825Sdim TemplateArgs.emplace_back( 335341825Sdim QualifiedNameOfImplicitName(SMC), 336341825Sdim VarInit::get(QualifiedNameOfImplicitName(CurMC), StringRecTy::get())); 337226584Sdim 338341825Sdim // Add all of the defs in the subclass into the current multiclass. 339341825Sdim return resolve(SMC->Entries, TemplateArgs, false, &CurMC->Entries); 340341825Sdim} 341226584Sdim 342341825Sdim/// Add a record or foreach loop to the current context (global record keeper, 343341825Sdim/// current inner-most foreach loop, or multiclass). 344341825Sdimbool TGParser::addEntry(RecordsEntry E) { 345341825Sdim assert(!E.Rec || !E.Loop); 346226584Sdim 347341825Sdim if (!Loops.empty()) { 348341825Sdim Loops.back()->Entries.push_back(std::move(E)); 349341825Sdim return false; 350341825Sdim } 351226584Sdim 352341825Sdim if (E.Loop) { 353341825Sdim SubstStack Stack; 354341825Sdim return resolve(*E.Loop, Stack, CurMultiClass == nullptr, 355341825Sdim CurMultiClass ? &CurMultiClass->Entries : nullptr); 356226584Sdim } 357226584Sdim 358341825Sdim if (CurMultiClass) { 359341825Sdim CurMultiClass->Entries.push_back(std::move(E)); 360239462Sdim return false; 361341825Sdim } 362239462Sdim 363341825Sdim return addDefOne(std::move(E.Rec)); 364234353Sdim} 365234353Sdim 366341825Sdim/// Resolve the entries in \p Loop, going over inner loops recursively 367341825Sdim/// and making the given subsitutions of (name, value) pairs. 368341825Sdim/// 369341825Sdim/// The resulting records are stored in \p Dest if non-null. Otherwise, they 370341825Sdim/// are added to the global record keeper. 371341825Sdimbool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs, 372341825Sdim bool Final, std::vector<RecordsEntry> *Dest, 373341825Sdim SMLoc *Loc) { 374341825Sdim MapResolver R; 375341825Sdim for (const auto &S : Substs) 376341825Sdim R.set(S.first, S.second); 377341825Sdim Init *List = Loop.ListValue->resolveReferences(R); 378341825Sdim auto LI = dyn_cast<ListInit>(List); 379341825Sdim if (!LI) { 380341825Sdim if (!Final) { 381360784Sdim Dest->emplace_back(std::make_unique<ForeachLoop>(Loop.Loc, Loop.IterVar, 382341825Sdim List)); 383341825Sdim return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries, 384341825Sdim Loc); 385239462Sdim } 386234353Sdim 387341825Sdim PrintError(Loop.Loc, Twine("attempting to loop over '") + 388341825Sdim List->getAsString() + "', expected a list"); 389341825Sdim return true; 390234353Sdim } 391234353Sdim 392341825Sdim bool Error = false; 393341825Sdim for (auto Elt : *LI) { 394360784Sdim if (Loop.IterVar) 395360784Sdim Substs.emplace_back(Loop.IterVar->getNameInit(), Elt); 396341825Sdim Error = resolve(Loop.Entries, Substs, Final, Dest); 397360784Sdim if (Loop.IterVar) 398360784Sdim Substs.pop_back(); 399341825Sdim if (Error) 400341825Sdim break; 401341825Sdim } 402341825Sdim return Error; 403341825Sdim} 404234353Sdim 405341825Sdim/// Resolve the entries in \p Source, going over loops recursively and 406341825Sdim/// making the given substitutions of (name, value) pairs. 407341825Sdim/// 408341825Sdim/// The resulting records are stored in \p Dest if non-null. Otherwise, they 409341825Sdim/// are added to the global record keeper. 410341825Sdimbool TGParser::resolve(const std::vector<RecordsEntry> &Source, 411341825Sdim SubstStack &Substs, bool Final, 412341825Sdim std::vector<RecordsEntry> *Dest, SMLoc *Loc) { 413341825Sdim bool Error = false; 414341825Sdim for (auto &E : Source) { 415341825Sdim if (E.Loop) { 416341825Sdim Error = resolve(*E.Loop, Substs, Final, Dest); 417341825Sdim } else { 418360784Sdim auto Rec = std::make_unique<Record>(*E.Rec); 419341825Sdim if (Loc) 420341825Sdim Rec->appendLoc(*Loc); 421234353Sdim 422341825Sdim MapResolver R(Rec.get()); 423341825Sdim for (const auto &S : Substs) 424341825Sdim R.set(S.first, S.second); 425341825Sdim Rec->resolveReferences(R); 426234353Sdim 427341825Sdim if (Dest) 428341825Sdim Dest->push_back(std::move(Rec)); 429341825Sdim else 430341825Sdim Error = addDefOne(std::move(Rec)); 431341825Sdim } 432341825Sdim if (Error) 433341825Sdim break; 434341825Sdim } 435341825Sdim return Error; 436341825Sdim} 437234353Sdim 438341825Sdim/// Resolve the record fully and add it to the record keeper. 439341825Sdimbool TGParser::addDefOne(std::unique_ptr<Record> Rec) { 440341825Sdim if (Record *Prev = Records.getDef(Rec->getNameInitAsString())) { 441341825Sdim if (!Rec->isAnonymous()) { 442341825Sdim PrintError(Rec->getLoc(), 443341825Sdim "def already exists: " + Rec->getNameInitAsString()); 444341825Sdim PrintNote(Prev->getLoc(), "location of previous definition"); 445341825Sdim return true; 446341825Sdim } 447341825Sdim Rec->setName(Records.getNewAnonymousName()); 448341825Sdim } 449234353Sdim 450341825Sdim Rec->resolveReferences(); 451341825Sdim checkConcrete(*Rec); 452341825Sdim 453341825Sdim if (!isa<StringInit>(Rec->getNameInit())) { 454341825Sdim PrintError(Rec->getLoc(), Twine("record name '") + 455341825Sdim Rec->getNameInit()->getAsString() + 456341825Sdim "' could not be fully resolved"); 457341825Sdim return true; 458239462Sdim } 459234353Sdim 460341825Sdim // If ObjectBody has template arguments, it's an error. 461341825Sdim assert(Rec->getTemplateArgs().empty() && "How'd this get template args?"); 462280031Sdim 463341825Sdim for (DefsetRecord *Defset : Defsets) { 464341825Sdim DefInit *I = Rec->getDefInit(); 465341825Sdim if (!I->getType()->typeIsA(Defset->EltTy)) { 466341825Sdim PrintError(Rec->getLoc(), Twine("adding record of incompatible type '") + 467341825Sdim I->getType()->getAsString() + 468341825Sdim "' to defset"); 469341825Sdim PrintNote(Defset->Loc, "location of defset declaration"); 470341825Sdim return true; 471341825Sdim } 472341825Sdim Defset->Elements.push_back(I); 473239462Sdim } 474234353Sdim 475341825Sdim Records.addDef(std::move(Rec)); 476234353Sdim return false; 477234353Sdim} 478234353Sdim 479226584Sdim//===----------------------------------------------------------------------===// 480226584Sdim// Parser Code 481226584Sdim//===----------------------------------------------------------------------===// 482226584Sdim 483226584Sdim/// isObjectStart - Return true if this is a valid first token for an Object. 484226584Sdimstatic bool isObjectStart(tgtok::TokKind K) { 485341825Sdim return K == tgtok::Class || K == tgtok::Def || K == tgtok::Defm || 486341825Sdim K == tgtok::Let || K == tgtok::MultiClass || K == tgtok::Foreach || 487360784Sdim K == tgtok::Defset || K == tgtok::Defvar || K == tgtok::If; 488226584Sdim} 489226584Sdim 490341825Sdim/// ParseObjectName - If a valid object name is specified, return it. If no 491341825Sdim/// name is specified, return the unset initializer. Return nullptr on parse 492341825Sdim/// error. 493234353Sdim/// ObjectName ::= Value [ '#' Value ]* 494226584Sdim/// ObjectName ::= /*empty*/ 495226584Sdim/// 496234353SdimInit *TGParser::ParseObjectName(MultiClass *CurMultiClass) { 497234353Sdim switch (Lex.getCode()) { 498234353Sdim case tgtok::colon: 499234353Sdim case tgtok::semi: 500234353Sdim case tgtok::l_brace: 501234353Sdim // These are all of the tokens that can begin an object body. 502234353Sdim // Some of these can also begin values but we disallow those cases 503234353Sdim // because they are unlikely to be useful. 504341825Sdim return UnsetInit::get(); 505234353Sdim default: 506234353Sdim break; 507234353Sdim } 508226584Sdim 509276479Sdim Record *CurRec = nullptr; 510234353Sdim if (CurMultiClass) 511234353Sdim CurRec = &CurMultiClass->Rec; 512234353Sdim 513341825Sdim Init *Name = ParseValue(CurRec, StringRecTy::get(), ParseNameMode); 514341825Sdim if (!Name) 515341825Sdim return nullptr; 516341825Sdim 517341825Sdim if (CurMultiClass) { 518341825Sdim Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass); 519341825Sdim HasReferenceResolver R(NameStr); 520341825Sdim Name->resolveReferences(R); 521341825Sdim if (!R.found()) 522341825Sdim Name = BinOpInit::getStrConcat(VarInit::get(NameStr, StringRecTy::get()), 523341825Sdim Name); 524234353Sdim } 525234353Sdim 526341825Sdim return Name; 527226584Sdim} 528226584Sdim 529226584Sdim/// ParseClassID - Parse and resolve a reference to a class name. This returns 530226584Sdim/// null on error. 531226584Sdim/// 532226584Sdim/// ClassID ::= ID 533226584Sdim/// 534226584SdimRecord *TGParser::ParseClassID() { 535226584Sdim if (Lex.getCode() != tgtok::Id) { 536226584Sdim TokError("expected name for ClassID"); 537276479Sdim return nullptr; 538226584Sdim } 539226584Sdim 540226584Sdim Record *Result = Records.getClass(Lex.getCurStrVal()); 541353358Sdim if (!Result) { 542353358Sdim std::string Msg("Couldn't find class '" + Lex.getCurStrVal() + "'"); 543353358Sdim if (MultiClasses[Lex.getCurStrVal()].get()) 544353358Sdim TokError(Msg + ". Use 'defm' if you meant to use multiclass '" + 545353358Sdim Lex.getCurStrVal() + "'"); 546353358Sdim else 547353358Sdim TokError(Msg); 548353358Sdim } 549226584Sdim 550226584Sdim Lex.Lex(); 551226584Sdim return Result; 552226584Sdim} 553226584Sdim 554226584Sdim/// ParseMultiClassID - Parse and resolve a reference to a multiclass name. 555226584Sdim/// This returns null on error. 556226584Sdim/// 557226584Sdim/// MultiClassID ::= ID 558226584Sdim/// 559226584SdimMultiClass *TGParser::ParseMultiClassID() { 560226584Sdim if (Lex.getCode() != tgtok::Id) { 561249423Sdim TokError("expected name for MultiClassID"); 562276479Sdim return nullptr; 563226584Sdim } 564226584Sdim 565280031Sdim MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get(); 566276479Sdim if (!Result) 567249423Sdim TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'"); 568226584Sdim 569226584Sdim Lex.Lex(); 570226584Sdim return Result; 571226584Sdim} 572226584Sdim 573226584Sdim/// ParseSubClassReference - Parse a reference to a subclass or to a templated 574226584Sdim/// subclass. This returns a SubClassRefTy with a null Record* on error. 575226584Sdim/// 576226584Sdim/// SubClassRef ::= ClassID 577226584Sdim/// SubClassRef ::= ClassID '<' ValueList '>' 578226584Sdim/// 579226584SdimSubClassReference TGParser:: 580226584SdimParseSubClassReference(Record *CurRec, bool isDefm) { 581226584Sdim SubClassReference Result; 582249423Sdim Result.RefRange.Start = Lex.getLoc(); 583226584Sdim 584249423Sdim if (isDefm) { 585249423Sdim if (MultiClass *MC = ParseMultiClassID()) 586249423Sdim Result.Rec = &MC->Rec; 587249423Sdim } else { 588226584Sdim Result.Rec = ParseClassID(); 589249423Sdim } 590276479Sdim if (!Result.Rec) return Result; 591226584Sdim 592226584Sdim // If there is no template arg list, we're done. 593249423Sdim if (Lex.getCode() != tgtok::less) { 594249423Sdim Result.RefRange.End = Lex.getLoc(); 595226584Sdim return Result; 596249423Sdim } 597226584Sdim Lex.Lex(); // Eat the '<' 598226584Sdim 599226584Sdim if (Lex.getCode() == tgtok::greater) { 600226584Sdim TokError("subclass reference requires a non-empty list of template values"); 601276479Sdim Result.Rec = nullptr; 602226584Sdim return Result; 603226584Sdim } 604226584Sdim 605314564Sdim ParseValueList(Result.TemplateArgs, CurRec, Result.Rec); 606226584Sdim if (Result.TemplateArgs.empty()) { 607276479Sdim Result.Rec = nullptr; // Error parsing value list. 608226584Sdim return Result; 609226584Sdim } 610226584Sdim 611226584Sdim if (Lex.getCode() != tgtok::greater) { 612226584Sdim TokError("expected '>' in template value list"); 613276479Sdim Result.Rec = nullptr; 614226584Sdim return Result; 615226584Sdim } 616226584Sdim Lex.Lex(); 617249423Sdim Result.RefRange.End = Lex.getLoc(); 618226584Sdim 619226584Sdim return Result; 620226584Sdim} 621226584Sdim 622226584Sdim/// ParseSubMultiClassReference - Parse a reference to a subclass or to a 623226584Sdim/// templated submulticlass. This returns a SubMultiClassRefTy with a null 624226584Sdim/// Record* on error. 625226584Sdim/// 626226584Sdim/// SubMultiClassRef ::= MultiClassID 627226584Sdim/// SubMultiClassRef ::= MultiClassID '<' ValueList '>' 628226584Sdim/// 629226584SdimSubMultiClassReference TGParser:: 630226584SdimParseSubMultiClassReference(MultiClass *CurMC) { 631226584Sdim SubMultiClassReference Result; 632249423Sdim Result.RefRange.Start = Lex.getLoc(); 633226584Sdim 634226584Sdim Result.MC = ParseMultiClassID(); 635276479Sdim if (!Result.MC) return Result; 636226584Sdim 637226584Sdim // If there is no template arg list, we're done. 638249423Sdim if (Lex.getCode() != tgtok::less) { 639249423Sdim Result.RefRange.End = Lex.getLoc(); 640226584Sdim return Result; 641249423Sdim } 642226584Sdim Lex.Lex(); // Eat the '<' 643226584Sdim 644226584Sdim if (Lex.getCode() == tgtok::greater) { 645226584Sdim TokError("subclass reference requires a non-empty list of template values"); 646276479Sdim Result.MC = nullptr; 647226584Sdim return Result; 648226584Sdim } 649226584Sdim 650314564Sdim ParseValueList(Result.TemplateArgs, &CurMC->Rec, &Result.MC->Rec); 651226584Sdim if (Result.TemplateArgs.empty()) { 652276479Sdim Result.MC = nullptr; // Error parsing value list. 653226584Sdim return Result; 654226584Sdim } 655226584Sdim 656226584Sdim if (Lex.getCode() != tgtok::greater) { 657226584Sdim TokError("expected '>' in template value list"); 658276479Sdim Result.MC = nullptr; 659226584Sdim return Result; 660226584Sdim } 661226584Sdim Lex.Lex(); 662249423Sdim Result.RefRange.End = Lex.getLoc(); 663226584Sdim 664226584Sdim return Result; 665226584Sdim} 666226584Sdim 667226584Sdim/// ParseRangePiece - Parse a bit/value range. 668226584Sdim/// RangePiece ::= INTVAL 669226584Sdim/// RangePiece ::= INTVAL '-' INTVAL 670226584Sdim/// RangePiece ::= INTVAL INTVAL 671353358Sdimbool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges, 672353358Sdim TypedInit *FirstItem) { 673353358Sdim Init *CurVal = FirstItem; 674353358Sdim if (!CurVal) 675353358Sdim CurVal = ParseValue(nullptr); 676353358Sdim 677353358Sdim IntInit *II = dyn_cast_or_null<IntInit>(CurVal); 678353358Sdim if (!II) 679353358Sdim return TokError("expected integer or bitrange"); 680353358Sdim 681353358Sdim int64_t Start = II->getValue(); 682226584Sdim int64_t End; 683226584Sdim 684226584Sdim if (Start < 0) 685226584Sdim return TokError("invalid range, cannot be negative"); 686226584Sdim 687353358Sdim switch (Lex.getCode()) { 688226584Sdim default: 689226584Sdim Ranges.push_back(Start); 690226584Sdim return false; 691353358Sdim case tgtok::minus: { 692353358Sdim Lex.Lex(); // eat 693353358Sdim 694353358Sdim Init *I_End = ParseValue(nullptr); 695353358Sdim IntInit *II_End = dyn_cast_or_null<IntInit>(I_End); 696353358Sdim if (!II_End) { 697226584Sdim TokError("expected integer value as end of range"); 698226584Sdim return true; 699226584Sdim } 700353358Sdim 701353358Sdim End = II_End->getValue(); 702226584Sdim break; 703353358Sdim } 704353358Sdim case tgtok::IntVal: { 705226584Sdim End = -Lex.getCurIntVal(); 706353358Sdim Lex.Lex(); 707226584Sdim break; 708226584Sdim } 709353358Sdim } 710226584Sdim if (End < 0) 711226584Sdim return TokError("invalid range, cannot be negative"); 712226584Sdim 713226584Sdim // Add to the range. 714288943Sdim if (Start < End) 715226584Sdim for (; Start <= End; ++Start) 716226584Sdim Ranges.push_back(Start); 717288943Sdim else 718226584Sdim for (; Start >= End; --Start) 719226584Sdim Ranges.push_back(Start); 720226584Sdim return false; 721226584Sdim} 722226584Sdim 723226584Sdim/// ParseRangeList - Parse a list of scalars and ranges into scalar values. 724226584Sdim/// 725226584Sdim/// RangeList ::= RangePiece (',' RangePiece)* 726226584Sdim/// 727314564Sdimvoid TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) { 728226584Sdim // Parse the first piece. 729314564Sdim if (ParseRangePiece(Result)) { 730314564Sdim Result.clear(); 731314564Sdim return; 732314564Sdim } 733226584Sdim while (Lex.getCode() == tgtok::comma) { 734226584Sdim Lex.Lex(); // Eat the comma. 735226584Sdim 736226584Sdim // Parse the next range piece. 737314564Sdim if (ParseRangePiece(Result)) { 738314564Sdim Result.clear(); 739314564Sdim return; 740314564Sdim } 741226584Sdim } 742226584Sdim} 743226584Sdim 744226584Sdim/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing. 745226584Sdim/// OptionalRangeList ::= '<' RangeList '>' 746226584Sdim/// OptionalRangeList ::= /*empty*/ 747314564Sdimbool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) { 748226584Sdim if (Lex.getCode() != tgtok::less) 749226584Sdim return false; 750226584Sdim 751226584Sdim SMLoc StartLoc = Lex.getLoc(); 752226584Sdim Lex.Lex(); // eat the '<' 753226584Sdim 754226584Sdim // Parse the range list. 755314564Sdim ParseRangeList(Ranges); 756226584Sdim if (Ranges.empty()) return true; 757226584Sdim 758226584Sdim if (Lex.getCode() != tgtok::greater) { 759226584Sdim TokError("expected '>' at end of range list"); 760226584Sdim return Error(StartLoc, "to match this '<'"); 761226584Sdim } 762226584Sdim Lex.Lex(); // eat the '>'. 763226584Sdim return false; 764226584Sdim} 765226584Sdim 766226584Sdim/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing. 767226584Sdim/// OptionalBitList ::= '{' RangeList '}' 768226584Sdim/// OptionalBitList ::= /*empty*/ 769314564Sdimbool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) { 770226584Sdim if (Lex.getCode() != tgtok::l_brace) 771226584Sdim return false; 772226584Sdim 773226584Sdim SMLoc StartLoc = Lex.getLoc(); 774226584Sdim Lex.Lex(); // eat the '{' 775226584Sdim 776226584Sdim // Parse the range list. 777314564Sdim ParseRangeList(Ranges); 778226584Sdim if (Ranges.empty()) return true; 779226584Sdim 780226584Sdim if (Lex.getCode() != tgtok::r_brace) { 781226584Sdim TokError("expected '}' at end of bit list"); 782226584Sdim return Error(StartLoc, "to match this '{'"); 783226584Sdim } 784226584Sdim Lex.Lex(); // eat the '}'. 785226584Sdim return false; 786226584Sdim} 787226584Sdim 788226584Sdim/// ParseType - Parse and return a tblgen type. This returns null on error. 789226584Sdim/// 790226584Sdim/// Type ::= STRING // string type 791234353Sdim/// Type ::= CODE // code type 792226584Sdim/// Type ::= BIT // bit type 793226584Sdim/// Type ::= BITS '<' INTVAL '>' // bits<x> type 794226584Sdim/// Type ::= INT // int type 795226584Sdim/// Type ::= LIST '<' Type '>' // list<x> type 796226584Sdim/// Type ::= DAG // dag type 797226584Sdim/// Type ::= ClassID // Record Type 798226584Sdim/// 799226584SdimRecTy *TGParser::ParseType() { 800226584Sdim switch (Lex.getCode()) { 801276479Sdim default: TokError("Unknown token when expecting a type"); return nullptr; 802226584Sdim case tgtok::String: Lex.Lex(); return StringRecTy::get(); 803309124Sdim case tgtok::Code: Lex.Lex(); return CodeRecTy::get(); 804226584Sdim case tgtok::Bit: Lex.Lex(); return BitRecTy::get(); 805226584Sdim case tgtok::Int: Lex.Lex(); return IntRecTy::get(); 806226584Sdim case tgtok::Dag: Lex.Lex(); return DagRecTy::get(); 807226584Sdim case tgtok::Id: 808226584Sdim if (Record *R = ParseClassID()) return RecordRecTy::get(R); 809341825Sdim TokError("unknown class name"); 810276479Sdim return nullptr; 811226584Sdim case tgtok::Bits: { 812226584Sdim if (Lex.Lex() != tgtok::less) { // Eat 'bits' 813226584Sdim TokError("expected '<' after bits type"); 814276479Sdim return nullptr; 815226584Sdim } 816226584Sdim if (Lex.Lex() != tgtok::IntVal) { // Eat '<' 817226584Sdim TokError("expected integer in bits<n> type"); 818276479Sdim return nullptr; 819226584Sdim } 820226584Sdim uint64_t Val = Lex.getCurIntVal(); 821226584Sdim if (Lex.Lex() != tgtok::greater) { // Eat count. 822226584Sdim TokError("expected '>' at end of bits<n> type"); 823276479Sdim return nullptr; 824226584Sdim } 825226584Sdim Lex.Lex(); // Eat '>' 826226584Sdim return BitsRecTy::get(Val); 827226584Sdim } 828226584Sdim case tgtok::List: { 829226584Sdim if (Lex.Lex() != tgtok::less) { // Eat 'bits' 830226584Sdim TokError("expected '<' after list type"); 831276479Sdim return nullptr; 832226584Sdim } 833226584Sdim Lex.Lex(); // Eat '<' 834226584Sdim RecTy *SubType = ParseType(); 835276479Sdim if (!SubType) return nullptr; 836226584Sdim 837226584Sdim if (Lex.getCode() != tgtok::greater) { 838226584Sdim TokError("expected '>' at end of list<ty> type"); 839276479Sdim return nullptr; 840226584Sdim } 841226584Sdim Lex.Lex(); // Eat '>' 842226584Sdim return ListRecTy::get(SubType); 843226584Sdim } 844226584Sdim } 845226584Sdim} 846226584Sdim 847226584Sdim/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID 848226584Sdim/// has already been read. 849314564SdimInit *TGParser::ParseIDValue(Record *CurRec, StringInit *Name, SMLoc NameLoc, 850234353Sdim IDParseMode Mode) { 851226584Sdim if (CurRec) { 852226584Sdim if (const RecordVal *RV = CurRec->getValue(Name)) 853226584Sdim return VarInit::get(Name, RV->getType()); 854341825Sdim } 855226584Sdim 856341825Sdim if ((CurRec && CurRec->isClass()) || CurMultiClass) { 857341825Sdim Init *TemplateArgName; 858341825Sdim if (CurMultiClass) { 859341825Sdim TemplateArgName = 860341825Sdim QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::"); 861341825Sdim } else 862341825Sdim TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":"); 863234353Sdim 864341825Sdim Record *TemplateRec = CurMultiClass ? &CurMultiClass->Rec : CurRec; 865341825Sdim if (TemplateRec->isTemplateArg(TemplateArgName)) { 866341825Sdim const RecordVal *RV = TemplateRec->getValue(TemplateArgName); 867226584Sdim assert(RV && "Template arg doesn't exist??"); 868226584Sdim return VarInit::get(TemplateArgName, RV->getType()); 869341825Sdim } else if (Name->getValue() == "NAME") { 870341825Sdim return VarInit::get(TemplateArgName, StringRecTy::get()); 871226584Sdim } 872226584Sdim } 873226584Sdim 874360784Sdim if (CurLocalScope) 875360784Sdim if (Init *I = CurLocalScope->getVar(Name->getValue())) 876360784Sdim return I; 877360784Sdim 878234353Sdim // If this is in a foreach loop, make sure it's not a loop iterator 879288943Sdim for (const auto &L : Loops) { 880360784Sdim if (L->IterVar) { 881360784Sdim VarInit *IterVar = dyn_cast<VarInit>(L->IterVar); 882360784Sdim if (IterVar && IterVar->getNameInit() == Name) 883360784Sdim return IterVar; 884360784Sdim } 885234353Sdim } 886234353Sdim 887234353Sdim if (Mode == ParseNameMode) 888314564Sdim return Name; 889234353Sdim 890341825Sdim if (Init *I = Records.getGlobal(Name->getValue())) 891341825Sdim return I; 892226584Sdim 893341825Sdim // Allow self-references of concrete defs, but delay the lookup so that we 894341825Sdim // get the correct type. 895341825Sdim if (CurRec && !CurRec->isClass() && !CurMultiClass && 896341825Sdim CurRec->getNameInit() == Name) 897341825Sdim return UnOpInit::get(UnOpInit::CAST, Name, CurRec->getType()); 898288943Sdim 899341825Sdim Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'"); 900341825Sdim return nullptr; 901226584Sdim} 902226584Sdim 903226584Sdim/// ParseOperation - Parse an operator. This returns null on error. 904226584Sdim/// 905226584Sdim/// Operation ::= XOperator ['<' Type '>'] '(' Args ')' 906226584Sdim/// 907276479SdimInit *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) { 908226584Sdim switch (Lex.getCode()) { 909226584Sdim default: 910226584Sdim TokError("unknown operation"); 911276479Sdim return nullptr; 912226584Sdim case tgtok::XHead: 913226584Sdim case tgtok::XTail: 914341825Sdim case tgtok::XSize: 915226584Sdim case tgtok::XEmpty: 916360784Sdim case tgtok::XCast: 917360784Sdim case tgtok::XGetOp: { // Value ::= !unop '(' Value ')' 918226584Sdim UnOpInit::UnaryOp Code; 919276479Sdim RecTy *Type = nullptr; 920226584Sdim 921226584Sdim switch (Lex.getCode()) { 922234353Sdim default: llvm_unreachable("Unhandled code!"); 923226584Sdim case tgtok::XCast: 924226584Sdim Lex.Lex(); // eat the operation 925226584Sdim Code = UnOpInit::CAST; 926226584Sdim 927226584Sdim Type = ParseOperatorType(); 928226584Sdim 929276479Sdim if (!Type) { 930226584Sdim TokError("did not get type for unary operator"); 931276479Sdim return nullptr; 932226584Sdim } 933226584Sdim 934226584Sdim break; 935226584Sdim case tgtok::XHead: 936226584Sdim Lex.Lex(); // eat the operation 937226584Sdim Code = UnOpInit::HEAD; 938226584Sdim break; 939226584Sdim case tgtok::XTail: 940226584Sdim Lex.Lex(); // eat the operation 941226584Sdim Code = UnOpInit::TAIL; 942226584Sdim break; 943341825Sdim case tgtok::XSize: 944341825Sdim Lex.Lex(); 945341825Sdim Code = UnOpInit::SIZE; 946341825Sdim Type = IntRecTy::get(); 947341825Sdim break; 948226584Sdim case tgtok::XEmpty: 949226584Sdim Lex.Lex(); // eat the operation 950226584Sdim Code = UnOpInit::EMPTY; 951226584Sdim Type = IntRecTy::get(); 952226584Sdim break; 953360784Sdim case tgtok::XGetOp: 954360784Sdim Lex.Lex(); // eat the operation 955360784Sdim if (Lex.getCode() == tgtok::less) { 956360784Sdim // Parse an optional type suffix, so that you can say 957360784Sdim // !getop<BaseClass>(someDag) as a shorthand for 958360784Sdim // !cast<BaseClass>(!getop(someDag)). 959360784Sdim Type = ParseOperatorType(); 960360784Sdim 961360784Sdim if (!Type) { 962360784Sdim TokError("did not get type for unary operator"); 963360784Sdim return nullptr; 964360784Sdim } 965360784Sdim 966360784Sdim if (!isa<RecordRecTy>(Type)) { 967360784Sdim TokError("type for !getop must be a record type"); 968360784Sdim // but keep parsing, to consume the operand 969360784Sdim } 970360784Sdim } else { 971360784Sdim Type = RecordRecTy::get({}); 972360784Sdim } 973360784Sdim Code = UnOpInit::GETOP; 974360784Sdim break; 975226584Sdim } 976226584Sdim if (Lex.getCode() != tgtok::l_paren) { 977226584Sdim TokError("expected '(' after unary operator"); 978276479Sdim return nullptr; 979226584Sdim } 980226584Sdim Lex.Lex(); // eat the '(' 981226584Sdim 982226584Sdim Init *LHS = ParseValue(CurRec); 983276479Sdim if (!LHS) return nullptr; 984226584Sdim 985288943Sdim if (Code == UnOpInit::HEAD || 986288943Sdim Code == UnOpInit::TAIL || 987288943Sdim Code == UnOpInit::EMPTY) { 988243830Sdim ListInit *LHSl = dyn_cast<ListInit>(LHS); 989243830Sdim StringInit *LHSs = dyn_cast<StringInit>(LHS); 990243830Sdim TypedInit *LHSt = dyn_cast<TypedInit>(LHS); 991276479Sdim if (!LHSl && !LHSs && !LHSt) { 992226584Sdim TokError("expected list or string type argument in unary operator"); 993276479Sdim return nullptr; 994226584Sdim } 995226584Sdim if (LHSt) { 996243830Sdim ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); 997243830Sdim StringRecTy *SType = dyn_cast<StringRecTy>(LHSt->getType()); 998276479Sdim if (!LType && !SType) { 999276479Sdim TokError("expected list or string type argument in unary operator"); 1000276479Sdim return nullptr; 1001226584Sdim } 1002226584Sdim } 1003226584Sdim 1004341825Sdim if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL || 1005341825Sdim Code == UnOpInit::SIZE) { 1006276479Sdim if (!LHSl && !LHSt) { 1007276479Sdim TokError("expected list type argument in unary operator"); 1008276479Sdim return nullptr; 1009226584Sdim } 1010341825Sdim } 1011226584Sdim 1012341825Sdim if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL) { 1013288943Sdim if (LHSl && LHSl->empty()) { 1014226584Sdim TokError("empty list argument in unary operator"); 1015276479Sdim return nullptr; 1016226584Sdim } 1017226584Sdim if (LHSl) { 1018226584Sdim Init *Item = LHSl->getElement(0); 1019243830Sdim TypedInit *Itemt = dyn_cast<TypedInit>(Item); 1020276479Sdim if (!Itemt) { 1021226584Sdim TokError("untyped list element in unary operator"); 1022276479Sdim return nullptr; 1023226584Sdim } 1024288943Sdim Type = (Code == UnOpInit::HEAD) ? Itemt->getType() 1025288943Sdim : ListRecTy::get(Itemt->getType()); 1026226584Sdim } else { 1027226584Sdim assert(LHSt && "expected list type argument in unary operator"); 1028243830Sdim ListRecTy *LType = dyn_cast<ListRecTy>(LHSt->getType()); 1029276479Sdim if (!LType) { 1030276479Sdim TokError("expected list type argument in unary operator"); 1031276479Sdim return nullptr; 1032226584Sdim } 1033288943Sdim Type = (Code == UnOpInit::HEAD) ? LType->getElementType() : LType; 1034226584Sdim } 1035226584Sdim } 1036226584Sdim } 1037226584Sdim 1038226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1039226584Sdim TokError("expected ')' in unary operator"); 1040276479Sdim return nullptr; 1041226584Sdim } 1042226584Sdim Lex.Lex(); // eat the ')' 1043341825Sdim return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec); 1044226584Sdim } 1045226584Sdim 1046341825Sdim case tgtok::XIsA: { 1047341825Sdim // Value ::= !isa '<' Type '>' '(' Value ')' 1048341825Sdim Lex.Lex(); // eat the operation 1049341825Sdim 1050341825Sdim RecTy *Type = ParseOperatorType(); 1051341825Sdim if (!Type) 1052341825Sdim return nullptr; 1053341825Sdim 1054341825Sdim if (Lex.getCode() != tgtok::l_paren) { 1055341825Sdim TokError("expected '(' after type of !isa"); 1056341825Sdim return nullptr; 1057341825Sdim } 1058341825Sdim Lex.Lex(); // eat the '(' 1059341825Sdim 1060341825Sdim Init *LHS = ParseValue(CurRec); 1061341825Sdim if (!LHS) 1062341825Sdim return nullptr; 1063341825Sdim 1064341825Sdim if (Lex.getCode() != tgtok::r_paren) { 1065341825Sdim TokError("expected ')' in !isa"); 1066341825Sdim return nullptr; 1067341825Sdim } 1068341825Sdim Lex.Lex(); // eat the ')' 1069341825Sdim 1070341825Sdim return (IsAOpInit::get(Type, LHS))->Fold(); 1071341825Sdim } 1072341825Sdim 1073226584Sdim case tgtok::XConcat: 1074249423Sdim case tgtok::XADD: 1075353358Sdim case tgtok::XMUL: 1076280031Sdim case tgtok::XAND: 1077314564Sdim case tgtok::XOR: 1078226584Sdim case tgtok::XSRA: 1079226584Sdim case tgtok::XSRL: 1080226584Sdim case tgtok::XSHL: 1081226584Sdim case tgtok::XEq: 1082341825Sdim case tgtok::XNe: 1083341825Sdim case tgtok::XLe: 1084341825Sdim case tgtok::XLt: 1085341825Sdim case tgtok::XGe: 1086341825Sdim case tgtok::XGt: 1087276479Sdim case tgtok::XListConcat: 1088353358Sdim case tgtok::XListSplat: 1089360784Sdim case tgtok::XStrConcat: 1090360784Sdim case tgtok::XSetOp: { // Value ::= !binop '(' Value ',' Value ')' 1091226584Sdim tgtok::TokKind OpTok = Lex.getCode(); 1092226584Sdim SMLoc OpLoc = Lex.getLoc(); 1093226584Sdim Lex.Lex(); // eat the operation 1094226584Sdim 1095226584Sdim BinOpInit::BinaryOp Code; 1096341825Sdim switch (OpTok) { 1097341825Sdim default: llvm_unreachable("Unhandled code!"); 1098341825Sdim case tgtok::XConcat: Code = BinOpInit::CONCAT; break; 1099341825Sdim case tgtok::XADD: Code = BinOpInit::ADD; break; 1100353358Sdim case tgtok::XMUL: Code = BinOpInit::MUL; break; 1101341825Sdim case tgtok::XAND: Code = BinOpInit::AND; break; 1102341825Sdim case tgtok::XOR: Code = BinOpInit::OR; break; 1103341825Sdim case tgtok::XSRA: Code = BinOpInit::SRA; break; 1104341825Sdim case tgtok::XSRL: Code = BinOpInit::SRL; break; 1105341825Sdim case tgtok::XSHL: Code = BinOpInit::SHL; break; 1106341825Sdim case tgtok::XEq: Code = BinOpInit::EQ; break; 1107341825Sdim case tgtok::XNe: Code = BinOpInit::NE; break; 1108341825Sdim case tgtok::XLe: Code = BinOpInit::LE; break; 1109341825Sdim case tgtok::XLt: Code = BinOpInit::LT; break; 1110341825Sdim case tgtok::XGe: Code = BinOpInit::GE; break; 1111341825Sdim case tgtok::XGt: Code = BinOpInit::GT; break; 1112341825Sdim case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break; 1113353358Sdim case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break; 1114341825Sdim case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break; 1115360784Sdim case tgtok::XSetOp: Code = BinOpInit::SETOP; break; 1116341825Sdim } 1117341825Sdim 1118276479Sdim RecTy *Type = nullptr; 1119341825Sdim RecTy *ArgType = nullptr; 1120226584Sdim switch (OpTok) { 1121341825Sdim default: 1122341825Sdim llvm_unreachable("Unhandled code!"); 1123341825Sdim case tgtok::XConcat: 1124360784Sdim case tgtok::XSetOp: 1125341825Sdim Type = DagRecTy::get(); 1126341825Sdim ArgType = DagRecTy::get(); 1127341825Sdim break; 1128341825Sdim case tgtok::XAND: 1129341825Sdim case tgtok::XOR: 1130341825Sdim case tgtok::XSRA: 1131341825Sdim case tgtok::XSRL: 1132341825Sdim case tgtok::XSHL: 1133341825Sdim case tgtok::XADD: 1134353358Sdim case tgtok::XMUL: 1135341825Sdim Type = IntRecTy::get(); 1136341825Sdim ArgType = IntRecTy::get(); 1137341825Sdim break; 1138341825Sdim case tgtok::XEq: 1139341825Sdim case tgtok::XNe: 1140341825Sdim Type = BitRecTy::get(); 1141341825Sdim // ArgType for Eq / Ne is not known at this point 1142341825Sdim break; 1143341825Sdim case tgtok::XLe: 1144341825Sdim case tgtok::XLt: 1145341825Sdim case tgtok::XGe: 1146341825Sdim case tgtok::XGt: 1147341825Sdim Type = BitRecTy::get(); 1148341825Sdim ArgType = IntRecTy::get(); 1149341825Sdim break; 1150276479Sdim case tgtok::XListConcat: 1151276479Sdim // We don't know the list type until we parse the first argument 1152341825Sdim ArgType = ItemType; 1153276479Sdim break; 1154353358Sdim case tgtok::XListSplat: 1155353358Sdim // Can't do any typechecking until we parse the first argument. 1156353358Sdim break; 1157226584Sdim case tgtok::XStrConcat: 1158226584Sdim Type = StringRecTy::get(); 1159341825Sdim ArgType = StringRecTy::get(); 1160226584Sdim break; 1161226584Sdim } 1162226584Sdim 1163341825Sdim if (Type && ItemType && !Type->typeIsConvertibleTo(ItemType)) { 1164341825Sdim Error(OpLoc, Twine("expected value of type '") + 1165341825Sdim ItemType->getAsString() + "', got '" + 1166341825Sdim Type->getAsString() + "'"); 1167341825Sdim return nullptr; 1168341825Sdim } 1169341825Sdim 1170226584Sdim if (Lex.getCode() != tgtok::l_paren) { 1171226584Sdim TokError("expected '(' after binary operator"); 1172276479Sdim return nullptr; 1173226584Sdim } 1174226584Sdim Lex.Lex(); // eat the '(' 1175226584Sdim 1176226584Sdim SmallVector<Init*, 2> InitList; 1177226584Sdim 1178341825Sdim for (;;) { 1179341825Sdim SMLoc InitLoc = Lex.getLoc(); 1180341825Sdim InitList.push_back(ParseValue(CurRec, ArgType)); 1181341825Sdim if (!InitList.back()) return nullptr; 1182226584Sdim 1183360784Sdim RecTy *ListType = cast<TypedInit>(InitList.back())->getType(); 1184341825Sdim if (!ArgType) { 1185360784Sdim ArgType = ListType; 1186341825Sdim 1187341825Sdim switch (Code) { 1188341825Sdim case BinOpInit::LISTCONCAT: 1189341825Sdim if (!isa<ListRecTy>(ArgType)) { 1190341825Sdim Error(InitLoc, Twine("expected a list, got value of type '") + 1191341825Sdim ArgType->getAsString() + "'"); 1192341825Sdim return nullptr; 1193341825Sdim } 1194341825Sdim break; 1195353358Sdim case BinOpInit::LISTSPLAT: 1196353358Sdim if (ItemType && InitList.size() == 1) { 1197353358Sdim if (!isa<ListRecTy>(ItemType)) { 1198353358Sdim Error(OpLoc, 1199353358Sdim Twine("expected output type to be a list, got type '") + 1200353358Sdim ItemType->getAsString() + "'"); 1201353358Sdim return nullptr; 1202353358Sdim } 1203353358Sdim if (!ArgType->getListTy()->typeIsConvertibleTo(ItemType)) { 1204353358Sdim Error(OpLoc, Twine("expected first arg type to be '") + 1205353358Sdim ArgType->getAsString() + 1206353358Sdim "', got value of type '" + 1207353358Sdim cast<ListRecTy>(ItemType) 1208353358Sdim ->getElementType() 1209353358Sdim ->getAsString() + 1210353358Sdim "'"); 1211353358Sdim return nullptr; 1212353358Sdim } 1213353358Sdim } 1214353358Sdim if (InitList.size() == 2 && !isa<IntRecTy>(ArgType)) { 1215353358Sdim Error(InitLoc, Twine("expected second parameter to be an int, got " 1216353358Sdim "value of type '") + 1217353358Sdim ArgType->getAsString() + "'"); 1218353358Sdim return nullptr; 1219353358Sdim } 1220353358Sdim ArgType = nullptr; // Broken invariant: types not identical. 1221353358Sdim break; 1222341825Sdim case BinOpInit::EQ: 1223341825Sdim case BinOpInit::NE: 1224341825Sdim if (!ArgType->typeIsConvertibleTo(IntRecTy::get()) && 1225341825Sdim !ArgType->typeIsConvertibleTo(StringRecTy::get())) { 1226341825Sdim Error(InitLoc, Twine("expected int, bits, or string; got value of " 1227341825Sdim "type '") + ArgType->getAsString() + "'"); 1228341825Sdim return nullptr; 1229341825Sdim } 1230341825Sdim break; 1231341825Sdim default: llvm_unreachable("other ops have fixed argument types"); 1232341825Sdim } 1233341825Sdim } else { 1234360784Sdim RecTy *Resolved = resolveTypes(ArgType, ListType); 1235341825Sdim if (!Resolved) { 1236341825Sdim Error(InitLoc, Twine("expected value of type '") + 1237360784Sdim ArgType->getAsString() + "', got '" + 1238360784Sdim ListType->getAsString() + "'"); 1239341825Sdim return nullptr; 1240341825Sdim } 1241341825Sdim if (Code != BinOpInit::ADD && Code != BinOpInit::AND && 1242341825Sdim Code != BinOpInit::OR && Code != BinOpInit::SRA && 1243353358Sdim Code != BinOpInit::SRL && Code != BinOpInit::SHL && 1244353358Sdim Code != BinOpInit::MUL) 1245341825Sdim ArgType = Resolved; 1246341825Sdim } 1247341825Sdim 1248360784Sdim // Deal with BinOps whose arguments have different types, by 1249360784Sdim // rewriting ArgType in between them. 1250360784Sdim switch (Code) { 1251360784Sdim case BinOpInit::SETOP: 1252360784Sdim // After parsing the first dag argument, switch to expecting 1253360784Sdim // a record, with no restriction on its superclasses. 1254360784Sdim ArgType = RecordRecTy::get({}); 1255360784Sdim break; 1256360784Sdim default: 1257360784Sdim break; 1258360784Sdim } 1259360784Sdim 1260341825Sdim if (Lex.getCode() != tgtok::comma) 1261341825Sdim break; 1262226584Sdim Lex.Lex(); // eat the ',' 1263226584Sdim } 1264226584Sdim 1265226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1266226584Sdim TokError("expected ')' in operator"); 1267276479Sdim return nullptr; 1268226584Sdim } 1269226584Sdim Lex.Lex(); // eat the ')' 1270226584Sdim 1271353358Sdim // listconcat returns a list with type of the argument. 1272341825Sdim if (Code == BinOpInit::LISTCONCAT) 1273341825Sdim Type = ArgType; 1274353358Sdim // listsplat returns a list of type of the *first* argument. 1275353358Sdim if (Code == BinOpInit::LISTSPLAT) 1276353358Sdim Type = cast<TypedInit>(InitList.front())->getType()->getListTy(); 1277276479Sdim 1278226584Sdim // We allow multiple operands to associative operators like !strconcat as 1279226584Sdim // shorthand for nesting them. 1280341825Sdim if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT || 1281341825Sdim Code == BinOpInit::CONCAT || Code == BinOpInit::ADD || 1282353358Sdim Code == BinOpInit::AND || Code == BinOpInit::OR || 1283353358Sdim Code == BinOpInit::MUL) { 1284226584Sdim while (InitList.size() > 2) { 1285226584Sdim Init *RHS = InitList.pop_back_val(); 1286341825Sdim RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec); 1287226584Sdim InitList.back() = RHS; 1288226584Sdim } 1289226584Sdim } 1290226584Sdim 1291226584Sdim if (InitList.size() == 2) 1292226584Sdim return (BinOpInit::get(Code, InitList[0], InitList[1], Type)) 1293341825Sdim ->Fold(CurRec); 1294226584Sdim 1295226584Sdim Error(OpLoc, "expected two operands to operator"); 1296276479Sdim return nullptr; 1297226584Sdim } 1298226584Sdim 1299341825Sdim case tgtok::XForEach: { // Value ::= !foreach '(' Id ',' Value ',' Value ')' 1300341825Sdim SMLoc OpLoc = Lex.getLoc(); 1301341825Sdim Lex.Lex(); // eat the operation 1302341825Sdim if (Lex.getCode() != tgtok::l_paren) { 1303341825Sdim TokError("expected '(' after !foreach"); 1304341825Sdim return nullptr; 1305341825Sdim } 1306341825Sdim 1307341825Sdim if (Lex.Lex() != tgtok::Id) { // eat the '(' 1308341825Sdim TokError("first argument of !foreach must be an identifier"); 1309341825Sdim return nullptr; 1310341825Sdim } 1311341825Sdim 1312341825Sdim Init *LHS = StringInit::get(Lex.getCurStrVal()); 1313341825Sdim 1314341825Sdim if (CurRec && CurRec->getValue(LHS)) { 1315341825Sdim TokError((Twine("iteration variable '") + LHS->getAsString() + 1316341825Sdim "' already defined") 1317341825Sdim .str()); 1318341825Sdim return nullptr; 1319341825Sdim } 1320341825Sdim 1321341825Sdim if (Lex.Lex() != tgtok::comma) { // eat the id 1322341825Sdim TokError("expected ',' in ternary operator"); 1323341825Sdim return nullptr; 1324341825Sdim } 1325341825Sdim Lex.Lex(); // eat the ',' 1326341825Sdim 1327341825Sdim Init *MHS = ParseValue(CurRec); 1328341825Sdim if (!MHS) 1329341825Sdim return nullptr; 1330341825Sdim 1331341825Sdim if (Lex.getCode() != tgtok::comma) { 1332341825Sdim TokError("expected ',' in ternary operator"); 1333341825Sdim return nullptr; 1334341825Sdim } 1335341825Sdim Lex.Lex(); // eat the ',' 1336341825Sdim 1337341825Sdim TypedInit *MHSt = dyn_cast<TypedInit>(MHS); 1338341825Sdim if (!MHSt) { 1339341825Sdim TokError("could not get type of !foreach input"); 1340341825Sdim return nullptr; 1341341825Sdim } 1342341825Sdim 1343341825Sdim RecTy *InEltType = nullptr; 1344341825Sdim RecTy *OutEltType = nullptr; 1345341825Sdim bool IsDAG = false; 1346341825Sdim 1347341825Sdim if (ListRecTy *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) { 1348341825Sdim InEltType = InListTy->getElementType(); 1349341825Sdim if (ItemType) { 1350341825Sdim if (ListRecTy *OutListTy = dyn_cast<ListRecTy>(ItemType)) { 1351341825Sdim OutEltType = OutListTy->getElementType(); 1352341825Sdim } else { 1353341825Sdim Error(OpLoc, 1354341825Sdim "expected value of type '" + Twine(ItemType->getAsString()) + 1355341825Sdim "', but got !foreach of list type"); 1356341825Sdim return nullptr; 1357341825Sdim } 1358341825Sdim } 1359341825Sdim } else if (DagRecTy *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) { 1360341825Sdim InEltType = InDagTy; 1361341825Sdim if (ItemType && !isa<DagRecTy>(ItemType)) { 1362341825Sdim Error(OpLoc, 1363341825Sdim "expected value of type '" + Twine(ItemType->getAsString()) + 1364341825Sdim "', but got !foreach of dag type"); 1365341825Sdim return nullptr; 1366341825Sdim } 1367341825Sdim IsDAG = true; 1368341825Sdim } else { 1369341825Sdim TokError("!foreach must have list or dag input"); 1370341825Sdim return nullptr; 1371341825Sdim } 1372341825Sdim 1373341825Sdim // We need to create a temporary record to provide a scope for the iteration 1374341825Sdim // variable while parsing top-level foreach's. 1375341825Sdim std::unique_ptr<Record> ParseRecTmp; 1376341825Sdim Record *ParseRec = CurRec; 1377341825Sdim if (!ParseRec) { 1378360784Sdim ParseRecTmp = std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records); 1379341825Sdim ParseRec = ParseRecTmp.get(); 1380341825Sdim } 1381341825Sdim 1382341825Sdim ParseRec->addValue(RecordVal(LHS, InEltType, false)); 1383341825Sdim Init *RHS = ParseValue(ParseRec, OutEltType); 1384341825Sdim ParseRec->removeValue(LHS); 1385341825Sdim if (!RHS) 1386341825Sdim return nullptr; 1387341825Sdim 1388341825Sdim if (Lex.getCode() != tgtok::r_paren) { 1389341825Sdim TokError("expected ')' in binary operator"); 1390341825Sdim return nullptr; 1391341825Sdim } 1392341825Sdim Lex.Lex(); // eat the ')' 1393341825Sdim 1394341825Sdim RecTy *OutType; 1395341825Sdim if (IsDAG) { 1396341825Sdim OutType = InEltType; 1397341825Sdim } else { 1398341825Sdim TypedInit *RHSt = dyn_cast<TypedInit>(RHS); 1399341825Sdim if (!RHSt) { 1400341825Sdim TokError("could not get type of !foreach result"); 1401341825Sdim return nullptr; 1402341825Sdim } 1403341825Sdim OutType = RHSt->getType()->getListTy(); 1404341825Sdim } 1405341825Sdim 1406341825Sdim return (TernOpInit::get(TernOpInit::FOREACH, LHS, MHS, RHS, OutType)) 1407341825Sdim ->Fold(CurRec); 1408341825Sdim } 1409341825Sdim 1410341825Sdim case tgtok::XDag: 1411226584Sdim case tgtok::XIf: 1412226584Sdim case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' 1413226584Sdim TernOpInit::TernaryOp Code; 1414276479Sdim RecTy *Type = nullptr; 1415226584Sdim 1416226584Sdim tgtok::TokKind LexCode = Lex.getCode(); 1417226584Sdim Lex.Lex(); // eat the operation 1418226584Sdim switch (LexCode) { 1419234353Sdim default: llvm_unreachable("Unhandled code!"); 1420341825Sdim case tgtok::XDag: 1421341825Sdim Code = TernOpInit::DAG; 1422341825Sdim Type = DagRecTy::get(); 1423341825Sdim ItemType = nullptr; 1424341825Sdim break; 1425226584Sdim case tgtok::XIf: 1426226584Sdim Code = TernOpInit::IF; 1427226584Sdim break; 1428226584Sdim case tgtok::XSubst: 1429226584Sdim Code = TernOpInit::SUBST; 1430226584Sdim break; 1431226584Sdim } 1432226584Sdim if (Lex.getCode() != tgtok::l_paren) { 1433226584Sdim TokError("expected '(' after ternary operator"); 1434276479Sdim return nullptr; 1435226584Sdim } 1436226584Sdim Lex.Lex(); // eat the '(' 1437226584Sdim 1438226584Sdim Init *LHS = ParseValue(CurRec); 1439276479Sdim if (!LHS) return nullptr; 1440226584Sdim 1441226584Sdim if (Lex.getCode() != tgtok::comma) { 1442226584Sdim TokError("expected ',' in ternary operator"); 1443276479Sdim return nullptr; 1444226584Sdim } 1445226584Sdim Lex.Lex(); // eat the ',' 1446226584Sdim 1447341825Sdim SMLoc MHSLoc = Lex.getLoc(); 1448276479Sdim Init *MHS = ParseValue(CurRec, ItemType); 1449276479Sdim if (!MHS) 1450276479Sdim return nullptr; 1451226584Sdim 1452226584Sdim if (Lex.getCode() != tgtok::comma) { 1453226584Sdim TokError("expected ',' in ternary operator"); 1454276479Sdim return nullptr; 1455226584Sdim } 1456226584Sdim Lex.Lex(); // eat the ',' 1457226584Sdim 1458341825Sdim SMLoc RHSLoc = Lex.getLoc(); 1459276479Sdim Init *RHS = ParseValue(CurRec, ItemType); 1460276479Sdim if (!RHS) 1461276479Sdim return nullptr; 1462226584Sdim 1463226584Sdim if (Lex.getCode() != tgtok::r_paren) { 1464226584Sdim TokError("expected ')' in binary operator"); 1465276479Sdim return nullptr; 1466226584Sdim } 1467226584Sdim Lex.Lex(); // eat the ')' 1468226584Sdim 1469226584Sdim switch (LexCode) { 1470234353Sdim default: llvm_unreachable("Unhandled code!"); 1471341825Sdim case tgtok::XDag: { 1472341825Sdim TypedInit *MHSt = dyn_cast<TypedInit>(MHS); 1473341825Sdim if (!MHSt && !isa<UnsetInit>(MHS)) { 1474341825Sdim Error(MHSLoc, "could not determine type of the child list in !dag"); 1475341825Sdim return nullptr; 1476341825Sdim } 1477341825Sdim if (MHSt && !isa<ListRecTy>(MHSt->getType())) { 1478341825Sdim Error(MHSLoc, Twine("expected list of children, got type '") + 1479341825Sdim MHSt->getType()->getAsString() + "'"); 1480341825Sdim return nullptr; 1481341825Sdim } 1482341825Sdim 1483341825Sdim TypedInit *RHSt = dyn_cast<TypedInit>(RHS); 1484341825Sdim if (!RHSt && !isa<UnsetInit>(RHS)) { 1485341825Sdim Error(RHSLoc, "could not determine type of the name list in !dag"); 1486341825Sdim return nullptr; 1487341825Sdim } 1488341825Sdim if (RHSt && StringRecTy::get()->getListTy() != RHSt->getType()) { 1489341825Sdim Error(RHSLoc, Twine("expected list<string>, got type '") + 1490341825Sdim RHSt->getType()->getAsString() + "'"); 1491341825Sdim return nullptr; 1492341825Sdim } 1493341825Sdim 1494341825Sdim if (!MHSt && !RHSt) { 1495341825Sdim Error(MHSLoc, 1496341825Sdim "cannot have both unset children and unset names in !dag"); 1497341825Sdim return nullptr; 1498341825Sdim } 1499341825Sdim break; 1500341825Sdim } 1501226584Sdim case tgtok::XIf: { 1502276479Sdim RecTy *MHSTy = nullptr; 1503276479Sdim RecTy *RHSTy = nullptr; 1504226584Sdim 1505243830Sdim if (TypedInit *MHSt = dyn_cast<TypedInit>(MHS)) 1506243830Sdim MHSTy = MHSt->getType(); 1507243830Sdim if (BitsInit *MHSbits = dyn_cast<BitsInit>(MHS)) 1508243830Sdim MHSTy = BitsRecTy::get(MHSbits->getNumBits()); 1509243830Sdim if (isa<BitInit>(MHS)) 1510243830Sdim MHSTy = BitRecTy::get(); 1511226584Sdim 1512243830Sdim if (TypedInit *RHSt = dyn_cast<TypedInit>(RHS)) 1513226584Sdim RHSTy = RHSt->getType(); 1514243830Sdim if (BitsInit *RHSbits = dyn_cast<BitsInit>(RHS)) 1515243830Sdim RHSTy = BitsRecTy::get(RHSbits->getNumBits()); 1516243830Sdim if (isa<BitInit>(RHS)) 1517243830Sdim RHSTy = BitRecTy::get(); 1518226584Sdim 1519243830Sdim // For UnsetInit, it's typed from the other hand. 1520243830Sdim if (isa<UnsetInit>(MHS)) 1521243830Sdim MHSTy = RHSTy; 1522243830Sdim if (isa<UnsetInit>(RHS)) 1523243830Sdim RHSTy = MHSTy; 1524243830Sdim 1525226584Sdim if (!MHSTy || !RHSTy) { 1526226584Sdim TokError("could not get type for !if"); 1527276479Sdim return nullptr; 1528226584Sdim } 1529226584Sdim 1530341825Sdim Type = resolveTypes(MHSTy, RHSTy); 1531341825Sdim if (!Type) { 1532341825Sdim TokError(Twine("inconsistent types '") + MHSTy->getAsString() + 1533341825Sdim "' and '" + RHSTy->getAsString() + "' for !if"); 1534276479Sdim return nullptr; 1535226584Sdim } 1536226584Sdim break; 1537226584Sdim } 1538226584Sdim case tgtok::XSubst: { 1539243830Sdim TypedInit *RHSt = dyn_cast<TypedInit>(RHS); 1540276479Sdim if (!RHSt) { 1541226584Sdim TokError("could not get type for !subst"); 1542276479Sdim return nullptr; 1543226584Sdim } 1544226584Sdim Type = RHSt->getType(); 1545226584Sdim break; 1546226584Sdim } 1547226584Sdim } 1548341825Sdim return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec); 1549226584Sdim } 1550341825Sdim 1551353358Sdim case tgtok::XCond: 1552353358Sdim return ParseOperationCond(CurRec, ItemType); 1553353358Sdim 1554341825Sdim case tgtok::XFoldl: { 1555341825Sdim // Value ::= !foldl '(' Id ',' Id ',' Value ',' Value ',' Value ')' 1556341825Sdim Lex.Lex(); // eat the operation 1557341825Sdim if (Lex.getCode() != tgtok::l_paren) { 1558341825Sdim TokError("expected '(' after !foldl"); 1559341825Sdim return nullptr; 1560341825Sdim } 1561341825Sdim Lex.Lex(); // eat the '(' 1562341825Sdim 1563341825Sdim Init *StartUntyped = ParseValue(CurRec); 1564341825Sdim if (!StartUntyped) 1565341825Sdim return nullptr; 1566341825Sdim 1567341825Sdim TypedInit *Start = dyn_cast<TypedInit>(StartUntyped); 1568341825Sdim if (!Start) { 1569341825Sdim TokError(Twine("could not get type of !foldl start: '") + 1570341825Sdim StartUntyped->getAsString() + "'"); 1571341825Sdim return nullptr; 1572341825Sdim } 1573341825Sdim 1574341825Sdim if (Lex.getCode() != tgtok::comma) { 1575341825Sdim TokError("expected ',' in !foldl"); 1576341825Sdim return nullptr; 1577341825Sdim } 1578341825Sdim Lex.Lex(); // eat the ',' 1579341825Sdim 1580341825Sdim Init *ListUntyped = ParseValue(CurRec); 1581341825Sdim if (!ListUntyped) 1582341825Sdim return nullptr; 1583341825Sdim 1584341825Sdim TypedInit *List = dyn_cast<TypedInit>(ListUntyped); 1585341825Sdim if (!List) { 1586341825Sdim TokError(Twine("could not get type of !foldl list: '") + 1587341825Sdim ListUntyped->getAsString() + "'"); 1588341825Sdim return nullptr; 1589341825Sdim } 1590341825Sdim 1591341825Sdim ListRecTy *ListType = dyn_cast<ListRecTy>(List->getType()); 1592341825Sdim if (!ListType) { 1593341825Sdim TokError(Twine("!foldl list must be a list, but is of type '") + 1594341825Sdim List->getType()->getAsString()); 1595341825Sdim return nullptr; 1596341825Sdim } 1597341825Sdim 1598341825Sdim if (Lex.getCode() != tgtok::comma) { 1599341825Sdim TokError("expected ',' in !foldl"); 1600341825Sdim return nullptr; 1601341825Sdim } 1602341825Sdim 1603341825Sdim if (Lex.Lex() != tgtok::Id) { // eat the ',' 1604341825Sdim TokError("third argument of !foldl must be an identifier"); 1605341825Sdim return nullptr; 1606341825Sdim } 1607341825Sdim 1608341825Sdim Init *A = StringInit::get(Lex.getCurStrVal()); 1609341825Sdim if (CurRec && CurRec->getValue(A)) { 1610341825Sdim TokError((Twine("left !foldl variable '") + A->getAsString() + 1611341825Sdim "' already defined") 1612341825Sdim .str()); 1613341825Sdim return nullptr; 1614341825Sdim } 1615341825Sdim 1616341825Sdim if (Lex.Lex() != tgtok::comma) { // eat the id 1617341825Sdim TokError("expected ',' in !foldl"); 1618341825Sdim return nullptr; 1619341825Sdim } 1620341825Sdim 1621341825Sdim if (Lex.Lex() != tgtok::Id) { // eat the ',' 1622341825Sdim TokError("fourth argument of !foldl must be an identifier"); 1623341825Sdim return nullptr; 1624341825Sdim } 1625341825Sdim 1626341825Sdim Init *B = StringInit::get(Lex.getCurStrVal()); 1627341825Sdim if (CurRec && CurRec->getValue(B)) { 1628341825Sdim TokError((Twine("right !foldl variable '") + B->getAsString() + 1629341825Sdim "' already defined") 1630341825Sdim .str()); 1631341825Sdim return nullptr; 1632341825Sdim } 1633341825Sdim 1634341825Sdim if (Lex.Lex() != tgtok::comma) { // eat the id 1635341825Sdim TokError("expected ',' in !foldl"); 1636341825Sdim return nullptr; 1637341825Sdim } 1638341825Sdim Lex.Lex(); // eat the ',' 1639341825Sdim 1640341825Sdim // We need to create a temporary record to provide a scope for the iteration 1641341825Sdim // variable while parsing top-level foreach's. 1642341825Sdim std::unique_ptr<Record> ParseRecTmp; 1643341825Sdim Record *ParseRec = CurRec; 1644341825Sdim if (!ParseRec) { 1645360784Sdim ParseRecTmp = std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records); 1646341825Sdim ParseRec = ParseRecTmp.get(); 1647341825Sdim } 1648341825Sdim 1649341825Sdim ParseRec->addValue(RecordVal(A, Start->getType(), false)); 1650341825Sdim ParseRec->addValue(RecordVal(B, ListType->getElementType(), false)); 1651341825Sdim Init *ExprUntyped = ParseValue(ParseRec); 1652341825Sdim ParseRec->removeValue(A); 1653341825Sdim ParseRec->removeValue(B); 1654341825Sdim if (!ExprUntyped) 1655341825Sdim return nullptr; 1656341825Sdim 1657341825Sdim TypedInit *Expr = dyn_cast<TypedInit>(ExprUntyped); 1658341825Sdim if (!Expr) { 1659341825Sdim TokError("could not get type of !foldl expression"); 1660341825Sdim return nullptr; 1661341825Sdim } 1662341825Sdim 1663341825Sdim if (Expr->getType() != Start->getType()) { 1664341825Sdim TokError(Twine("!foldl expression must be of same type as start (") + 1665341825Sdim Start->getType()->getAsString() + "), but is of type " + 1666341825Sdim Expr->getType()->getAsString()); 1667341825Sdim return nullptr; 1668341825Sdim } 1669341825Sdim 1670341825Sdim if (Lex.getCode() != tgtok::r_paren) { 1671341825Sdim TokError("expected ')' in fold operator"); 1672341825Sdim return nullptr; 1673341825Sdim } 1674341825Sdim Lex.Lex(); // eat the ')' 1675341825Sdim 1676341825Sdim return FoldOpInit::get(Start, List, A, B, Expr, Start->getType()) 1677341825Sdim ->Fold(CurRec); 1678226584Sdim } 1679341825Sdim } 1680226584Sdim} 1681226584Sdim 1682226584Sdim/// ParseOperatorType - Parse a type for an operator. This returns 1683226584Sdim/// null on error. 1684226584Sdim/// 1685226584Sdim/// OperatorType ::= '<' Type '>' 1686226584Sdim/// 1687226584SdimRecTy *TGParser::ParseOperatorType() { 1688276479Sdim RecTy *Type = nullptr; 1689226584Sdim 1690226584Sdim if (Lex.getCode() != tgtok::less) { 1691226584Sdim TokError("expected type name for operator"); 1692276479Sdim return nullptr; 1693226584Sdim } 1694226584Sdim Lex.Lex(); // eat the < 1695226584Sdim 1696226584Sdim Type = ParseType(); 1697226584Sdim 1698276479Sdim if (!Type) { 1699226584Sdim TokError("expected type name for operator"); 1700276479Sdim return nullptr; 1701226584Sdim } 1702226584Sdim 1703226584Sdim if (Lex.getCode() != tgtok::greater) { 1704226584Sdim TokError("expected type name for operator"); 1705276479Sdim return nullptr; 1706226584Sdim } 1707226584Sdim Lex.Lex(); // eat the > 1708226584Sdim 1709226584Sdim return Type; 1710226584Sdim} 1711226584Sdim 1712353358SdimInit *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) { 1713353358Sdim Lex.Lex(); // eat the operation 'cond' 1714353358Sdim 1715353358Sdim if (Lex.getCode() != tgtok::l_paren) { 1716353358Sdim TokError("expected '(' after !cond operator"); 1717353358Sdim return nullptr; 1718353358Sdim } 1719353358Sdim Lex.Lex(); // eat the '(' 1720353358Sdim 1721353358Sdim // Parse through '[Case: Val,]+' 1722353358Sdim SmallVector<Init *, 4> Case; 1723353358Sdim SmallVector<Init *, 4> Val; 1724353358Sdim while (true) { 1725353358Sdim if (Lex.getCode() == tgtok::r_paren) { 1726353358Sdim Lex.Lex(); // eat the ')' 1727353358Sdim break; 1728353358Sdim } 1729353358Sdim 1730353358Sdim Init *V = ParseValue(CurRec); 1731353358Sdim if (!V) 1732353358Sdim return nullptr; 1733353358Sdim Case.push_back(V); 1734353358Sdim 1735353358Sdim if (Lex.getCode() != tgtok::colon) { 1736353358Sdim TokError("expected ':' following a condition in !cond operator"); 1737353358Sdim return nullptr; 1738353358Sdim } 1739353358Sdim Lex.Lex(); // eat the ':' 1740353358Sdim 1741353358Sdim V = ParseValue(CurRec, ItemType); 1742353358Sdim if (!V) 1743353358Sdim return nullptr; 1744353358Sdim Val.push_back(V); 1745353358Sdim 1746353358Sdim if (Lex.getCode() == tgtok::r_paren) { 1747353358Sdim Lex.Lex(); // eat the ')' 1748353358Sdim break; 1749353358Sdim } 1750353358Sdim 1751353358Sdim if (Lex.getCode() != tgtok::comma) { 1752353358Sdim TokError("expected ',' or ')' following a value in !cond operator"); 1753353358Sdim return nullptr; 1754353358Sdim } 1755353358Sdim Lex.Lex(); // eat the ',' 1756353358Sdim } 1757353358Sdim 1758353358Sdim if (Case.size() < 1) { 1759353358Sdim TokError("there should be at least 1 'condition : value' in the !cond operator"); 1760353358Sdim return nullptr; 1761353358Sdim } 1762353358Sdim 1763353358Sdim // resolve type 1764353358Sdim RecTy *Type = nullptr; 1765353358Sdim for (Init *V : Val) { 1766353358Sdim RecTy *VTy = nullptr; 1767353358Sdim if (TypedInit *Vt = dyn_cast<TypedInit>(V)) 1768353358Sdim VTy = Vt->getType(); 1769353358Sdim if (BitsInit *Vbits = dyn_cast<BitsInit>(V)) 1770353358Sdim VTy = BitsRecTy::get(Vbits->getNumBits()); 1771353358Sdim if (isa<BitInit>(V)) 1772353358Sdim VTy = BitRecTy::get(); 1773353358Sdim 1774353358Sdim if (Type == nullptr) { 1775353358Sdim if (!isa<UnsetInit>(V)) 1776353358Sdim Type = VTy; 1777353358Sdim } else { 1778353358Sdim if (!isa<UnsetInit>(V)) { 1779353358Sdim RecTy *RType = resolveTypes(Type, VTy); 1780353358Sdim if (!RType) { 1781353358Sdim TokError(Twine("inconsistent types '") + Type->getAsString() + 1782353358Sdim "' and '" + VTy->getAsString() + "' for !cond"); 1783353358Sdim return nullptr; 1784353358Sdim } 1785353358Sdim Type = RType; 1786353358Sdim } 1787353358Sdim } 1788353358Sdim } 1789353358Sdim 1790353358Sdim if (!Type) { 1791353358Sdim TokError("could not determine type for !cond from its arguments"); 1792353358Sdim return nullptr; 1793353358Sdim } 1794353358Sdim return CondOpInit::get(Case, Val, Type)->Fold(CurRec); 1795353358Sdim} 1796353358Sdim 1797226584Sdim/// ParseSimpleValue - Parse a tblgen value. This returns null on error. 1798226584Sdim/// 1799226584Sdim/// SimpleValue ::= IDValue 1800226584Sdim/// SimpleValue ::= INTVAL 1801226584Sdim/// SimpleValue ::= STRVAL+ 1802226584Sdim/// SimpleValue ::= CODEFRAGMENT 1803226584Sdim/// SimpleValue ::= '?' 1804226584Sdim/// SimpleValue ::= '{' ValueList '}' 1805226584Sdim/// SimpleValue ::= ID '<' ValueListNE '>' 1806226584Sdim/// SimpleValue ::= '[' ValueList ']' 1807226584Sdim/// SimpleValue ::= '(' IDValue DagArgList ')' 1808226584Sdim/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')' 1809249423Sdim/// SimpleValue ::= ADDTOK '(' Value ',' Value ')' 1810226584Sdim/// SimpleValue ::= SHLTOK '(' Value ',' Value ')' 1811226584Sdim/// SimpleValue ::= SRATOK '(' Value ',' Value ')' 1812226584Sdim/// SimpleValue ::= SRLTOK '(' Value ',' Value ')' 1813276479Sdim/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')' 1814353358Sdim/// SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')' 1815226584Sdim/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' 1816353358Sdim/// SimpleValue ::= COND '(' [Value ':' Value,]+ ')' 1817226584Sdim/// 1818234353SdimInit *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType, 1819234353Sdim IDParseMode Mode) { 1820276479Sdim Init *R = nullptr; 1821226584Sdim switch (Lex.getCode()) { 1822226584Sdim default: TokError("Unknown token when parsing a value"); break; 1823234353Sdim case tgtok::paste: 1824234353Sdim // This is a leading paste operation. This is deprecated but 1825234353Sdim // still exists in some .td files. Ignore it. 1826234353Sdim Lex.Lex(); // Skip '#'. 1827234353Sdim return ParseSimpleValue(CurRec, ItemType, Mode); 1828226584Sdim case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; 1829280031Sdim case tgtok::BinaryIntVal: { 1830280031Sdim auto BinaryVal = Lex.getCurBinaryIntVal(); 1831280031Sdim SmallVector<Init*, 16> Bits(BinaryVal.second); 1832280031Sdim for (unsigned i = 0, e = BinaryVal.second; i != e; ++i) 1833280031Sdim Bits[i] = BitInit::get(BinaryVal.first & (1LL << i)); 1834280031Sdim R = BitsInit::get(Bits); 1835280031Sdim Lex.Lex(); 1836280031Sdim break; 1837280031Sdim } 1838226584Sdim case tgtok::StrVal: { 1839226584Sdim std::string Val = Lex.getCurStrVal(); 1840226584Sdim Lex.Lex(); 1841226584Sdim 1842226584Sdim // Handle multiple consecutive concatenated strings. 1843226584Sdim while (Lex.getCode() == tgtok::StrVal) { 1844226584Sdim Val += Lex.getCurStrVal(); 1845226584Sdim Lex.Lex(); 1846226584Sdim } 1847226584Sdim 1848226584Sdim R = StringInit::get(Val); 1849226584Sdim break; 1850226584Sdim } 1851226584Sdim case tgtok::CodeFragment: 1852353358Sdim R = CodeInit::get(Lex.getCurStrVal(), Lex.getLoc()); 1853226584Sdim Lex.Lex(); 1854226584Sdim break; 1855226584Sdim case tgtok::question: 1856226584Sdim R = UnsetInit::get(); 1857226584Sdim Lex.Lex(); 1858226584Sdim break; 1859226584Sdim case tgtok::Id: { 1860226584Sdim SMLoc NameLoc = Lex.getLoc(); 1861314564Sdim StringInit *Name = StringInit::get(Lex.getCurStrVal()); 1862226584Sdim if (Lex.Lex() != tgtok::less) // consume the Id. 1863234353Sdim return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue 1864226584Sdim 1865226584Sdim // Value ::= ID '<' ValueListNE '>' 1866226584Sdim if (Lex.Lex() == tgtok::greater) { 1867226584Sdim TokError("expected non-empty value list"); 1868276479Sdim return nullptr; 1869226584Sdim } 1870226584Sdim 1871226584Sdim // This is a CLASS<initvalslist> expression. This is supposed to synthesize 1872226584Sdim // a new anonymous definition, deriving from CLASS<initvalslist> with no 1873226584Sdim // body. 1874314564Sdim Record *Class = Records.getClass(Name->getValue()); 1875226584Sdim if (!Class) { 1876314564Sdim Error(NameLoc, "Expected a class name, got '" + Name->getValue() + "'"); 1877276479Sdim return nullptr; 1878226584Sdim } 1879226584Sdim 1880341825Sdim SmallVector<Init *, 8> Args; 1881341825Sdim ParseValueList(Args, CurRec, Class); 1882341825Sdim if (Args.empty()) return nullptr; 1883226584Sdim 1884226584Sdim if (Lex.getCode() != tgtok::greater) { 1885226584Sdim TokError("expected '>' at end of value list"); 1886276479Sdim return nullptr; 1887226584Sdim } 1888226584Sdim Lex.Lex(); // eat the '>' 1889226584Sdim 1890341825Sdim // Typecheck the template arguments list 1891341825Sdim ArrayRef<Init *> ExpectedArgs = Class->getTemplateArgs(); 1892341825Sdim if (ExpectedArgs.size() < Args.size()) { 1893341825Sdim Error(NameLoc, 1894341825Sdim "More template args specified than expected"); 1895276479Sdim return nullptr; 1896341825Sdim } 1897280031Sdim 1898341825Sdim for (unsigned i = 0, e = ExpectedArgs.size(); i != e; ++i) { 1899341825Sdim RecordVal *ExpectedArg = Class->getValue(ExpectedArgs[i]); 1900341825Sdim if (i < Args.size()) { 1901341825Sdim if (TypedInit *TI = dyn_cast<TypedInit>(Args[i])) { 1902341825Sdim RecTy *ExpectedType = ExpectedArg->getType(); 1903341825Sdim if (!TI->getType()->typeIsConvertibleTo(ExpectedType)) { 1904341825Sdim Error(NameLoc, 1905341825Sdim "Value specified for template argument #" + Twine(i) + " (" + 1906341825Sdim ExpectedArg->getNameInitAsString() + ") is of type '" + 1907341825Sdim TI->getType()->getAsString() + "', expected '" + 1908341825Sdim ExpectedType->getAsString() + "': " + TI->getAsString()); 1909341825Sdim return nullptr; 1910341825Sdim } 1911341825Sdim continue; 1912341825Sdim } 1913341825Sdim } else if (ExpectedArg->getValue()->isComplete()) 1914341825Sdim continue; 1915226584Sdim 1916341825Sdim Error(NameLoc, 1917341825Sdim "Value not specified for template argument #" + Twine(i) + " (" + 1918341825Sdim ExpectedArgs[i]->getAsUnquotedString() + ")"); 1919341825Sdim return nullptr; 1920276479Sdim } 1921276479Sdim 1922341825Sdim return VarDefInit::get(Class, Args)->Fold(); 1923226584Sdim } 1924226584Sdim case tgtok::l_brace: { // Value ::= '{' ValueList '}' 1925226584Sdim SMLoc BraceLoc = Lex.getLoc(); 1926226584Sdim Lex.Lex(); // eat the '{' 1927314564Sdim SmallVector<Init*, 16> Vals; 1928226584Sdim 1929226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1930314564Sdim ParseValueList(Vals, CurRec); 1931276479Sdim if (Vals.empty()) return nullptr; 1932226584Sdim } 1933226584Sdim if (Lex.getCode() != tgtok::r_brace) { 1934226584Sdim TokError("expected '}' at end of bit list value"); 1935276479Sdim return nullptr; 1936226584Sdim } 1937226584Sdim Lex.Lex(); // eat the '}' 1938226584Sdim 1939280031Sdim SmallVector<Init *, 16> NewBits; 1940226584Sdim 1941280031Sdim // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it 1942280031Sdim // first. We'll first read everything in to a vector, then we can reverse 1943280031Sdim // it to get the bits in the correct order for the BitsInit value. 1944226584Sdim for (unsigned i = 0, e = Vals.size(); i != e; ++i) { 1945280031Sdim // FIXME: The following two loops would not be duplicated 1946280031Sdim // if the API was a little more orthogonal. 1947280031Sdim 1948280031Sdim // bits<n> values are allowed to initialize n bits. 1949280031Sdim if (BitsInit *BI = dyn_cast<BitsInit>(Vals[i])) { 1950280031Sdim for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) 1951280031Sdim NewBits.push_back(BI->getBit((e - i) - 1)); 1952280031Sdim continue; 1953280031Sdim } 1954280031Sdim // bits<n> can also come from variable initializers. 1955280031Sdim if (VarInit *VI = dyn_cast<VarInit>(Vals[i])) { 1956280031Sdim if (BitsRecTy *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) { 1957280031Sdim for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i) 1958280031Sdim NewBits.push_back(VI->getBit((e - i) - 1)); 1959280031Sdim continue; 1960280031Sdim } 1961280031Sdim // Fallthrough to try convert this to a bit. 1962280031Sdim } 1963280031Sdim // All other values must be convertible to just a single bit. 1964341825Sdim Init *Bit = Vals[i]->getCastTo(BitRecTy::get()); 1965276479Sdim if (!Bit) { 1966288943Sdim Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() + 1967226584Sdim ") is not convertable to a bit"); 1968276479Sdim return nullptr; 1969226584Sdim } 1970280031Sdim NewBits.push_back(Bit); 1971226584Sdim } 1972280031Sdim std::reverse(NewBits.begin(), NewBits.end()); 1973226584Sdim return BitsInit::get(NewBits); 1974226584Sdim } 1975226584Sdim case tgtok::l_square: { // Value ::= '[' ValueList ']' 1976226584Sdim Lex.Lex(); // eat the '[' 1977314564Sdim SmallVector<Init*, 16> Vals; 1978226584Sdim 1979276479Sdim RecTy *DeducedEltTy = nullptr; 1980276479Sdim ListRecTy *GivenListTy = nullptr; 1981226584Sdim 1982276479Sdim if (ItemType) { 1983243830Sdim ListRecTy *ListType = dyn_cast<ListRecTy>(ItemType); 1984276479Sdim if (!ListType) { 1985288943Sdim TokError(Twine("Type mismatch for list, expected list type, got ") + 1986288943Sdim ItemType->getAsString()); 1987276479Sdim return nullptr; 1988226584Sdim } 1989226584Sdim GivenListTy = ListType; 1990226584Sdim } 1991226584Sdim 1992226584Sdim if (Lex.getCode() != tgtok::r_square) { 1993314564Sdim ParseValueList(Vals, CurRec, nullptr, 1994314564Sdim GivenListTy ? GivenListTy->getElementType() : nullptr); 1995276479Sdim if (Vals.empty()) return nullptr; 1996226584Sdim } 1997226584Sdim if (Lex.getCode() != tgtok::r_square) { 1998226584Sdim TokError("expected ']' at end of list value"); 1999276479Sdim return nullptr; 2000226584Sdim } 2001226584Sdim Lex.Lex(); // eat the ']' 2002226584Sdim 2003276479Sdim RecTy *GivenEltTy = nullptr; 2004226584Sdim if (Lex.getCode() == tgtok::less) { 2005226584Sdim // Optional list element type 2006226584Sdim Lex.Lex(); // eat the '<' 2007226584Sdim 2008226584Sdim GivenEltTy = ParseType(); 2009276479Sdim if (!GivenEltTy) { 2010226584Sdim // Couldn't parse element type 2011276479Sdim return nullptr; 2012226584Sdim } 2013226584Sdim 2014226584Sdim if (Lex.getCode() != tgtok::greater) { 2015226584Sdim TokError("expected '>' at end of list element type"); 2016276479Sdim return nullptr; 2017226584Sdim } 2018226584Sdim Lex.Lex(); // eat the '>' 2019226584Sdim } 2020226584Sdim 2021226584Sdim // Check elements 2022276479Sdim RecTy *EltTy = nullptr; 2023288943Sdim for (Init *V : Vals) { 2024288943Sdim TypedInit *TArg = dyn_cast<TypedInit>(V); 2025341825Sdim if (TArg) { 2026341825Sdim if (EltTy) { 2027341825Sdim EltTy = resolveTypes(EltTy, TArg->getType()); 2028341825Sdim if (!EltTy) { 2029341825Sdim TokError("Incompatible types in list elements"); 2030341825Sdim return nullptr; 2031341825Sdim } 2032341825Sdim } else { 2033341825Sdim EltTy = TArg->getType(); 2034226584Sdim } 2035226584Sdim } 2036226584Sdim } 2037226584Sdim 2038276479Sdim if (GivenEltTy) { 2039276479Sdim if (EltTy) { 2040226584Sdim // Verify consistency 2041226584Sdim if (!EltTy->typeIsConvertibleTo(GivenEltTy)) { 2042226584Sdim TokError("Incompatible types in list elements"); 2043276479Sdim return nullptr; 2044226584Sdim } 2045226584Sdim } 2046226584Sdim EltTy = GivenEltTy; 2047226584Sdim } 2048226584Sdim 2049276479Sdim if (!EltTy) { 2050276479Sdim if (!ItemType) { 2051226584Sdim TokError("No type for list"); 2052276479Sdim return nullptr; 2053226584Sdim } 2054226584Sdim DeducedEltTy = GivenListTy->getElementType(); 2055226584Sdim } else { 2056226584Sdim // Make sure the deduced type is compatible with the given type 2057226584Sdim if (GivenListTy) { 2058226584Sdim if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) { 2059341825Sdim TokError(Twine("Element type mismatch for list: element type '") + 2060341825Sdim EltTy->getAsString() + "' not convertible to '" + 2061341825Sdim GivenListTy->getElementType()->getAsString()); 2062276479Sdim return nullptr; 2063226584Sdim } 2064226584Sdim } 2065226584Sdim DeducedEltTy = EltTy; 2066226584Sdim } 2067226584Sdim 2068226584Sdim return ListInit::get(Vals, DeducedEltTy); 2069226584Sdim } 2070226584Sdim case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' 2071226584Sdim Lex.Lex(); // eat the '(' 2072360784Sdim if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast && 2073360784Sdim Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetOp) { 2074226584Sdim TokError("expected identifier in dag init"); 2075276479Sdim return nullptr; 2076226584Sdim } 2077226584Sdim 2078226584Sdim Init *Operator = ParseValue(CurRec); 2079276479Sdim if (!Operator) return nullptr; 2080226584Sdim 2081226584Sdim // If the operator name is present, parse it. 2082314564Sdim StringInit *OperatorName = nullptr; 2083226584Sdim if (Lex.getCode() == tgtok::colon) { 2084226584Sdim if (Lex.Lex() != tgtok::VarName) { // eat the ':' 2085226584Sdim TokError("expected variable name in dag operator"); 2086276479Sdim return nullptr; 2087226584Sdim } 2088314564Sdim OperatorName = StringInit::get(Lex.getCurStrVal()); 2089226584Sdim Lex.Lex(); // eat the VarName. 2090226584Sdim } 2091226584Sdim 2092314564Sdim SmallVector<std::pair<llvm::Init*, StringInit*>, 8> DagArgs; 2093226584Sdim if (Lex.getCode() != tgtok::r_paren) { 2094314564Sdim ParseDagArgList(DagArgs, CurRec); 2095276479Sdim if (DagArgs.empty()) return nullptr; 2096226584Sdim } 2097226584Sdim 2098226584Sdim if (Lex.getCode() != tgtok::r_paren) { 2099226584Sdim TokError("expected ')' in dag init"); 2100276479Sdim return nullptr; 2101226584Sdim } 2102226584Sdim Lex.Lex(); // eat the ')' 2103226584Sdim 2104226584Sdim return DagInit::get(Operator, OperatorName, DagArgs); 2105226584Sdim } 2106226584Sdim 2107226584Sdim case tgtok::XHead: 2108226584Sdim case tgtok::XTail: 2109341825Sdim case tgtok::XSize: 2110226584Sdim case tgtok::XEmpty: 2111360784Sdim case tgtok::XCast: 2112360784Sdim case tgtok::XGetOp: // Value ::= !unop '(' Value ')' 2113341825Sdim case tgtok::XIsA: 2114226584Sdim case tgtok::XConcat: 2115341825Sdim case tgtok::XDag: 2116249423Sdim case tgtok::XADD: 2117353358Sdim case tgtok::XMUL: 2118280031Sdim case tgtok::XAND: 2119314564Sdim case tgtok::XOR: 2120226584Sdim case tgtok::XSRA: 2121226584Sdim case tgtok::XSRL: 2122226584Sdim case tgtok::XSHL: 2123226584Sdim case tgtok::XEq: 2124341825Sdim case tgtok::XNe: 2125341825Sdim case tgtok::XLe: 2126341825Sdim case tgtok::XLt: 2127341825Sdim case tgtok::XGe: 2128341825Sdim case tgtok::XGt: 2129276479Sdim case tgtok::XListConcat: 2130353358Sdim case tgtok::XListSplat: 2131360784Sdim case tgtok::XStrConcat: 2132360784Sdim case tgtok::XSetOp: // Value ::= !binop '(' Value ',' Value ')' 2133226584Sdim case tgtok::XIf: 2134353358Sdim case tgtok::XCond: 2135341825Sdim case tgtok::XFoldl: 2136226584Sdim case tgtok::XForEach: 2137226584Sdim case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' 2138276479Sdim return ParseOperation(CurRec, ItemType); 2139226584Sdim } 2140226584Sdim } 2141226584Sdim 2142226584Sdim return R; 2143226584Sdim} 2144226584Sdim 2145226584Sdim/// ParseValue - Parse a tblgen value. This returns null on error. 2146226584Sdim/// 2147226584Sdim/// Value ::= SimpleValue ValueSuffix* 2148226584Sdim/// ValueSuffix ::= '{' BitList '}' 2149226584Sdim/// ValueSuffix ::= '[' BitList ']' 2150226584Sdim/// ValueSuffix ::= '.' ID 2151226584Sdim/// 2152234353SdimInit *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { 2153234353Sdim Init *Result = ParseSimpleValue(CurRec, ItemType, Mode); 2154276479Sdim if (!Result) return nullptr; 2155226584Sdim 2156226584Sdim // Parse the suffixes now if present. 2157314564Sdim while (true) { 2158226584Sdim switch (Lex.getCode()) { 2159226584Sdim default: return Result; 2160226584Sdim case tgtok::l_brace: { 2161341825Sdim if (Mode == ParseNameMode) 2162234353Sdim // This is the beginning of the object body. 2163234353Sdim return Result; 2164234353Sdim 2165226584Sdim SMLoc CurlyLoc = Lex.getLoc(); 2166226584Sdim Lex.Lex(); // eat the '{' 2167314564Sdim SmallVector<unsigned, 16> Ranges; 2168314564Sdim ParseRangeList(Ranges); 2169276479Sdim if (Ranges.empty()) return nullptr; 2170226584Sdim 2171226584Sdim // Reverse the bitlist. 2172226584Sdim std::reverse(Ranges.begin(), Ranges.end()); 2173226584Sdim Result = Result->convertInitializerBitRange(Ranges); 2174276479Sdim if (!Result) { 2175226584Sdim Error(CurlyLoc, "Invalid bit range for value"); 2176276479Sdim return nullptr; 2177226584Sdim } 2178226584Sdim 2179226584Sdim // Eat the '}'. 2180226584Sdim if (Lex.getCode() != tgtok::r_brace) { 2181226584Sdim TokError("expected '}' at end of bit range list"); 2182276479Sdim return nullptr; 2183226584Sdim } 2184226584Sdim Lex.Lex(); 2185226584Sdim break; 2186226584Sdim } 2187226584Sdim case tgtok::l_square: { 2188226584Sdim SMLoc SquareLoc = Lex.getLoc(); 2189226584Sdim Lex.Lex(); // eat the '[' 2190314564Sdim SmallVector<unsigned, 16> Ranges; 2191314564Sdim ParseRangeList(Ranges); 2192276479Sdim if (Ranges.empty()) return nullptr; 2193226584Sdim 2194226584Sdim Result = Result->convertInitListSlice(Ranges); 2195276479Sdim if (!Result) { 2196226584Sdim Error(SquareLoc, "Invalid range for list slice"); 2197276479Sdim return nullptr; 2198226584Sdim } 2199226584Sdim 2200226584Sdim // Eat the ']'. 2201226584Sdim if (Lex.getCode() != tgtok::r_square) { 2202226584Sdim TokError("expected ']' at end of list slice"); 2203276479Sdim return nullptr; 2204226584Sdim } 2205226584Sdim Lex.Lex(); 2206226584Sdim break; 2207226584Sdim } 2208314564Sdim case tgtok::period: { 2209226584Sdim if (Lex.Lex() != tgtok::Id) { // eat the . 2210226584Sdim TokError("expected field identifier after '.'"); 2211276479Sdim return nullptr; 2212226584Sdim } 2213314564Sdim StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); 2214314564Sdim if (!Result->getFieldType(FieldName)) { 2215226584Sdim TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + 2216226584Sdim Result->getAsString() + "'"); 2217276479Sdim return nullptr; 2218226584Sdim } 2219341825Sdim Result = FieldInit::get(Result, FieldName)->Fold(CurRec); 2220226584Sdim Lex.Lex(); // eat field name 2221226584Sdim break; 2222314564Sdim } 2223234353Sdim 2224234353Sdim case tgtok::paste: 2225234353Sdim SMLoc PasteLoc = Lex.getLoc(); 2226243830Sdim TypedInit *LHS = dyn_cast<TypedInit>(Result); 2227234353Sdim if (!LHS) { 2228234353Sdim Error(PasteLoc, "LHS of paste is not typed!"); 2229276479Sdim return nullptr; 2230234353Sdim } 2231288943Sdim 2232353358Sdim // Check if it's a 'listA # listB' 2233353358Sdim if (isa<ListRecTy>(LHS->getType())) { 2234353358Sdim Lex.Lex(); // Eat the '#'. 2235353358Sdim 2236353358Sdim switch (Lex.getCode()) { 2237353358Sdim case tgtok::colon: 2238353358Sdim case tgtok::semi: 2239353358Sdim case tgtok::l_brace: 2240353358Sdim Result = LHS; // trailing paste, ignore. 2241353358Sdim break; 2242353358Sdim default: 2243353358Sdim Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode); 2244353358Sdim Result = BinOpInit::getListConcat(LHS, RHSResult); 2245353358Sdim } 2246353358Sdim break; 2247353358Sdim } 2248353358Sdim 2249353358Sdim // Create a !strconcat() operation, first casting each operand to 2250353358Sdim // a string if necessary. 2251234353Sdim if (LHS->getType() != StringRecTy::get()) { 2252353358Sdim auto CastLHS = dyn_cast<TypedInit>( 2253341825Sdim UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get()) 2254341825Sdim ->Fold(CurRec)); 2255353358Sdim if (!CastLHS) { 2256353358Sdim Error(PasteLoc, 2257353358Sdim Twine("can't cast '") + LHS->getAsString() + "' to string"); 2258341825Sdim return nullptr; 2259341825Sdim } 2260353358Sdim LHS = CastLHS; 2261234353Sdim } 2262234353Sdim 2263276479Sdim TypedInit *RHS = nullptr; 2264234353Sdim 2265234353Sdim Lex.Lex(); // Eat the '#'. 2266341825Sdim switch (Lex.getCode()) { 2267234353Sdim case tgtok::colon: 2268234353Sdim case tgtok::semi: 2269234353Sdim case tgtok::l_brace: 2270234353Sdim // These are all of the tokens that can begin an object body. 2271234353Sdim // Some of these can also begin values but we disallow those cases 2272234353Sdim // because they are unlikely to be useful. 2273288943Sdim 2274234353Sdim // Trailing paste, concat with an empty string. 2275234353Sdim RHS = StringInit::get(""); 2276234353Sdim break; 2277234353Sdim 2278234353Sdim default: 2279341825Sdim Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode); 2280243830Sdim RHS = dyn_cast<TypedInit>(RHSResult); 2281234353Sdim if (!RHS) { 2282234353Sdim Error(PasteLoc, "RHS of paste is not typed!"); 2283276479Sdim return nullptr; 2284234353Sdim } 2285234353Sdim 2286234353Sdim if (RHS->getType() != StringRecTy::get()) { 2287353358Sdim auto CastRHS = dyn_cast<TypedInit>( 2288341825Sdim UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get()) 2289341825Sdim ->Fold(CurRec)); 2290353358Sdim if (!CastRHS) { 2291353358Sdim Error(PasteLoc, 2292353358Sdim Twine("can't cast '") + RHS->getAsString() + "' to string"); 2293341825Sdim return nullptr; 2294341825Sdim } 2295353358Sdim RHS = CastRHS; 2296234353Sdim } 2297288943Sdim 2298234353Sdim break; 2299234353Sdim } 2300234353Sdim 2301341825Sdim Result = BinOpInit::getStrConcat(LHS, RHS); 2302234353Sdim break; 2303226584Sdim } 2304226584Sdim } 2305226584Sdim} 2306226584Sdim 2307226584Sdim/// ParseDagArgList - Parse the argument list for a dag literal expression. 2308226584Sdim/// 2309249423Sdim/// DagArg ::= Value (':' VARNAME)? 2310249423Sdim/// DagArg ::= VARNAME 2311249423Sdim/// DagArgList ::= DagArg 2312249423Sdim/// DagArgList ::= DagArgList ',' DagArg 2313314564Sdimvoid TGParser::ParseDagArgList( 2314314564Sdim SmallVectorImpl<std::pair<llvm::Init*, StringInit*>> &Result, 2315314564Sdim Record *CurRec) { 2316226584Sdim 2317314564Sdim while (true) { 2318249423Sdim // DagArg ::= VARNAME 2319249423Sdim if (Lex.getCode() == tgtok::VarName) { 2320249423Sdim // A missing value is treated like '?'. 2321314564Sdim StringInit *VarName = StringInit::get(Lex.getCurStrVal()); 2322314564Sdim Result.emplace_back(UnsetInit::get(), VarName); 2323249423Sdim Lex.Lex(); 2324249423Sdim } else { 2325249423Sdim // DagArg ::= Value (':' VARNAME)? 2326249423Sdim Init *Val = ParseValue(CurRec); 2327314564Sdim if (!Val) { 2328314564Sdim Result.clear(); 2329314564Sdim return; 2330314564Sdim } 2331226584Sdim 2332249423Sdim // If the variable name is present, add it. 2333314564Sdim StringInit *VarName = nullptr; 2334249423Sdim if (Lex.getCode() == tgtok::colon) { 2335249423Sdim if (Lex.Lex() != tgtok::VarName) { // eat the ':' 2336249423Sdim TokError("expected variable name in dag literal"); 2337314564Sdim Result.clear(); 2338314564Sdim return; 2339249423Sdim } 2340314564Sdim VarName = StringInit::get(Lex.getCurStrVal()); 2341249423Sdim Lex.Lex(); // eat the VarName. 2342226584Sdim } 2343249423Sdim 2344249423Sdim Result.push_back(std::make_pair(Val, VarName)); 2345226584Sdim } 2346226584Sdim if (Lex.getCode() != tgtok::comma) break; 2347226584Sdim Lex.Lex(); // eat the ',' 2348226584Sdim } 2349226584Sdim} 2350226584Sdim 2351226584Sdim/// ParseValueList - Parse a comma separated list of values, returning them as a 2352226584Sdim/// vector. Note that this always expects to be able to parse at least one 2353226584Sdim/// value. It returns an empty list if this is not possible. 2354226584Sdim/// 2355226584Sdim/// ValueList ::= Value (',' Value) 2356226584Sdim/// 2357314564Sdimvoid TGParser::ParseValueList(SmallVectorImpl<Init*> &Result, Record *CurRec, 2358314564Sdim Record *ArgsRec, RecTy *EltTy) { 2359226584Sdim RecTy *ItemType = EltTy; 2360226584Sdim unsigned int ArgN = 0; 2361276479Sdim if (ArgsRec && !EltTy) { 2362296417Sdim ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); 2363288943Sdim if (TArgs.empty()) { 2364234353Sdim TokError("template argument provided to non-template class"); 2365314564Sdim Result.clear(); 2366314564Sdim return; 2367234353Sdim } 2368226584Sdim const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); 2369226584Sdim if (!RV) { 2370226584Sdim errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN] 2371226584Sdim << ")\n"; 2372226584Sdim } 2373226584Sdim assert(RV && "Template argument record not found??"); 2374226584Sdim ItemType = RV->getType(); 2375226584Sdim ++ArgN; 2376226584Sdim } 2377226584Sdim Result.push_back(ParseValue(CurRec, ItemType)); 2378314564Sdim if (!Result.back()) { 2379314564Sdim Result.clear(); 2380314564Sdim return; 2381314564Sdim } 2382226584Sdim 2383226584Sdim while (Lex.getCode() == tgtok::comma) { 2384226584Sdim Lex.Lex(); // Eat the comma 2385226584Sdim 2386353358Sdim // ignore trailing comma for lists 2387353358Sdim if (Lex.getCode() == tgtok::r_square) 2388353358Sdim return; 2389353358Sdim 2390276479Sdim if (ArgsRec && !EltTy) { 2391296417Sdim ArrayRef<Init *> TArgs = ArgsRec->getTemplateArgs(); 2392226584Sdim if (ArgN >= TArgs.size()) { 2393226584Sdim TokError("too many template arguments"); 2394314564Sdim Result.clear(); 2395314564Sdim return; 2396226584Sdim } 2397226584Sdim const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); 2398226584Sdim assert(RV && "Template argument record not found??"); 2399226584Sdim ItemType = RV->getType(); 2400226584Sdim ++ArgN; 2401226584Sdim } 2402226584Sdim Result.push_back(ParseValue(CurRec, ItemType)); 2403314564Sdim if (!Result.back()) { 2404314564Sdim Result.clear(); 2405314564Sdim return; 2406314564Sdim } 2407226584Sdim } 2408226584Sdim} 2409226584Sdim 2410226584Sdim/// ParseDeclaration - Read a declaration, returning the name of field ID, or an 2411226584Sdim/// empty string on error. This can happen in a number of different context's, 2412226584Sdim/// including within a def or in the template args for a def (which which case 2413226584Sdim/// CurRec will be non-null) and within the template args for a multiclass (in 2414226584Sdim/// which case CurRec will be null, but CurMultiClass will be set). This can 2415226584Sdim/// also happen within a def that is within a multiclass, which will set both 2416226584Sdim/// CurRec and CurMultiClass. 2417226584Sdim/// 2418226584Sdim/// Declaration ::= FIELD? Type ID ('=' Value)? 2419226584Sdim/// 2420234353SdimInit *TGParser::ParseDeclaration(Record *CurRec, 2421226584Sdim bool ParsingTemplateArgs) { 2422226584Sdim // Read the field prefix if present. 2423226584Sdim bool HasField = Lex.getCode() == tgtok::Field; 2424226584Sdim if (HasField) Lex.Lex(); 2425226584Sdim 2426226584Sdim RecTy *Type = ParseType(); 2427276479Sdim if (!Type) return nullptr; 2428226584Sdim 2429226584Sdim if (Lex.getCode() != tgtok::Id) { 2430226584Sdim TokError("Expected identifier in declaration"); 2431276479Sdim return nullptr; 2432226584Sdim } 2433226584Sdim 2434341825Sdim std::string Str = Lex.getCurStrVal(); 2435341825Sdim if (Str == "NAME") { 2436341825Sdim TokError("'" + Str + "' is a reserved variable name"); 2437341825Sdim return nullptr; 2438341825Sdim } 2439341825Sdim 2440226584Sdim SMLoc IdLoc = Lex.getLoc(); 2441341825Sdim Init *DeclName = StringInit::get(Str); 2442226584Sdim Lex.Lex(); 2443226584Sdim 2444226584Sdim if (ParsingTemplateArgs) { 2445288943Sdim if (CurRec) 2446234353Sdim DeclName = QualifyName(*CurRec, CurMultiClass, DeclName, ":"); 2447288943Sdim else 2448226584Sdim assert(CurMultiClass); 2449226584Sdim if (CurMultiClass) 2450234353Sdim DeclName = QualifyName(CurMultiClass->Rec, CurMultiClass, DeclName, 2451234353Sdim "::"); 2452226584Sdim } 2453226584Sdim 2454226584Sdim // Add the value. 2455226584Sdim if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField))) 2456276479Sdim return nullptr; 2457226584Sdim 2458226584Sdim // If a value is present, parse it. 2459226584Sdim if (Lex.getCode() == tgtok::equal) { 2460226584Sdim Lex.Lex(); 2461226584Sdim SMLoc ValLoc = Lex.getLoc(); 2462226584Sdim Init *Val = ParseValue(CurRec, Type); 2463276479Sdim if (!Val || 2464296417Sdim SetValue(CurRec, ValLoc, DeclName, None, Val)) 2465280031Sdim // Return the name, even if an error is thrown. This is so that we can 2466280031Sdim // continue to make some progress, even without the value having been 2467280031Sdim // initialized. 2468280031Sdim return DeclName; 2469226584Sdim } 2470226584Sdim 2471226584Sdim return DeclName; 2472226584Sdim} 2473226584Sdim 2474234353Sdim/// ParseForeachDeclaration - Read a foreach declaration, returning 2475234353Sdim/// the name of the declared object or a NULL Init on error. Return 2476234353Sdim/// the name of the parsed initializer list through ForeachListName. 2477234353Sdim/// 2478239462Sdim/// ForeachDeclaration ::= ID '=' '{' RangeList '}' 2479239462Sdim/// ForeachDeclaration ::= ID '=' RangePiece 2480341825Sdim/// ForeachDeclaration ::= ID '=' Value 2481234353Sdim/// 2482341825SdimVarInit *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) { 2483234353Sdim if (Lex.getCode() != tgtok::Id) { 2484234353Sdim TokError("Expected identifier in foreach declaration"); 2485276479Sdim return nullptr; 2486234353Sdim } 2487234353Sdim 2488234353Sdim Init *DeclName = StringInit::get(Lex.getCurStrVal()); 2489234353Sdim Lex.Lex(); 2490234353Sdim 2491234353Sdim // If a value is present, parse it. 2492234353Sdim if (Lex.getCode() != tgtok::equal) { 2493234353Sdim TokError("Expected '=' in foreach declaration"); 2494276479Sdim return nullptr; 2495234353Sdim } 2496234353Sdim Lex.Lex(); // Eat the '=' 2497234353Sdim 2498276479Sdim RecTy *IterType = nullptr; 2499314564Sdim SmallVector<unsigned, 16> Ranges; 2500234353Sdim 2501239462Sdim switch (Lex.getCode()) { 2502239462Sdim case tgtok::l_brace: { // '{' RangeList '}' 2503239462Sdim Lex.Lex(); // eat the '{' 2504314564Sdim ParseRangeList(Ranges); 2505239462Sdim if (Lex.getCode() != tgtok::r_brace) { 2506239462Sdim TokError("expected '}' at end of bit range list"); 2507276479Sdim return nullptr; 2508239462Sdim } 2509239462Sdim Lex.Lex(); 2510239462Sdim break; 2511239462Sdim } 2512341825Sdim 2513341825Sdim default: { 2514341825Sdim SMLoc ValueLoc = Lex.getLoc(); 2515341825Sdim Init *I = ParseValue(nullptr); 2516353358Sdim if (!I) 2517353358Sdim return nullptr; 2518353358Sdim 2519341825Sdim TypedInit *TI = dyn_cast<TypedInit>(I); 2520353358Sdim if (TI && isa<ListRecTy>(TI->getType())) { 2521353358Sdim ForeachListValue = I; 2522353358Sdim IterType = cast<ListRecTy>(TI->getType())->getElementType(); 2523353358Sdim break; 2524341825Sdim } 2525353358Sdim 2526353358Sdim if (TI) { 2527353358Sdim if (ParseRangePiece(Ranges, TI)) 2528353358Sdim return nullptr; 2529353358Sdim break; 2530353358Sdim } 2531353358Sdim 2532353358Sdim std::string Type; 2533353358Sdim if (TI) 2534353358Sdim Type = (Twine("' of type '") + TI->getType()->getAsString()).str(); 2535353358Sdim Error(ValueLoc, "expected a list, got '" + I->getAsString() + Type + "'"); 2536353358Sdim if (CurMultiClass) { 2537353358Sdim PrintNote({}, "references to multiclass template arguments cannot be " 2538353358Sdim "resolved at this time"); 2539353358Sdim } 2540353358Sdim return nullptr; 2541239462Sdim } 2542341825Sdim } 2543234353Sdim 2544353358Sdim 2545239462Sdim if (!Ranges.empty()) { 2546239462Sdim assert(!IterType && "Type already initialized?"); 2547239462Sdim IterType = IntRecTy::get(); 2548239462Sdim std::vector<Init*> Values; 2549288943Sdim for (unsigned R : Ranges) 2550288943Sdim Values.push_back(IntInit::get(R)); 2551239462Sdim ForeachListValue = ListInit::get(Values, IterType); 2552239462Sdim } 2553239462Sdim 2554239462Sdim if (!IterType) 2555276479Sdim return nullptr; 2556239462Sdim 2557239462Sdim return VarInit::get(DeclName, IterType); 2558234353Sdim} 2559234353Sdim 2560226584Sdim/// ParseTemplateArgList - Read a template argument list, which is a non-empty 2561226584Sdim/// sequence of template-declarations in <>'s. If CurRec is non-null, these are 2562226584Sdim/// template args for a def, which may or may not be in a multiclass. If null, 2563226584Sdim/// these are the template args for a multiclass. 2564226584Sdim/// 2565226584Sdim/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>' 2566226584Sdim/// 2567226584Sdimbool TGParser::ParseTemplateArgList(Record *CurRec) { 2568226584Sdim assert(Lex.getCode() == tgtok::less && "Not a template arg list!"); 2569226584Sdim Lex.Lex(); // eat the '<' 2570226584Sdim 2571226584Sdim Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec; 2572226584Sdim 2573226584Sdim // Read the first declaration. 2574234353Sdim Init *TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); 2575276479Sdim if (!TemplArg) 2576226584Sdim return true; 2577226584Sdim 2578226584Sdim TheRecToAddTo->addTemplateArg(TemplArg); 2579226584Sdim 2580226584Sdim while (Lex.getCode() == tgtok::comma) { 2581226584Sdim Lex.Lex(); // eat the ',' 2582226584Sdim 2583226584Sdim // Read the following declarations. 2584341825Sdim SMLoc Loc = Lex.getLoc(); 2585226584Sdim TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); 2586276479Sdim if (!TemplArg) 2587226584Sdim return true; 2588341825Sdim 2589341825Sdim if (TheRecToAddTo->isTemplateArg(TemplArg)) 2590341825Sdim return Error(Loc, "template argument with the same name has already been " 2591341825Sdim "defined"); 2592341825Sdim 2593226584Sdim TheRecToAddTo->addTemplateArg(TemplArg); 2594226584Sdim } 2595226584Sdim 2596226584Sdim if (Lex.getCode() != tgtok::greater) 2597226584Sdim return TokError("expected '>' at end of template argument list"); 2598226584Sdim Lex.Lex(); // eat the '>'. 2599226584Sdim return false; 2600226584Sdim} 2601226584Sdim 2602226584Sdim/// ParseBodyItem - Parse a single item at within the body of a def or class. 2603226584Sdim/// 2604226584Sdim/// BodyItem ::= Declaration ';' 2605226584Sdim/// BodyItem ::= LET ID OptionalBitList '=' Value ';' 2606360784Sdim/// BodyItem ::= Defvar 2607226584Sdimbool TGParser::ParseBodyItem(Record *CurRec) { 2608360784Sdim if (Lex.getCode() == tgtok::Defvar) 2609360784Sdim return ParseDefvar(); 2610360784Sdim 2611226584Sdim if (Lex.getCode() != tgtok::Let) { 2612276479Sdim if (!ParseDeclaration(CurRec, false)) 2613226584Sdim return true; 2614226584Sdim 2615226584Sdim if (Lex.getCode() != tgtok::semi) 2616226584Sdim return TokError("expected ';' after declaration"); 2617226584Sdim Lex.Lex(); 2618226584Sdim return false; 2619226584Sdim } 2620226584Sdim 2621226584Sdim // LET ID OptionalRangeList '=' Value ';' 2622226584Sdim if (Lex.Lex() != tgtok::Id) 2623226584Sdim return TokError("expected field identifier after let"); 2624226584Sdim 2625226584Sdim SMLoc IdLoc = Lex.getLoc(); 2626314564Sdim StringInit *FieldName = StringInit::get(Lex.getCurStrVal()); 2627226584Sdim Lex.Lex(); // eat the field name. 2628226584Sdim 2629314564Sdim SmallVector<unsigned, 16> BitList; 2630226584Sdim if (ParseOptionalBitList(BitList)) 2631226584Sdim return true; 2632226584Sdim std::reverse(BitList.begin(), BitList.end()); 2633226584Sdim 2634226584Sdim if (Lex.getCode() != tgtok::equal) 2635226584Sdim return TokError("expected '=' in let expression"); 2636226584Sdim Lex.Lex(); // eat the '='. 2637226584Sdim 2638226584Sdim RecordVal *Field = CurRec->getValue(FieldName); 2639276479Sdim if (!Field) 2640314564Sdim return TokError("Value '" + FieldName->getValue() + "' unknown!"); 2641226584Sdim 2642226584Sdim RecTy *Type = Field->getType(); 2643226584Sdim 2644226584Sdim Init *Val = ParseValue(CurRec, Type); 2645276479Sdim if (!Val) return true; 2646226584Sdim 2647226584Sdim if (Lex.getCode() != tgtok::semi) 2648226584Sdim return TokError("expected ';' after let expression"); 2649226584Sdim Lex.Lex(); 2650226584Sdim 2651226584Sdim return SetValue(CurRec, IdLoc, FieldName, BitList, Val); 2652226584Sdim} 2653226584Sdim 2654226584Sdim/// ParseBody - Read the body of a class or def. Return true on error, false on 2655226584Sdim/// success. 2656226584Sdim/// 2657226584Sdim/// Body ::= ';' 2658226584Sdim/// Body ::= '{' BodyList '}' 2659226584Sdim/// BodyList BodyItem* 2660226584Sdim/// 2661226584Sdimbool TGParser::ParseBody(Record *CurRec) { 2662226584Sdim // If this is a null definition, just eat the semi and return. 2663226584Sdim if (Lex.getCode() == tgtok::semi) { 2664226584Sdim Lex.Lex(); 2665226584Sdim return false; 2666226584Sdim } 2667226584Sdim 2668226584Sdim if (Lex.getCode() != tgtok::l_brace) 2669226584Sdim return TokError("Expected ';' or '{' to start body"); 2670226584Sdim // Eat the '{'. 2671226584Sdim Lex.Lex(); 2672226584Sdim 2673360784Sdim // An object body introduces a new scope for local variables. 2674360784Sdim TGLocalVarScope *BodyScope = PushLocalScope(); 2675360784Sdim 2676226584Sdim while (Lex.getCode() != tgtok::r_brace) 2677226584Sdim if (ParseBodyItem(CurRec)) 2678226584Sdim return true; 2679226584Sdim 2680360784Sdim PopLocalScope(BodyScope); 2681360784Sdim 2682226584Sdim // Eat the '}'. 2683226584Sdim Lex.Lex(); 2684226584Sdim return false; 2685226584Sdim} 2686226584Sdim 2687341825Sdim/// Apply the current let bindings to \a CurRec. 2688249423Sdim/// \returns true on error, false otherwise. 2689249423Sdimbool TGParser::ApplyLetStack(Record *CurRec) { 2690314564Sdim for (SmallVectorImpl<LetRecord> &LetInfo : LetStack) 2691288943Sdim for (LetRecord &LR : LetInfo) 2692288943Sdim if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value)) 2693249423Sdim return true; 2694249423Sdim return false; 2695249423Sdim} 2696249423Sdim 2697341825Sdimbool TGParser::ApplyLetStack(RecordsEntry &Entry) { 2698341825Sdim if (Entry.Rec) 2699341825Sdim return ApplyLetStack(Entry.Rec.get()); 2700341825Sdim 2701341825Sdim for (auto &E : Entry.Loop->Entries) { 2702341825Sdim if (ApplyLetStack(E)) 2703341825Sdim return true; 2704341825Sdim } 2705341825Sdim 2706341825Sdim return false; 2707341825Sdim} 2708341825Sdim 2709226584Sdim/// ParseObjectBody - Parse the body of a def or class. This consists of an 2710226584Sdim/// optional ClassList followed by a Body. CurRec is the current def or class 2711226584Sdim/// that is being parsed. 2712226584Sdim/// 2713226584Sdim/// ObjectBody ::= BaseClassList Body 2714226584Sdim/// BaseClassList ::= /*empty*/ 2715226584Sdim/// BaseClassList ::= ':' BaseClassListNE 2716226584Sdim/// BaseClassListNE ::= SubClassRef (',' SubClassRef)* 2717226584Sdim/// 2718226584Sdimbool TGParser::ParseObjectBody(Record *CurRec) { 2719226584Sdim // If there is a baseclass list, read it. 2720226584Sdim if (Lex.getCode() == tgtok::colon) { 2721226584Sdim Lex.Lex(); 2722226584Sdim 2723226584Sdim // Read all of the subclasses. 2724226584Sdim SubClassReference SubClass = ParseSubClassReference(CurRec, false); 2725314564Sdim while (true) { 2726226584Sdim // Check for error. 2727276479Sdim if (!SubClass.Rec) return true; 2728226584Sdim 2729226584Sdim // Add it. 2730226584Sdim if (AddSubClass(CurRec, SubClass)) 2731226584Sdim return true; 2732226584Sdim 2733226584Sdim if (Lex.getCode() != tgtok::comma) break; 2734226584Sdim Lex.Lex(); // eat ','. 2735226584Sdim SubClass = ParseSubClassReference(CurRec, false); 2736226584Sdim } 2737226584Sdim } 2738226584Sdim 2739249423Sdim if (ApplyLetStack(CurRec)) 2740249423Sdim return true; 2741226584Sdim 2742226584Sdim return ParseBody(CurRec); 2743226584Sdim} 2744226584Sdim 2745226584Sdim/// ParseDef - Parse and return a top level or multiclass def, return the record 2746226584Sdim/// corresponding to it. This returns null on error. 2747226584Sdim/// 2748226584Sdim/// DefInst ::= DEF ObjectName ObjectBody 2749226584Sdim/// 2750226584Sdimbool TGParser::ParseDef(MultiClass *CurMultiClass) { 2751226584Sdim SMLoc DefLoc = Lex.getLoc(); 2752226584Sdim assert(Lex.getCode() == tgtok::Def && "Unknown tok"); 2753226584Sdim Lex.Lex(); // Eat the 'def' token. 2754226584Sdim 2755226584Sdim // Parse ObjectName and make a record for it. 2756341825Sdim std::unique_ptr<Record> CurRec; 2757249423Sdim Init *Name = ParseObjectName(CurMultiClass); 2758341825Sdim if (!Name) 2759341825Sdim return true; 2760341825Sdim 2761341825Sdim if (isa<UnsetInit>(Name)) 2762360784Sdim CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc, Records, 2763341825Sdim /*Anonymous=*/true); 2764249423Sdim else 2765360784Sdim CurRec = std::make_unique<Record>(Name, DefLoc, Records); 2766226584Sdim 2767341825Sdim if (ParseObjectBody(CurRec.get())) 2768341825Sdim return true; 2769226584Sdim 2770341825Sdim return addEntry(std::move(CurRec)); 2771341825Sdim} 2772276479Sdim 2773341825Sdim/// ParseDefset - Parse a defset statement. 2774341825Sdim/// 2775341825Sdim/// Defset ::= DEFSET Type Id '=' '{' ObjectList '}' 2776341825Sdim/// 2777341825Sdimbool TGParser::ParseDefset() { 2778341825Sdim assert(Lex.getCode() == tgtok::Defset); 2779341825Sdim Lex.Lex(); // Eat the 'defset' token 2780276479Sdim 2781341825Sdim DefsetRecord Defset; 2782341825Sdim Defset.Loc = Lex.getLoc(); 2783341825Sdim RecTy *Type = ParseType(); 2784341825Sdim if (!Type) 2785226584Sdim return true; 2786341825Sdim if (!isa<ListRecTy>(Type)) 2787341825Sdim return Error(Defset.Loc, "expected list type"); 2788341825Sdim Defset.EltTy = cast<ListRecTy>(Type)->getElementType(); 2789226584Sdim 2790341825Sdim if (Lex.getCode() != tgtok::Id) 2791341825Sdim return TokError("expected identifier"); 2792341825Sdim StringInit *DeclName = StringInit::get(Lex.getCurStrVal()); 2793341825Sdim if (Records.getGlobal(DeclName->getValue())) 2794341825Sdim return TokError("def or global variable of this name already exists"); 2795226584Sdim 2796341825Sdim if (Lex.Lex() != tgtok::equal) // Eat the identifier 2797341825Sdim return TokError("expected '='"); 2798341825Sdim if (Lex.Lex() != tgtok::l_brace) // Eat the '=' 2799341825Sdim return TokError("expected '{'"); 2800341825Sdim SMLoc BraceLoc = Lex.getLoc(); 2801341825Sdim Lex.Lex(); // Eat the '{' 2802226584Sdim 2803341825Sdim Defsets.push_back(&Defset); 2804341825Sdim bool Err = ParseObjectList(nullptr); 2805341825Sdim Defsets.pop_back(); 2806341825Sdim if (Err) 2807341825Sdim return true; 2808341825Sdim 2809341825Sdim if (Lex.getCode() != tgtok::r_brace) { 2810341825Sdim TokError("expected '}' at end of defset"); 2811341825Sdim return Error(BraceLoc, "to match this '{'"); 2812226584Sdim } 2813341825Sdim Lex.Lex(); // Eat the '}' 2814226584Sdim 2815341825Sdim Records.addExtraGlobal(DeclName->getValue(), 2816341825Sdim ListInit::get(Defset.Elements, Defset.EltTy)); 2817226584Sdim return false; 2818226584Sdim} 2819226584Sdim 2820360784Sdim/// ParseDefvar - Parse a defvar statement. 2821360784Sdim/// 2822360784Sdim/// Defvar ::= DEFVAR Id '=' Value ';' 2823360784Sdim/// 2824360784Sdimbool TGParser::ParseDefvar() { 2825360784Sdim assert(Lex.getCode() == tgtok::Defvar); 2826360784Sdim Lex.Lex(); // Eat the 'defvar' token 2827360784Sdim 2828360784Sdim if (Lex.getCode() != tgtok::Id) 2829360784Sdim return TokError("expected identifier"); 2830360784Sdim StringInit *DeclName = StringInit::get(Lex.getCurStrVal()); 2831360784Sdim if (CurLocalScope) { 2832360784Sdim if (CurLocalScope->varAlreadyDefined(DeclName->getValue())) 2833360784Sdim return TokError("local variable of this name already exists"); 2834360784Sdim } else { 2835360784Sdim if (Records.getGlobal(DeclName->getValue())) 2836360784Sdim return TokError("def or global variable of this name already exists"); 2837360784Sdim } 2838360784Sdim 2839360784Sdim if (Lex.Lex() != tgtok::equal) // Eat the identifier 2840360784Sdim return TokError("expected '='"); 2841360784Sdim Lex.Lex(); // Eat the '=' 2842360784Sdim 2843360784Sdim Init *Value = ParseValue(nullptr); 2844360784Sdim if (!Value) 2845360784Sdim return true; 2846360784Sdim 2847360784Sdim if (Lex.getCode() != tgtok::semi) 2848360784Sdim return TokError("expected ';'"); 2849360784Sdim Lex.Lex(); // Eat the ';' 2850360784Sdim 2851360784Sdim if (CurLocalScope) 2852360784Sdim CurLocalScope->addVar(DeclName->getValue(), Value); 2853360784Sdim else 2854360784Sdim Records.addExtraGlobal(DeclName->getValue(), Value); 2855360784Sdim 2856360784Sdim return false; 2857360784Sdim} 2858360784Sdim 2859234353Sdim/// ParseForeach - Parse a for statement. Return the record corresponding 2860234353Sdim/// to it. This returns true on error. 2861234353Sdim/// 2862234353Sdim/// Foreach ::= FOREACH Declaration IN '{ ObjectList '}' 2863234353Sdim/// Foreach ::= FOREACH Declaration IN Object 2864234353Sdim/// 2865234353Sdimbool TGParser::ParseForeach(MultiClass *CurMultiClass) { 2866341825Sdim SMLoc Loc = Lex.getLoc(); 2867234353Sdim assert(Lex.getCode() == tgtok::Foreach && "Unknown tok"); 2868234353Sdim Lex.Lex(); // Eat the 'for' token. 2869234353Sdim 2870234353Sdim // Make a temporary object to record items associated with the for 2871234353Sdim // loop. 2872341825Sdim Init *ListValue = nullptr; 2873239462Sdim VarInit *IterName = ParseForeachDeclaration(ListValue); 2874276479Sdim if (!IterName) 2875234353Sdim return TokError("expected declaration in for"); 2876234353Sdim 2877234353Sdim if (Lex.getCode() != tgtok::In) 2878234353Sdim return TokError("Unknown tok"); 2879234353Sdim Lex.Lex(); // Eat the in 2880234353Sdim 2881234353Sdim // Create a loop object and remember it. 2882360784Sdim Loops.push_back(std::make_unique<ForeachLoop>(Loc, IterName, ListValue)); 2883234353Sdim 2884360784Sdim // A foreach loop introduces a new scope for local variables. 2885360784Sdim TGLocalVarScope *ForeachScope = PushLocalScope(); 2886360784Sdim 2887234353Sdim if (Lex.getCode() != tgtok::l_brace) { 2888234353Sdim // FOREACH Declaration IN Object 2889234353Sdim if (ParseObject(CurMultiClass)) 2890234353Sdim return true; 2891288943Sdim } else { 2892234353Sdim SMLoc BraceLoc = Lex.getLoc(); 2893234353Sdim // Otherwise, this is a group foreach. 2894234353Sdim Lex.Lex(); // eat the '{'. 2895234353Sdim 2896234353Sdim // Parse the object list. 2897234353Sdim if (ParseObjectList(CurMultiClass)) 2898234353Sdim return true; 2899234353Sdim 2900234353Sdim if (Lex.getCode() != tgtok::r_brace) { 2901234353Sdim TokError("expected '}' at end of foreach command"); 2902234353Sdim return Error(BraceLoc, "to match this '{'"); 2903234353Sdim } 2904234353Sdim Lex.Lex(); // Eat the } 2905234353Sdim } 2906234353Sdim 2907360784Sdim PopLocalScope(ForeachScope); 2908360784Sdim 2909341825Sdim // Resolve the loop or store it for later resolution. 2910341825Sdim std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back()); 2911234353Sdim Loops.pop_back(); 2912234353Sdim 2913341825Sdim return addEntry(std::move(Loop)); 2914234353Sdim} 2915234353Sdim 2916360784Sdim/// ParseIf - Parse an if statement. 2917360784Sdim/// 2918360784Sdim/// If ::= IF Value THEN IfBody 2919360784Sdim/// If ::= IF Value THEN IfBody ELSE IfBody 2920360784Sdim/// 2921360784Sdimbool TGParser::ParseIf(MultiClass *CurMultiClass) { 2922360784Sdim SMLoc Loc = Lex.getLoc(); 2923360784Sdim assert(Lex.getCode() == tgtok::If && "Unknown tok"); 2924360784Sdim Lex.Lex(); // Eat the 'if' token. 2925360784Sdim 2926360784Sdim // Make a temporary object to record items associated with the for 2927360784Sdim // loop. 2928360784Sdim Init *Condition = ParseValue(nullptr); 2929360784Sdim if (!Condition) 2930360784Sdim return true; 2931360784Sdim 2932360784Sdim if (Lex.getCode() != tgtok::Then) 2933360784Sdim return TokError("Unknown tok"); 2934360784Sdim Lex.Lex(); // Eat the 'then' 2935360784Sdim 2936360784Sdim // We have to be able to save if statements to execute later, and they have 2937360784Sdim // to live on the same stack as foreach loops. The simplest implementation 2938360784Sdim // technique is to convert each 'then' or 'else' clause *into* a foreach 2939360784Sdim // loop, over a list of length 0 or 1 depending on the condition, and with no 2940360784Sdim // iteration variable being assigned. 2941360784Sdim 2942360784Sdim ListInit *EmptyList = ListInit::get({}, BitRecTy::get()); 2943360784Sdim ListInit *SingletonList = ListInit::get({BitInit::get(1)}, BitRecTy::get()); 2944360784Sdim RecTy *BitListTy = ListRecTy::get(BitRecTy::get()); 2945360784Sdim 2946360784Sdim // The foreach containing the then-clause selects SingletonList if 2947360784Sdim // the condition is true. 2948360784Sdim Init *ThenClauseList = 2949360784Sdim TernOpInit::get(TernOpInit::IF, Condition, SingletonList, EmptyList, 2950360784Sdim BitListTy) 2951360784Sdim ->Fold(nullptr); 2952360784Sdim Loops.push_back(std::make_unique<ForeachLoop>(Loc, nullptr, ThenClauseList)); 2953360784Sdim 2954360784Sdim if (ParseIfBody(CurMultiClass, "then")) 2955360784Sdim return true; 2956360784Sdim 2957360784Sdim std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back()); 2958360784Sdim Loops.pop_back(); 2959360784Sdim 2960360784Sdim if (addEntry(std::move(Loop))) 2961360784Sdim return true; 2962360784Sdim 2963360784Sdim // Now look for an optional else clause. The if-else syntax has the usual 2964360784Sdim // dangling-else ambiguity, and by greedily matching an else here if we can, 2965360784Sdim // we implement the usual resolution of pairing with the innermost unmatched 2966360784Sdim // if. 2967360784Sdim if (Lex.getCode() == tgtok::ElseKW) { 2968360784Sdim Lex.Lex(); // Eat the 'else' 2969360784Sdim 2970360784Sdim // The foreach containing the else-clause uses the same pair of lists as 2971360784Sdim // above, but this time, selects SingletonList if the condition is *false*. 2972360784Sdim Init *ElseClauseList = 2973360784Sdim TernOpInit::get(TernOpInit::IF, Condition, EmptyList, SingletonList, 2974360784Sdim BitListTy) 2975360784Sdim ->Fold(nullptr); 2976360784Sdim Loops.push_back( 2977360784Sdim std::make_unique<ForeachLoop>(Loc, nullptr, ElseClauseList)); 2978360784Sdim 2979360784Sdim if (ParseIfBody(CurMultiClass, "else")) 2980360784Sdim return true; 2981360784Sdim 2982360784Sdim Loop = std::move(Loops.back()); 2983360784Sdim Loops.pop_back(); 2984360784Sdim 2985360784Sdim if (addEntry(std::move(Loop))) 2986360784Sdim return true; 2987360784Sdim } 2988360784Sdim 2989360784Sdim return false; 2990360784Sdim} 2991360784Sdim 2992360784Sdim/// ParseIfBody - Parse the then-clause or else-clause of an if statement. 2993360784Sdim/// 2994360784Sdim/// IfBody ::= Object 2995360784Sdim/// IfBody ::= '{' ObjectList '}' 2996360784Sdim/// 2997360784Sdimbool TGParser::ParseIfBody(MultiClass *CurMultiClass, StringRef Kind) { 2998360784Sdim TGLocalVarScope *BodyScope = PushLocalScope(); 2999360784Sdim 3000360784Sdim if (Lex.getCode() != tgtok::l_brace) { 3001360784Sdim // A single object. 3002360784Sdim if (ParseObject(CurMultiClass)) 3003360784Sdim return true; 3004360784Sdim } else { 3005360784Sdim SMLoc BraceLoc = Lex.getLoc(); 3006360784Sdim // A braced block. 3007360784Sdim Lex.Lex(); // eat the '{'. 3008360784Sdim 3009360784Sdim // Parse the object list. 3010360784Sdim if (ParseObjectList(CurMultiClass)) 3011360784Sdim return true; 3012360784Sdim 3013360784Sdim if (Lex.getCode() != tgtok::r_brace) { 3014360784Sdim TokError("expected '}' at end of '" + Kind + "' clause"); 3015360784Sdim return Error(BraceLoc, "to match this '{'"); 3016360784Sdim } 3017360784Sdim 3018360784Sdim Lex.Lex(); // Eat the } 3019360784Sdim } 3020360784Sdim 3021360784Sdim PopLocalScope(BodyScope); 3022360784Sdim return false; 3023360784Sdim} 3024360784Sdim 3025226584Sdim/// ParseClass - Parse a tblgen class definition. 3026226584Sdim/// 3027226584Sdim/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody 3028226584Sdim/// 3029226584Sdimbool TGParser::ParseClass() { 3030226584Sdim assert(Lex.getCode() == tgtok::Class && "Unexpected token!"); 3031226584Sdim Lex.Lex(); 3032226584Sdim 3033226584Sdim if (Lex.getCode() != tgtok::Id) 3034226584Sdim return TokError("expected class name after 'class' keyword"); 3035226584Sdim 3036226584Sdim Record *CurRec = Records.getClass(Lex.getCurStrVal()); 3037226584Sdim if (CurRec) { 3038226584Sdim // If the body was previously defined, this is an error. 3039341825Sdim if (!CurRec->getValues().empty() || 3040226584Sdim !CurRec->getSuperClasses().empty() || 3041226584Sdim !CurRec->getTemplateArgs().empty()) 3042288943Sdim return TokError("Class '" + CurRec->getNameInitAsString() + 3043288943Sdim "' already defined"); 3044226584Sdim } else { 3045226584Sdim // If this is the first reference to this class, create and add it. 3046280031Sdim auto NewRec = 3047360784Sdim std::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(), Records, 3048341825Sdim /*Class=*/true); 3049280031Sdim CurRec = NewRec.get(); 3050280031Sdim Records.addClass(std::move(NewRec)); 3051226584Sdim } 3052226584Sdim Lex.Lex(); // eat the name. 3053226584Sdim 3054226584Sdim // If there are template args, parse them. 3055226584Sdim if (Lex.getCode() == tgtok::less) 3056226584Sdim if (ParseTemplateArgList(CurRec)) 3057226584Sdim return true; 3058226584Sdim 3059226584Sdim return ParseObjectBody(CurRec); 3060226584Sdim} 3061226584Sdim 3062226584Sdim/// ParseLetList - Parse a non-empty list of assignment expressions into a list 3063226584Sdim/// of LetRecords. 3064226584Sdim/// 3065226584Sdim/// LetList ::= LetItem (',' LetItem)* 3066226584Sdim/// LetItem ::= ID OptionalRangeList '=' Value 3067226584Sdim/// 3068314564Sdimvoid TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) { 3069314564Sdim while (true) { 3070226584Sdim if (Lex.getCode() != tgtok::Id) { 3071226584Sdim TokError("expected identifier in let definition"); 3072314564Sdim Result.clear(); 3073314564Sdim return; 3074226584Sdim } 3075314564Sdim 3076314564Sdim StringInit *Name = StringInit::get(Lex.getCurStrVal()); 3077226584Sdim SMLoc NameLoc = Lex.getLoc(); 3078226584Sdim Lex.Lex(); // Eat the identifier. 3079226584Sdim 3080226584Sdim // Check for an optional RangeList. 3081314564Sdim SmallVector<unsigned, 16> Bits; 3082314564Sdim if (ParseOptionalRangeList(Bits)) { 3083314564Sdim Result.clear(); 3084314564Sdim return; 3085314564Sdim } 3086226584Sdim std::reverse(Bits.begin(), Bits.end()); 3087226584Sdim 3088226584Sdim if (Lex.getCode() != tgtok::equal) { 3089226584Sdim TokError("expected '=' in let expression"); 3090314564Sdim Result.clear(); 3091314564Sdim return; 3092226584Sdim } 3093226584Sdim Lex.Lex(); // eat the '='. 3094226584Sdim 3095276479Sdim Init *Val = ParseValue(nullptr); 3096314564Sdim if (!Val) { 3097314564Sdim Result.clear(); 3098314564Sdim return; 3099314564Sdim } 3100226584Sdim 3101226584Sdim // Now that we have everything, add the record. 3102314564Sdim Result.emplace_back(Name, Bits, Val, NameLoc); 3103226584Sdim 3104226584Sdim if (Lex.getCode() != tgtok::comma) 3105314564Sdim return; 3106226584Sdim Lex.Lex(); // eat the comma. 3107226584Sdim } 3108226584Sdim} 3109226584Sdim 3110226584Sdim/// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of 3111226584Sdim/// different related productions. This works inside multiclasses too. 3112226584Sdim/// 3113226584Sdim/// Object ::= LET LetList IN '{' ObjectList '}' 3114226584Sdim/// Object ::= LET LetList IN Object 3115226584Sdim/// 3116226584Sdimbool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) { 3117226584Sdim assert(Lex.getCode() == tgtok::Let && "Unexpected token"); 3118226584Sdim Lex.Lex(); 3119226584Sdim 3120226584Sdim // Add this entry to the let stack. 3121314564Sdim SmallVector<LetRecord, 8> LetInfo; 3122314564Sdim ParseLetList(LetInfo); 3123226584Sdim if (LetInfo.empty()) return true; 3124280031Sdim LetStack.push_back(std::move(LetInfo)); 3125226584Sdim 3126226584Sdim if (Lex.getCode() != tgtok::In) 3127226584Sdim return TokError("expected 'in' at end of top-level 'let'"); 3128226584Sdim Lex.Lex(); 3129226584Sdim 3130360784Sdim TGLocalVarScope *LetScope = PushLocalScope(); 3131360784Sdim 3132226584Sdim // If this is a scalar let, just handle it now 3133226584Sdim if (Lex.getCode() != tgtok::l_brace) { 3134226584Sdim // LET LetList IN Object 3135226584Sdim if (ParseObject(CurMultiClass)) 3136226584Sdim return true; 3137226584Sdim } else { // Object ::= LETCommand '{' ObjectList '}' 3138226584Sdim SMLoc BraceLoc = Lex.getLoc(); 3139226584Sdim // Otherwise, this is a group let. 3140226584Sdim Lex.Lex(); // eat the '{'. 3141226584Sdim 3142226584Sdim // Parse the object list. 3143226584Sdim if (ParseObjectList(CurMultiClass)) 3144226584Sdim return true; 3145226584Sdim 3146226584Sdim if (Lex.getCode() != tgtok::r_brace) { 3147226584Sdim TokError("expected '}' at end of top level let command"); 3148226584Sdim return Error(BraceLoc, "to match this '{'"); 3149226584Sdim } 3150226584Sdim Lex.Lex(); 3151226584Sdim } 3152226584Sdim 3153360784Sdim PopLocalScope(LetScope); 3154360784Sdim 3155226584Sdim // Outside this let scope, this let block is not active. 3156226584Sdim LetStack.pop_back(); 3157226584Sdim return false; 3158226584Sdim} 3159226584Sdim 3160226584Sdim/// ParseMultiClass - Parse a multiclass definition. 3161226584Sdim/// 3162226584Sdim/// MultiClassInst ::= MULTICLASS ID TemplateArgList? 3163249423Sdim/// ':' BaseMultiClassList '{' MultiClassObject+ '}' 3164249423Sdim/// MultiClassObject ::= DefInst 3165249423Sdim/// MultiClassObject ::= MultiClassInst 3166249423Sdim/// MultiClassObject ::= DefMInst 3167249423Sdim/// MultiClassObject ::= LETCommand '{' ObjectList '}' 3168249423Sdim/// MultiClassObject ::= LETCommand Object 3169226584Sdim/// 3170226584Sdimbool TGParser::ParseMultiClass() { 3171226584Sdim assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token"); 3172226584Sdim Lex.Lex(); // Eat the multiclass token. 3173226584Sdim 3174226584Sdim if (Lex.getCode() != tgtok::Id) 3175226584Sdim return TokError("expected identifier after multiclass for name"); 3176226584Sdim std::string Name = Lex.getCurStrVal(); 3177226584Sdim 3178280031Sdim auto Result = 3179280031Sdim MultiClasses.insert(std::make_pair(Name, 3180360784Sdim std::make_unique<MultiClass>(Name, Lex.getLoc(),Records))); 3181280031Sdim 3182280031Sdim if (!Result.second) 3183226584Sdim return TokError("multiclass '" + Name + "' already defined"); 3184226584Sdim 3185280031Sdim CurMultiClass = Result.first->second.get(); 3186226584Sdim Lex.Lex(); // Eat the identifier. 3187226584Sdim 3188226584Sdim // If there are template args, parse them. 3189226584Sdim if (Lex.getCode() == tgtok::less) 3190276479Sdim if (ParseTemplateArgList(nullptr)) 3191226584Sdim return true; 3192226584Sdim 3193226584Sdim bool inherits = false; 3194226584Sdim 3195226584Sdim // If there are submulticlasses, parse them. 3196226584Sdim if (Lex.getCode() == tgtok::colon) { 3197226584Sdim inherits = true; 3198226584Sdim 3199226584Sdim Lex.Lex(); 3200226584Sdim 3201226584Sdim // Read all of the submulticlasses. 3202226584Sdim SubMultiClassReference SubMultiClass = 3203226584Sdim ParseSubMultiClassReference(CurMultiClass); 3204314564Sdim while (true) { 3205226584Sdim // Check for error. 3206276479Sdim if (!SubMultiClass.MC) return true; 3207226584Sdim 3208226584Sdim // Add it. 3209226584Sdim if (AddSubMultiClass(CurMultiClass, SubMultiClass)) 3210226584Sdim return true; 3211226584Sdim 3212226584Sdim if (Lex.getCode() != tgtok::comma) break; 3213226584Sdim Lex.Lex(); // eat ','. 3214226584Sdim SubMultiClass = ParseSubMultiClassReference(CurMultiClass); 3215226584Sdim } 3216226584Sdim } 3217226584Sdim 3218226584Sdim if (Lex.getCode() != tgtok::l_brace) { 3219226584Sdim if (!inherits) 3220226584Sdim return TokError("expected '{' in multiclass definition"); 3221280031Sdim if (Lex.getCode() != tgtok::semi) 3222226584Sdim return TokError("expected ';' in multiclass definition"); 3223280031Sdim Lex.Lex(); // eat the ';'. 3224226584Sdim } else { 3225226584Sdim if (Lex.Lex() == tgtok::r_brace) // eat the '{'. 3226226584Sdim return TokError("multiclass must contain at least one def"); 3227226584Sdim 3228360784Sdim // A multiclass body introduces a new scope for local variables. 3229360784Sdim TGLocalVarScope *MulticlassScope = PushLocalScope(); 3230360784Sdim 3231226584Sdim while (Lex.getCode() != tgtok::r_brace) { 3232226584Sdim switch (Lex.getCode()) { 3233280031Sdim default: 3234360784Sdim return TokError("expected 'let', 'def', 'defm', 'defvar', 'foreach' " 3235360784Sdim "or 'if' in multiclass body"); 3236280031Sdim case tgtok::Let: 3237280031Sdim case tgtok::Def: 3238280031Sdim case tgtok::Defm: 3239360784Sdim case tgtok::Defvar: 3240280031Sdim case tgtok::Foreach: 3241360784Sdim case tgtok::If: 3242280031Sdim if (ParseObject(CurMultiClass)) 3243280031Sdim return true; 3244280031Sdim break; 3245226584Sdim } 3246226584Sdim } 3247226584Sdim Lex.Lex(); // eat the '}'. 3248360784Sdim 3249360784Sdim PopLocalScope(MulticlassScope); 3250226584Sdim } 3251226584Sdim 3252276479Sdim CurMultiClass = nullptr; 3253226584Sdim return false; 3254226584Sdim} 3255226584Sdim 3256226584Sdim/// ParseDefm - Parse the instantiation of a multiclass. 3257226584Sdim/// 3258226584Sdim/// DefMInst ::= DEFM ID ':' DefmSubClassRef ';' 3259226584Sdim/// 3260226584Sdimbool TGParser::ParseDefm(MultiClass *CurMultiClass) { 3261226584Sdim assert(Lex.getCode() == tgtok::Defm && "Unexpected token!"); 3262341825Sdim Lex.Lex(); // eat the defm 3263234353Sdim 3264341825Sdim Init *DefmName = ParseObjectName(CurMultiClass); 3265341825Sdim if (!DefmName) 3266341825Sdim return true; 3267341825Sdim if (isa<UnsetInit>(DefmName)) { 3268341825Sdim DefmName = Records.getNewAnonymousName(); 3269341825Sdim if (CurMultiClass) 3270341825Sdim DefmName = BinOpInit::getStrConcat( 3271341825Sdim VarInit::get(QualifiedNameOfImplicitName(CurMultiClass), 3272341825Sdim StringRecTy::get()), 3273341825Sdim DefmName); 3274226584Sdim } 3275226584Sdim 3276226584Sdim if (Lex.getCode() != tgtok::colon) 3277226584Sdim return TokError("expected ':' after defm identifier"); 3278226584Sdim 3279226584Sdim // Keep track of the new generated record definitions. 3280341825Sdim std::vector<RecordsEntry> NewEntries; 3281226584Sdim 3282226584Sdim // This record also inherits from a regular class (non-multiclass)? 3283226584Sdim bool InheritFromClass = false; 3284226584Sdim 3285226584Sdim // eat the colon. 3286226584Sdim Lex.Lex(); 3287226584Sdim 3288226584Sdim SMLoc SubClassLoc = Lex.getLoc(); 3289276479Sdim SubClassReference Ref = ParseSubClassReference(nullptr, true); 3290226584Sdim 3291314564Sdim while (true) { 3292276479Sdim if (!Ref.Rec) return true; 3293226584Sdim 3294226584Sdim // To instantiate a multiclass, we need to first get the multiclass, then 3295226584Sdim // instantiate each def contained in the multiclass with the SubClassRef 3296226584Sdim // template parameters. 3297280031Sdim MultiClass *MC = MultiClasses[Ref.Rec->getName()].get(); 3298226584Sdim assert(MC && "Didn't lookup multiclass correctly?"); 3299314564Sdim ArrayRef<Init*> TemplateVals = Ref.TemplateArgs; 3300226584Sdim 3301226584Sdim // Verify that the correct number of template arguments were specified. 3302296417Sdim ArrayRef<Init *> TArgs = MC->Rec.getTemplateArgs(); 3303226584Sdim if (TArgs.size() < TemplateVals.size()) 3304226584Sdim return Error(SubClassLoc, 3305226584Sdim "more template args specified than multiclass expects"); 3306226584Sdim 3307341825Sdim SubstStack Substs; 3308341825Sdim for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { 3309341825Sdim if (i < TemplateVals.size()) { 3310341825Sdim Substs.emplace_back(TArgs[i], TemplateVals[i]); 3311341825Sdim } else { 3312341825Sdim Init *Default = MC->Rec.getValue(TArgs[i])->getValue(); 3313341825Sdim if (!Default->isComplete()) { 3314341825Sdim return Error(SubClassLoc, 3315341825Sdim "value not specified for template argument #" + 3316341825Sdim Twine(i) + " (" + TArgs[i]->getAsUnquotedString() + 3317341825Sdim ") of multiclass '" + MC->Rec.getNameInitAsString() + 3318341825Sdim "'"); 3319341825Sdim } 3320341825Sdim Substs.emplace_back(TArgs[i], Default); 3321280031Sdim } 3322226584Sdim } 3323226584Sdim 3324341825Sdim Substs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName); 3325226584Sdim 3326341825Sdim if (resolve(MC->Entries, Substs, CurMultiClass == nullptr, &NewEntries, 3327341825Sdim &SubClassLoc)) 3328341825Sdim return true; 3329341825Sdim 3330226584Sdim if (Lex.getCode() != tgtok::comma) break; 3331226584Sdim Lex.Lex(); // eat ','. 3332226584Sdim 3333261991Sdim if (Lex.getCode() != tgtok::Id) 3334261991Sdim return TokError("expected identifier"); 3335261991Sdim 3336226584Sdim SubClassLoc = Lex.getLoc(); 3337226584Sdim 3338226584Sdim // A defm can inherit from regular classes (non-multiclass) as 3339226584Sdim // long as they come in the end of the inheritance list. 3340276479Sdim InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr); 3341226584Sdim 3342226584Sdim if (InheritFromClass) 3343226584Sdim break; 3344226584Sdim 3345276479Sdim Ref = ParseSubClassReference(nullptr, true); 3346226584Sdim } 3347226584Sdim 3348226584Sdim if (InheritFromClass) { 3349226584Sdim // Process all the classes to inherit as if they were part of a 3350226584Sdim // regular 'def' and inherit all record values. 3351276479Sdim SubClassReference SubClass = ParseSubClassReference(nullptr, false); 3352314564Sdim while (true) { 3353226584Sdim // Check for error. 3354276479Sdim if (!SubClass.Rec) return true; 3355226584Sdim 3356226584Sdim // Get the expanded definition prototypes and teach them about 3357226584Sdim // the record values the current class to inherit has 3358341825Sdim for (auto &E : NewEntries) { 3359226584Sdim // Add it. 3360341825Sdim if (AddSubClass(E, SubClass)) 3361226584Sdim return true; 3362226584Sdim } 3363226584Sdim 3364226584Sdim if (Lex.getCode() != tgtok::comma) break; 3365226584Sdim Lex.Lex(); // eat ','. 3366276479Sdim SubClass = ParseSubClassReference(nullptr, false); 3367226584Sdim } 3368226584Sdim } 3369226584Sdim 3370341825Sdim for (auto &E : NewEntries) { 3371341825Sdim if (ApplyLetStack(E)) 3372341825Sdim return true; 3373226584Sdim 3374341825Sdim addEntry(std::move(E)); 3375341825Sdim } 3376341825Sdim 3377226584Sdim if (Lex.getCode() != tgtok::semi) 3378226584Sdim return TokError("expected ';' at end of defm"); 3379226584Sdim Lex.Lex(); 3380226584Sdim 3381226584Sdim return false; 3382226584Sdim} 3383226584Sdim 3384226584Sdim/// ParseObject 3385226584Sdim/// Object ::= ClassInst 3386226584Sdim/// Object ::= DefInst 3387226584Sdim/// Object ::= MultiClassInst 3388226584Sdim/// Object ::= DefMInst 3389226584Sdim/// Object ::= LETCommand '{' ObjectList '}' 3390226584Sdim/// Object ::= LETCommand Object 3391360784Sdim/// Object ::= Defset 3392360784Sdim/// Object ::= Defvar 3393226584Sdimbool TGParser::ParseObject(MultiClass *MC) { 3394226584Sdim switch (Lex.getCode()) { 3395226584Sdim default: 3396360784Sdim return TokError("Expected class, def, defm, defset, multiclass, let, " 3397360784Sdim "foreach or if"); 3398226584Sdim case tgtok::Let: return ParseTopLevelLet(MC); 3399226584Sdim case tgtok::Def: return ParseDef(MC); 3400234353Sdim case tgtok::Foreach: return ParseForeach(MC); 3401360784Sdim case tgtok::If: return ParseIf(MC); 3402226584Sdim case tgtok::Defm: return ParseDefm(MC); 3403341825Sdim case tgtok::Defset: 3404341825Sdim if (MC) 3405341825Sdim return TokError("defset is not allowed inside multiclass"); 3406341825Sdim return ParseDefset(); 3407360784Sdim case tgtok::Defvar: 3408360784Sdim return ParseDefvar(); 3409341825Sdim case tgtok::Class: 3410341825Sdim if (MC) 3411341825Sdim return TokError("class is not allowed inside multiclass"); 3412341825Sdim if (!Loops.empty()) 3413341825Sdim return TokError("class is not allowed inside foreach loop"); 3414341825Sdim return ParseClass(); 3415341825Sdim case tgtok::MultiClass: 3416341825Sdim if (!Loops.empty()) 3417341825Sdim return TokError("multiclass is not allowed inside foreach loop"); 3418341825Sdim return ParseMultiClass(); 3419226584Sdim } 3420226584Sdim} 3421226584Sdim 3422226584Sdim/// ParseObjectList 3423226584Sdim/// ObjectList :== Object* 3424226584Sdimbool TGParser::ParseObjectList(MultiClass *MC) { 3425226584Sdim while (isObjectStart(Lex.getCode())) { 3426226584Sdim if (ParseObject(MC)) 3427226584Sdim return true; 3428226584Sdim } 3429226584Sdim return false; 3430226584Sdim} 3431226584Sdim 3432226584Sdimbool TGParser::ParseFile() { 3433226584Sdim Lex.Lex(); // Prime the lexer. 3434226584Sdim if (ParseObjectList()) return true; 3435226584Sdim 3436226584Sdim // If we have unread input at the end of the file, report it. 3437226584Sdim if (Lex.getCode() == tgtok::Eof) 3438226584Sdim return false; 3439226584Sdim 3440226584Sdim return TokError("Unexpected input at top level"); 3441226584Sdim} 3442341825Sdim 3443341825Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 3444341825SdimLLVM_DUMP_METHOD void RecordsEntry::dump() const { 3445341825Sdim if (Loop) 3446341825Sdim Loop->dump(); 3447341825Sdim if (Rec) 3448341825Sdim Rec->dump(); 3449341825Sdim} 3450341825Sdim 3451341825SdimLLVM_DUMP_METHOD void ForeachLoop::dump() const { 3452341825Sdim errs() << "foreach " << IterVar->getAsString() << " = " 3453341825Sdim << ListValue->getAsString() << " in {\n"; 3454341825Sdim 3455341825Sdim for (const auto &E : Entries) 3456341825Sdim E.dump(); 3457341825Sdim 3458341825Sdim errs() << "}\n"; 3459341825Sdim} 3460341825Sdim 3461341825SdimLLVM_DUMP_METHOD void MultiClass::dump() const { 3462341825Sdim errs() << "Record:\n"; 3463341825Sdim Rec.dump(); 3464341825Sdim 3465341825Sdim errs() << "Defs:\n"; 3466341825Sdim for (const auto &E : Entries) 3467341825Sdim E.dump(); 3468341825Sdim} 3469341825Sdim#endif 3470