4674 lines · cpp
1//===- TGParser.cpp - Parser for TableGen Files ---------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Implement the Parser for TableGen.10//11//===----------------------------------------------------------------------===//12 13#include "TGParser.h"14#include "TGLexer.h"15#include "llvm/ADT/SmallVector.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/ADT/Twine.h"18#include "llvm/Config/llvm-config.h"19#include "llvm/Support/Casting.h"20#include "llvm/Support/Compiler.h"21#include "llvm/Support/ErrorHandling.h"22#include "llvm/Support/raw_ostream.h"23#include <algorithm>24#include <cassert>25#include <cstdint>26#include <limits>27 28using namespace llvm;29 30//===----------------------------------------------------------------------===//31// Support Code for the Semantic Actions.32//===----------------------------------------------------------------------===//33 34RecordsEntry::RecordsEntry(std::unique_ptr<Record> Rec) : Rec(std::move(Rec)) {}35RecordsEntry::RecordsEntry(std::unique_ptr<ForeachLoop> Loop)36 : Loop(std::move(Loop)) {}37RecordsEntry::RecordsEntry(std::unique_ptr<Record::AssertionInfo> Assertion)38 : Assertion(std::move(Assertion)) {}39RecordsEntry::RecordsEntry(std::unique_ptr<Record::DumpInfo> Dump)40 : Dump(std::move(Dump)) {}41 42namespace llvm {43struct SubClassReference {44 SMRange RefRange;45 const Record *Rec = nullptr;46 SmallVector<const ArgumentInit *, 4> TemplateArgs;47 48 SubClassReference() = default;49 50 bool isInvalid() const { return Rec == nullptr; }51};52 53struct SubMultiClassReference {54 SMRange RefRange;55 MultiClass *MC = nullptr;56 SmallVector<const ArgumentInit *, 4> TemplateArgs;57 58 SubMultiClassReference() = default;59 60 bool isInvalid() const { return MC == nullptr; }61 void dump() const;62};63} // end namespace llvm64 65#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)66LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {67 errs() << "Multiclass:\n";68 69 MC->dump();70 71 errs() << "Template args:\n";72 for (const Init *TA : TemplateArgs)73 TA->dump();74}75#endif76 77static bool checkBitsConcrete(Record &R, const RecordVal &RV) {78 const auto *BV = cast<BitsInit>(RV.getValue());79 for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {80 const Init *Bit = BV->getBit(i);81 bool IsReference = false;82 if (const auto *VBI = dyn_cast<VarBitInit>(Bit)) {83 if (const auto *VI = dyn_cast<VarInit>(VBI->getBitVar())) {84 if (R.getValue(VI->getName()))85 IsReference = true;86 }87 } else if (isa<VarInit>(Bit)) {88 IsReference = true;89 }90 if (!(IsReference || Bit->isConcrete()))91 return false;92 }93 return true;94}95 96static void checkConcrete(Record &R) {97 for (const RecordVal &RV : R.getValues()) {98 // HACK: Disable this check for variables declared with 'field'. This is99 // done merely because existing targets have legitimate cases of100 // non-concrete variables in helper defs. Ideally, we'd introduce a101 // 'maybe' or 'optional' modifier instead of this.102 if (RV.isNonconcreteOK())103 continue;104 105 if (const Init *V = RV.getValue()) {106 bool Ok = isa<BitsInit>(V) ? checkBitsConcrete(R, RV) : V->isConcrete();107 if (!Ok) {108 PrintError(R.getLoc(), Twine("Initializer of '") +109 RV.getNameInitAsString() + "' in '" +110 R.getNameInitAsString() +111 "' could not be fully resolved: " +112 RV.getValue()->getAsString());113 }114 }115 }116}117 118/// Return an Init with a qualifier prefix referring119/// to CurRec's name.120static const Init *QualifyName(const Record &CurRec, const Init *Name) {121 RecordKeeper &RK = CurRec.getRecords();122 const Init *NewName = BinOpInit::getStrConcat(123 CurRec.getNameInit(),124 StringInit::get(RK, CurRec.isMultiClass() ? "::" : ":"));125 NewName = BinOpInit::getStrConcat(NewName, Name);126 127 if (const auto *BinOp = dyn_cast<BinOpInit>(NewName))128 NewName = BinOp->Fold(&CurRec);129 return NewName;130}131 132static const Init *QualifyName(MultiClass *MC, const Init *Name) {133 return QualifyName(MC->Rec, Name);134}135 136/// Return the qualified version of the implicit 'NAME' template argument.137static const Init *QualifiedNameOfImplicitName(const Record &Rec) {138 return QualifyName(Rec, StringInit::get(Rec.getRecords(), "NAME"));139}140 141static const Init *QualifiedNameOfImplicitName(MultiClass *MC) {142 return QualifiedNameOfImplicitName(MC->Rec);143}144 145const Init *TGVarScope::getVar(RecordKeeper &Records,146 MultiClass *ParsingMultiClass,147 const StringInit *Name, SMRange NameLoc,148 bool TrackReferenceLocs) const {149 // First, we search in local variables.150 auto It = Vars.find(Name->getValue());151 if (It != Vars.end())152 return It->second;153 154 auto FindValueInArgs = [&](Record *Rec,155 const StringInit *Name) -> const Init * {156 if (!Rec)157 return nullptr;158 const Init *ArgName = QualifyName(*Rec, Name);159 if (Rec->isTemplateArg(ArgName)) {160 RecordVal *RV = Rec->getValue(ArgName);161 assert(RV && "Template arg doesn't exist??");162 RV->setUsed(true);163 if (TrackReferenceLocs)164 RV->addReferenceLoc(NameLoc);165 return VarInit::get(ArgName, RV->getType());166 }167 return Name->getValue() == "NAME"168 ? VarInit::get(ArgName, StringRecTy::get(Records))169 : nullptr;170 };171 172 // If not found, we try to find the variable in additional variables like173 // arguments, loop iterator, etc.174 switch (Kind) {175 case SK_Local:176 break; /* do nothing. */177 case SK_Record: {178 if (CurRec) {179 // The variable is a record field?180 if (RecordVal *RV = CurRec->getValue(Name)) {181 if (TrackReferenceLocs)182 RV->addReferenceLoc(NameLoc);183 return VarInit::get(Name, RV->getType());184 }185 186 // The variable is a class template argument?187 if (CurRec->isClass())188 if (auto *V = FindValueInArgs(CurRec, Name))189 return V;190 }191 break;192 }193 case SK_ForeachLoop: {194 // The variable is a loop iterator?195 if (CurLoop->IterVar) {196 const auto *IterVar = dyn_cast<VarInit>(CurLoop->IterVar);197 if (IterVar && IterVar->getNameInit() == Name)198 return IterVar;199 }200 break;201 }202 case SK_MultiClass: {203 // The variable is a multiclass template argument?204 if (CurMultiClass)205 if (auto *V = FindValueInArgs(&CurMultiClass->Rec, Name))206 return V;207 break;208 }209 }210 211 // Then, we try to find the name in parent scope.212 if (Parent)213 return Parent->getVar(Records, ParsingMultiClass, Name, NameLoc,214 TrackReferenceLocs);215 216 return nullptr;217}218 219bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {220 if (!CurRec)221 CurRec = &CurMultiClass->Rec;222 223 if (RecordVal *ERV = CurRec->getValue(RV.getNameInit())) {224 // The value already exists in the class, treat this as a set.225 if (ERV->setValue(RV.getValue()))226 return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +227 RV.getType()->getAsString() +228 "' is incompatible with " +229 "previous definition of type '" +230 ERV->getType()->getAsString() + "'");231 } else {232 CurRec->addValue(RV);233 }234 return false;235}236 237/// SetValue -238/// Return true on error, false on success.239bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const Init *ValName,240 ArrayRef<unsigned> BitList, const Init *V,241 bool AllowSelfAssignment, bool OverrideDefLoc) {242 if (!V)243 return false;244 245 if (!CurRec)246 CurRec = &CurMultiClass->Rec;247 248 RecordVal *RV = CurRec->getValue(ValName);249 if (!RV)250 return Error(Loc,251 "Value '" + ValName->getAsUnquotedString() + "' unknown!");252 253 // Do not allow assignments like 'X = X'. This will just cause infinite loops254 // in the resolution machinery.255 if (BitList.empty())256 if (const auto *VI = dyn_cast<VarInit>(V))257 if (VI->getNameInit() == ValName && !AllowSelfAssignment)258 return Error(Loc, "Recursion / self-assignment forbidden");259 260 // If we are assigning to a subset of the bits in the value we must be261 // assigning to a field of BitsRecTy, which must have a BitsInit initializer.262 if (!BitList.empty()) {263 const auto *CurVal = dyn_cast<BitsInit>(RV->getValue());264 if (!CurVal)265 return Error(Loc, "Value '" + ValName->getAsUnquotedString() +266 "' is not a bits type");267 268 // Convert the incoming value to a bits type of the appropriate size...269 const Init *BI = V->getCastTo(BitsRecTy::get(Records, BitList.size()));270 if (!BI)271 return Error(Loc, "Initializer is not compatible with bit range");272 273 SmallVector<const Init *, 16> NewBits(CurVal->getNumBits());274 275 // Loop over bits, assigning values as appropriate.276 for (unsigned i = 0, e = BitList.size(); i != e; ++i) {277 unsigned Bit = BitList[i];278 if (NewBits[Bit])279 return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" +280 ValName->getAsUnquotedString() +281 "' more than once");282 NewBits[Bit] = BI->getBit(i);283 }284 285 for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)286 if (!NewBits[i])287 NewBits[i] = CurVal->getBit(i);288 289 V = BitsInit::get(Records, NewBits);290 }291 292 if (OverrideDefLoc ? RV->setValue(V, Loc) : RV->setValue(V)) {293 std::string InitType;294 if (const auto *BI = dyn_cast<BitsInit>(V))295 InitType = (Twine("' of type bit initializer with length ") +296 Twine(BI->getNumBits()))297 .str();298 else if (const auto *TI = dyn_cast<TypedInit>(V))299 InitType =300 (Twine("' of type '") + TI->getType()->getAsString() + "'").str();301 302 return Error(Loc, "Field '" + ValName->getAsUnquotedString() +303 "' of type '" + RV->getType()->getAsString() +304 "' is incompatible with value '" + V->getAsString() +305 InitType);306 }307 return false;308}309 310/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template311/// args as SubClass's template arguments.312bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {313 const Record *SC = SubClass.Rec;314 MapResolver R(CurRec);315 316 // Loop over all the subclass record's fields. Add regular fields to the new317 // record.318 for (const RecordVal &Field : SC->getValues())319 if (!Field.isTemplateArg())320 if (AddValue(CurRec, SubClass.RefRange.Start, Field))321 return true;322 323 if (resolveArgumentsOfClass(R, SC, SubClass.TemplateArgs,324 SubClass.RefRange.Start))325 return true;326 327 // Copy the subclass record's assertions to the new record.328 CurRec->appendAssertions(SC);329 330 // Copy the subclass record's dumps to the new record.331 CurRec->appendDumps(SC);332 333 const Init *Name;334 if (CurRec->isClass())335 Name = VarInit::get(QualifiedNameOfImplicitName(*CurRec),336 StringRecTy::get(Records));337 else338 Name = CurRec->getNameInit();339 R.set(QualifiedNameOfImplicitName(*SC), Name);340 341 CurRec->resolveReferences(R);342 343 // Since everything went well, we can now set the "superclass" list for the344 // current record.345 if (CurRec->isSubClassOf(SC))346 return Error(SubClass.RefRange.Start,347 "Already subclass of '" + SC->getName() + "'!\n");348 CurRec->addDirectSuperClass(SC, SubClass.RefRange);349 return false;350}351 352bool TGParser::AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass) {353 if (Entry.Rec)354 return AddSubClass(Entry.Rec.get(), SubClass);355 356 if (Entry.Assertion)357 return false;358 359 for (auto &E : Entry.Loop->Entries) {360 if (AddSubClass(E, SubClass))361 return true;362 }363 364 return false;365}366 367/// AddSubMultiClass - Add SubMultiClass as a subclass to368/// CurMC, resolving its template args as SubMultiClass's369/// template arguments.370bool TGParser::AddSubMultiClass(MultiClass *CurMC,371 SubMultiClassReference &SubMultiClass) {372 MultiClass *SMC = SubMultiClass.MC;373 374 SubstStack Substs;375 if (resolveArgumentsOfMultiClass(376 Substs, SMC, SubMultiClass.TemplateArgs,377 VarInit::get(QualifiedNameOfImplicitName(CurMC),378 StringRecTy::get(Records)),379 SubMultiClass.RefRange.Start))380 return true;381 382 // Add all of the defs in the subclass into the current multiclass.383 return resolve(SMC->Entries, Substs, false, &CurMC->Entries);384}385 386/// Add a record, foreach loop, or assertion to the current context.387bool TGParser::addEntry(RecordsEntry E) {388 assert((!!E.Rec + !!E.Loop + !!E.Assertion + !!E.Dump) == 1 &&389 "RecordsEntry has invalid number of items");390 391 // If we are parsing a loop, add it to the loop's entries.392 if (!Loops.empty()) {393 Loops.back()->Entries.push_back(std::move(E));394 return false;395 }396 397 // If it is a loop, then resolve and perform the loop.398 if (E.Loop) {399 SubstStack Stack;400 return resolve(*E.Loop, Stack, CurMultiClass == nullptr,401 CurMultiClass ? &CurMultiClass->Entries : nullptr);402 }403 404 // If we are parsing a multiclass, add it to the multiclass's entries.405 if (CurMultiClass) {406 CurMultiClass->Entries.push_back(std::move(E));407 return false;408 }409 410 // If it is an assertion, then it's a top-level one, so check it.411 if (E.Assertion) {412 CheckAssert(E.Assertion->Loc, E.Assertion->Condition, E.Assertion->Message);413 return false;414 }415 416 if (E.Dump) {417 dumpMessage(E.Dump->Loc, E.Dump->Message);418 return false;419 }420 421 // It must be a record, so finish it off.422 return addDefOne(std::move(E.Rec));423}424 425/// Resolve the entries in \p Loop, going over inner loops recursively426/// and making the given subsitutions of (name, value) pairs.427///428/// The resulting records are stored in \p Dest if non-null. Otherwise, they429/// are added to the global record keeper.430bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs, bool Final,431 std::vector<RecordsEntry> *Dest, SMLoc *Loc) {432 433 MapResolver R;434 for (const auto &S : Substs)435 R.set(S.first, S.second);436 const Init *List = Loop.ListValue->resolveReferences(R);437 438 // For if-then-else blocks, we lower to a foreach loop whose list is a439 // ternary selection between lists of different length. Since we don't440 // have a means to track variable length record lists, we *must* resolve441 // the condition here. We want to defer final resolution of the arms442 // until the resulting records are finalized.443 // e.g. !if(!exists<SchedWrite>("__does_not_exist__"), [1], [])444 if (const auto *TI = dyn_cast<TernOpInit>(List);445 TI && TI->getOpcode() == TernOpInit::IF && Final) {446 const Init *OldLHS = TI->getLHS();447 R.setFinal(true);448 const Init *LHS = OldLHS->resolveReferences(R);449 if (LHS == OldLHS) {450 PrintError(Loop.Loc, Twine("unable to resolve if condition '") +451 LHS->getAsString() +452 "' at end of containing scope");453 return true;454 }455 const Init *MHS = TI->getMHS();456 const Init *RHS = TI->getRHS();457 List = TernOpInit::get(TernOpInit::IF, LHS, MHS, RHS, TI->getType())458 ->Fold(nullptr);459 }460 461 const auto *LI = dyn_cast<ListInit>(List);462 if (!LI) {463 if (!Final) {464 Dest->emplace_back(465 std::make_unique<ForeachLoop>(Loop.Loc, Loop.IterVar, List));466 return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,467 Loc);468 }469 470 PrintError(Loop.Loc, Twine("attempting to loop over '") +471 List->getAsString() + "', expected a list");472 return true;473 }474 475 bool Error = false;476 for (auto *Elt : *LI) {477 if (Loop.IterVar)478 Substs.emplace_back(Loop.IterVar->getNameInit(), Elt);479 Error = resolve(Loop.Entries, Substs, Final, Dest);480 if (Loop.IterVar)481 Substs.pop_back();482 if (Error)483 break;484 }485 return Error;486}487 488/// Resolve the entries in \p Source, going over loops recursively and489/// making the given substitutions of (name, value) pairs.490///491/// The resulting records are stored in \p Dest if non-null. Otherwise, they492/// are added to the global record keeper.493bool TGParser::resolve(const std::vector<RecordsEntry> &Source,494 SubstStack &Substs, bool Final,495 std::vector<RecordsEntry> *Dest, SMLoc *Loc) {496 bool Error = false;497 for (auto &E : Source) {498 if (E.Loop) {499 Error = resolve(*E.Loop, Substs, Final, Dest);500 501 } else if (E.Assertion) {502 MapResolver R;503 for (const auto &S : Substs)504 R.set(S.first, S.second);505 const Init *Condition = E.Assertion->Condition->resolveReferences(R);506 const Init *Message = E.Assertion->Message->resolveReferences(R);507 508 if (Dest)509 Dest->push_back(std::make_unique<Record::AssertionInfo>(510 E.Assertion->Loc, Condition, Message));511 else512 CheckAssert(E.Assertion->Loc, Condition, Message);513 514 } else if (E.Dump) {515 MapResolver R;516 for (const auto &S : Substs)517 R.set(S.first, S.second);518 const Init *Message = E.Dump->Message->resolveReferences(R);519 520 if (Dest)521 Dest->push_back(522 std::make_unique<Record::DumpInfo>(E.Dump->Loc, Message));523 else524 dumpMessage(E.Dump->Loc, Message);525 526 } else {527 auto Rec = std::make_unique<Record>(*E.Rec);528 if (Loc)529 Rec->appendLoc(*Loc);530 531 MapResolver R(Rec.get());532 for (const auto &S : Substs)533 R.set(S.first, S.second);534 Rec->resolveReferences(R);535 536 if (Dest)537 Dest->push_back(std::move(Rec));538 else539 Error = addDefOne(std::move(Rec));540 }541 if (Error)542 break;543 }544 return Error;545}546 547/// Resolve the record fully and add it to the record keeper.548bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {549 const Init *NewName = nullptr;550 if (const Record *Prev = Records.getDef(Rec->getNameInitAsString())) {551 if (!Rec->isAnonymous()) {552 PrintError(Rec->getLoc(),553 "def already exists: " + Rec->getNameInitAsString());554 PrintNote(Prev->getLoc(), "location of previous definition");555 return true;556 }557 NewName = Records.getNewAnonymousName();558 }559 560 Rec->resolveReferences(NewName);561 checkConcrete(*Rec);562 563 if (!isa<StringInit>(Rec->getNameInit())) {564 PrintError(Rec->getLoc(), Twine("record name '") +565 Rec->getNameInit()->getAsString() +566 "' could not be fully resolved");567 return true;568 }569 570 // Check the assertions.571 Rec->checkRecordAssertions();572 573 // Run the dumps.574 Rec->emitRecordDumps();575 576 // If ObjectBody has template arguments, it's an error.577 assert(Rec->getTemplateArgs().empty() && "How'd this get template args?");578 579 for (DefsetRecord *Defset : Defsets) {580 DefInit *I = Rec->getDefInit();581 if (!I->getType()->typeIsA(Defset->EltTy)) {582 PrintError(Rec->getLoc(), Twine("adding record of incompatible type '") +583 I->getType()->getAsString() +584 "' to defset");585 PrintNote(Defset->Loc, "location of defset declaration");586 return true;587 }588 Defset->Elements.push_back(I);589 }590 591 Records.addDef(std::move(Rec));592 return false;593}594 595bool TGParser::resolveArguments(const Record *Rec,596 ArrayRef<const ArgumentInit *> ArgValues,597 SMLoc Loc, ArgValueHandler ArgValueHandler) {598 ArrayRef<const Init *> ArgNames = Rec->getTemplateArgs();599 assert(ArgValues.size() <= ArgNames.size() &&600 "Too many template arguments allowed");601 602 // Loop over the template arguments and handle the (name, value) pair.603 SmallVector<const Init *, 2> UnsolvedArgNames(ArgNames);604 for (auto *Arg : ArgValues) {605 const Init *ArgName = nullptr;606 const Init *ArgValue = Arg->getValue();607 if (Arg->isPositional())608 ArgName = ArgNames[Arg->getIndex()];609 if (Arg->isNamed())610 ArgName = Arg->getName();611 612 // We can only specify the template argument once.613 if (!is_contained(UnsolvedArgNames, ArgName))614 return Error(Loc, "We can only specify the template argument '" +615 ArgName->getAsUnquotedString() + "' once");616 617 ArgValueHandler(ArgName, ArgValue);618 llvm::erase(UnsolvedArgNames, ArgName);619 }620 621 // For unsolved arguments, if there is no default value, complain.622 for (auto *UnsolvedArgName : UnsolvedArgNames) {623 const Init *Default = Rec->getValue(UnsolvedArgName)->getValue();624 if (!Default->isComplete()) {625 std::string Name = UnsolvedArgName->getAsUnquotedString();626 Error(Loc, "value not specified for template argument '" + Name + "'");627 PrintNote(Rec->getFieldLoc(Name),628 "declared in '" + Rec->getNameInitAsString() + "'");629 return true;630 }631 ArgValueHandler(UnsolvedArgName, Default);632 }633 634 return false;635}636 637/// Resolve the arguments of class and set them to MapResolver.638/// Returns true if failed.639bool TGParser::resolveArgumentsOfClass(MapResolver &R, const Record *Rec,640 ArrayRef<const ArgumentInit *> ArgValues,641 SMLoc Loc) {642 return resolveArguments(643 Rec, ArgValues, Loc,644 [&](const Init *Name, const Init *Value) { R.set(Name, Value); });645}646 647/// Resolve the arguments of multiclass and store them into SubstStack.648/// Returns true if failed.649bool TGParser::resolveArgumentsOfMultiClass(650 SubstStack &Substs, MultiClass *MC,651 ArrayRef<const ArgumentInit *> ArgValues, const Init *DefmName, SMLoc Loc) {652 // Add an implicit argument NAME.653 Substs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName);654 return resolveArguments(&MC->Rec, ArgValues, Loc,655 [&](const Init *Name, const Init *Value) {656 Substs.emplace_back(Name, Value);657 });658}659 660//===----------------------------------------------------------------------===//661// Parser Code662//===----------------------------------------------------------------------===//663 664bool TGParser::consume(tgtok::TokKind K) {665 if (Lex.getCode() == K) {666 Lex.Lex();667 return true;668 }669 return false;670}671 672/// ParseObjectName - If a valid object name is specified, return it. If no673/// name is specified, return the unset initializer. Return nullptr on parse674/// error.675/// ObjectName ::= Value [ '#' Value ]*676/// ObjectName ::= /*empty*/677///678const Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {679 switch (Lex.getCode()) {680 case tgtok::colon:681 case tgtok::semi:682 case tgtok::l_brace:683 // These are all of the tokens that can begin an object body.684 // Some of these can also begin values but we disallow those cases685 // because they are unlikely to be useful.686 return UnsetInit::get(Records);687 default:688 break;689 }690 691 Record *CurRec = nullptr;692 if (CurMultiClass)693 CurRec = &CurMultiClass->Rec;694 695 const Init *Name =696 ParseValue(CurRec, StringRecTy::get(Records), ParseNameMode);697 if (!Name)698 return nullptr;699 700 if (CurMultiClass) {701 const Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass);702 HasReferenceResolver R(NameStr);703 Name->resolveReferences(R);704 if (!R.found())705 Name = BinOpInit::getStrConcat(706 VarInit::get(NameStr, StringRecTy::get(Records)), Name);707 }708 709 return Name;710}711 712/// ParseClassID - Parse and resolve a reference to a class name. This returns713/// null on error.714///715/// ClassID ::= ID716///717const Record *TGParser::ParseClassID() {718 if (Lex.getCode() != tgtok::Id) {719 TokError("expected name for ClassID");720 return nullptr;721 }722 723 const Record *Result = Records.getClass(Lex.getCurStrVal());724 if (!Result) {725 std::string Msg("Couldn't find class '" + Lex.getCurStrVal() + "'");726 if (MultiClasses[Lex.getCurStrVal()].get())727 TokError(Msg + ". Use 'defm' if you meant to use multiclass '" +728 Lex.getCurStrVal() + "'");729 else730 TokError(Msg);731 } else if (TrackReferenceLocs) {732 Result->appendReferenceLoc(Lex.getLocRange());733 }734 735 Lex.Lex();736 return Result;737}738 739/// ParseMultiClassID - Parse and resolve a reference to a multiclass name.740/// This returns null on error.741///742/// MultiClassID ::= ID743///744MultiClass *TGParser::ParseMultiClassID() {745 if (Lex.getCode() != tgtok::Id) {746 TokError("expected name for MultiClassID");747 return nullptr;748 }749 750 MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get();751 if (!Result)752 TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");753 754 Lex.Lex();755 return Result;756}757 758/// ParseSubClassReference - Parse a reference to a subclass or a759/// multiclass. This returns a SubClassRefTy with a null Record* on error.760///761/// SubClassRef ::= ClassID762/// SubClassRef ::= ClassID '<' ArgValueList '>'763///764SubClassReference TGParser::ParseSubClassReference(Record *CurRec,765 bool isDefm) {766 SubClassReference Result;767 Result.RefRange.Start = Lex.getLoc();768 769 if (isDefm) {770 if (MultiClass *MC = ParseMultiClassID())771 Result.Rec = &MC->Rec;772 } else {773 Result.Rec = ParseClassID();774 }775 if (!Result.Rec)776 return Result;777 778 // If there is no template arg list, we're done.779 if (!consume(tgtok::less)) {780 Result.RefRange.End = Lex.getLoc();781 return Result;782 }783 784 SmallVector<SMLoc> ArgLocs;785 if (ParseTemplateArgValueList(Result.TemplateArgs, ArgLocs, CurRec,786 Result.Rec)) {787 Result.Rec = nullptr; // Error parsing value list.788 return Result;789 }790 791 if (CheckTemplateArgValues(Result.TemplateArgs, ArgLocs, Result.Rec)) {792 Result.Rec = nullptr; // Error checking value list.793 return Result;794 }795 796 Result.RefRange.End = Lex.getLoc();797 return Result;798}799 800/// ParseSubMultiClassReference - Parse a reference to a subclass or to a801/// templated submulticlass. This returns a SubMultiClassRefTy with a null802/// Record* on error.803///804/// SubMultiClassRef ::= MultiClassID805/// SubMultiClassRef ::= MultiClassID '<' ArgValueList '>'806///807SubMultiClassReference808TGParser::ParseSubMultiClassReference(MultiClass *CurMC) {809 SubMultiClassReference Result;810 Result.RefRange.Start = Lex.getLoc();811 812 Result.MC = ParseMultiClassID();813 if (!Result.MC)814 return Result;815 816 // If there is no template arg list, we're done.817 if (!consume(tgtok::less)) {818 Result.RefRange.End = Lex.getLoc();819 return Result;820 }821 822 SmallVector<SMLoc> ArgLocs;823 if (ParseTemplateArgValueList(Result.TemplateArgs, ArgLocs, &CurMC->Rec,824 &Result.MC->Rec)) {825 Result.MC = nullptr; // Error parsing value list.826 return Result;827 }828 829 Result.RefRange.End = Lex.getLoc();830 831 return Result;832}833 834/// ParseSliceElement - Parse subscript or range835///836/// SliceElement ::= Value<list<int>>837/// SliceElement ::= Value<int>838/// SliceElement ::= Value<int> '...' Value<int>839/// SliceElement ::= Value<int> '-' Value<int> (deprecated)840/// SliceElement ::= Value<int> INTVAL(Negative; deprecated)841///842/// SliceElement is either IntRecTy, ListRecTy, or nullptr843///844const TypedInit *TGParser::ParseSliceElement(Record *CurRec) {845 auto LHSLoc = Lex.getLoc();846 auto *CurVal = ParseValue(CurRec);847 if (!CurVal)848 return nullptr;849 const auto *LHS = cast<TypedInit>(CurVal);850 851 const TypedInit *RHS = nullptr;852 switch (Lex.getCode()) {853 case tgtok::dotdotdot:854 case tgtok::minus: { // Deprecated855 Lex.Lex(); // eat856 auto RHSLoc = Lex.getLoc();857 CurVal = ParseValue(CurRec);858 if (!CurVal)859 return nullptr;860 RHS = cast<TypedInit>(CurVal);861 if (!isa<IntRecTy>(RHS->getType())) {862 Error(RHSLoc,863 "expected int...int, got " + Twine(RHS->getType()->getAsString()));864 return nullptr;865 }866 break;867 }868 case tgtok::IntVal: { // Deprecated "-num"869 auto i = -Lex.getCurIntVal();870 if (i < 0) {871 TokError("invalid range, cannot be negative");872 return nullptr;873 }874 RHS = IntInit::get(Records, i);875 Lex.Lex(); // eat IntVal876 break;877 }878 default: // Single value (IntRecTy or ListRecTy)879 return LHS;880 }881 882 assert(RHS);883 assert(isa<IntRecTy>(RHS->getType()));884 885 // Closed-interval range <LHS:IntRecTy>...<RHS:IntRecTy>886 if (!isa<IntRecTy>(LHS->getType())) {887 Error(LHSLoc,888 "expected int...int, got " + Twine(LHS->getType()->getAsString()));889 return nullptr;890 }891 892 return cast<TypedInit>(BinOpInit::get(BinOpInit::RANGEC, LHS, RHS,893 IntRecTy::get(Records)->getListTy())894 ->Fold(CurRec));895}896 897/// ParseSliceElements - Parse subscripts in square brackets.898///899/// SliceElements ::= ( SliceElement ',' )* SliceElement ','?900///901/// SliceElement is either IntRecTy, ListRecTy, or nullptr902///903/// Returns ListRecTy by defaut.904/// Returns IntRecTy if;905/// - Single=true906/// - SliceElements is Value<int> w/o trailing comma907///908const TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {909 const TypedInit *CurVal;910 SmallVector<const Init *, 2> Elems; // int911 SmallVector<const TypedInit *, 2> Slices; // list<int>912 913 auto FlushElems = [&] {914 if (!Elems.empty()) {915 Slices.push_back(ListInit::get(Elems, IntRecTy::get(Records)));916 Elems.clear();917 }918 };919 920 do {921 auto LHSLoc = Lex.getLoc();922 CurVal = ParseSliceElement(CurRec);923 if (!CurVal)924 return nullptr;925 auto *CurValTy = CurVal->getType();926 927 if (const auto *ListValTy = dyn_cast<ListRecTy>(CurValTy)) {928 if (!isa<IntRecTy>(ListValTy->getElementType())) {929 Error(LHSLoc,930 "expected list<int>, got " + Twine(ListValTy->getAsString()));931 return nullptr;932 }933 934 FlushElems();935 Slices.push_back(CurVal);936 Single = false;937 CurVal = nullptr;938 } else if (!isa<IntRecTy>(CurValTy)) {939 Error(LHSLoc,940 "unhandled type " + Twine(CurValTy->getAsString()) + " in range");941 return nullptr;942 }943 944 if (Lex.getCode() != tgtok::comma)945 break;946 947 Lex.Lex(); // eat comma948 949 // `[i,]` is not LISTELEM but LISTSLICE950 Single = false;951 if (CurVal)952 Elems.push_back(CurVal);953 CurVal = nullptr;954 } while (Lex.getCode() != tgtok::r_square);955 956 if (CurVal) {957 // LISTELEM958 if (Single)959 return CurVal;960 961 Elems.push_back(CurVal);962 }963 964 FlushElems();965 966 // Concatenate lists in Slices967 const TypedInit *Result = nullptr;968 for (auto *Slice : Slices) {969 Result = (Result ? cast<TypedInit>(BinOpInit::getListConcat(Result, Slice))970 : Slice);971 }972 973 return Result;974}975 976/// ParseRangePiece - Parse a bit/value range.977/// RangePiece ::= INTVAL978/// RangePiece ::= INTVAL '...' INTVAL979/// RangePiece ::= INTVAL '-' INTVAL980/// RangePiece ::= INTVAL INTVAL981// The last two forms are deprecated.982bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,983 const TypedInit *FirstItem) {984 const Init *CurVal = FirstItem;985 if (!CurVal)986 CurVal = ParseValue(nullptr);987 988 const auto *II = dyn_cast_or_null<IntInit>(CurVal);989 if (!II)990 return TokError("expected integer or bitrange");991 992 int64_t Start = II->getValue();993 int64_t End;994 995 if (Start < 0)996 return TokError("invalid range, cannot be negative");997 998 switch (Lex.getCode()) {999 default:1000 Ranges.push_back(Start);1001 return false;1002 1003 case tgtok::dotdotdot:1004 case tgtok::minus: {1005 Lex.Lex(); // eat1006 1007 const Init *I_End = ParseValue(nullptr);1008 const auto *II_End = dyn_cast_or_null<IntInit>(I_End);1009 if (!II_End) {1010 TokError("expected integer value as end of range");1011 return true;1012 }1013 1014 End = II_End->getValue();1015 break;1016 }1017 case tgtok::IntVal: {1018 End = -Lex.getCurIntVal();1019 Lex.Lex();1020 break;1021 }1022 }1023 if (End < 0)1024 return TokError("invalid range, cannot be negative");1025 1026 // Add to the range.1027 if (Start < End)1028 for (; Start <= End; ++Start)1029 Ranges.push_back(Start);1030 else1031 for (; Start >= End; --Start)1032 Ranges.push_back(Start);1033 return false;1034}1035 1036/// ParseRangeList - Parse a list of scalars and ranges into scalar values.1037///1038/// RangeList ::= RangePiece (',' RangePiece)*1039///1040void TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) {1041 // Parse the first piece.1042 if (ParseRangePiece(Result)) {1043 Result.clear();1044 return;1045 }1046 while (consume(tgtok::comma))1047 // Parse the next range piece.1048 if (ParseRangePiece(Result)) {1049 Result.clear();1050 return;1051 }1052}1053 1054/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.1055/// OptionalRangeList ::= '<' RangeList '>'1056/// OptionalRangeList ::= /*empty*/1057bool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) {1058 SMLoc StartLoc = Lex.getLoc();1059 if (!consume(tgtok::less))1060 return false;1061 1062 // Parse the range list.1063 ParseRangeList(Ranges);1064 if (Ranges.empty())1065 return true;1066 1067 if (!consume(tgtok::greater)) {1068 TokError("expected '>' at end of range list");1069 return Error(StartLoc, "to match this '<'");1070 }1071 return false;1072}1073 1074/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing.1075/// OptionalBitList ::= '{' RangeList '}'1076/// OptionalBitList ::= /*empty*/1077bool TGParser::ParseOptionalBitList(SmallVectorImpl<unsigned> &Ranges) {1078 SMLoc StartLoc = Lex.getLoc();1079 if (!consume(tgtok::l_brace))1080 return false;1081 1082 // Parse the range list.1083 ParseRangeList(Ranges);1084 if (Ranges.empty())1085 return true;1086 1087 if (!consume(tgtok::r_brace)) {1088 TokError("expected '}' at end of bit list");1089 return Error(StartLoc, "to match this '{'");1090 }1091 return false;1092}1093 1094/// ParseType - Parse and return a tblgen type. This returns null on error.1095///1096/// Type ::= STRING // string type1097/// Type ::= CODE // code type1098/// Type ::= BIT // bit type1099/// Type ::= BITS '<' INTVAL '>' // bits<x> type1100/// Type ::= INT // int type1101/// Type ::= LIST '<' Type '>' // list<x> type1102/// Type ::= DAG // dag type1103/// Type ::= ClassID // Record Type1104///1105const RecTy *TGParser::ParseType() {1106 switch (Lex.getCode()) {1107 default:1108 TokError("Unknown token when expecting a type");1109 return nullptr;1110 case tgtok::String:1111 case tgtok::Code:1112 Lex.Lex();1113 return StringRecTy::get(Records);1114 case tgtok::Bit:1115 Lex.Lex();1116 return BitRecTy::get(Records);1117 case tgtok::Int:1118 Lex.Lex();1119 return IntRecTy::get(Records);1120 case tgtok::Dag:1121 Lex.Lex();1122 return DagRecTy::get(Records);1123 case tgtok::Id: {1124 auto I = TypeAliases.find(Lex.getCurStrVal());1125 if (I != TypeAliases.end()) {1126 Lex.Lex();1127 return I->second;1128 }1129 if (const Record *R = ParseClassID())1130 return RecordRecTy::get(R);1131 TokError("unknown class name");1132 return nullptr;1133 }1134 case tgtok::Bits: {1135 if (Lex.Lex() != tgtok::less) { // Eat 'bits'1136 TokError("expected '<' after bits type");1137 return nullptr;1138 }1139 if (Lex.Lex() != tgtok::IntVal) { // Eat '<'1140 TokError("expected integer in bits<n> type");1141 return nullptr;1142 }1143 uint64_t Val = Lex.getCurIntVal();1144 if (Lex.Lex() != tgtok::greater) { // Eat count.1145 TokError("expected '>' at end of bits<n> type");1146 return nullptr;1147 }1148 Lex.Lex(); // Eat '>'1149 return BitsRecTy::get(Records, Val);1150 }1151 case tgtok::List: {1152 if (Lex.Lex() != tgtok::less) { // Eat 'bits'1153 TokError("expected '<' after list type");1154 return nullptr;1155 }1156 Lex.Lex(); // Eat '<'1157 const RecTy *SubType = ParseType();1158 if (!SubType)1159 return nullptr;1160 1161 if (!consume(tgtok::greater)) {1162 TokError("expected '>' at end of list<ty> type");1163 return nullptr;1164 }1165 return ListRecTy::get(SubType);1166 }1167 }1168}1169 1170/// ParseIDValue1171const Init *TGParser::ParseIDValue(Record *CurRec, const StringInit *Name,1172 SMRange NameLoc, IDParseMode Mode) {1173 if (const Init *I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,1174 TrackReferenceLocs))1175 return I;1176 1177 if (Mode == ParseNameMode)1178 return Name;1179 1180 if (const Init *I = Records.getGlobal(Name->getValue())) {1181 // Add a reference to the global if it's a record.1182 if (TrackReferenceLocs) {1183 if (const auto *Def = dyn_cast<DefInit>(I))1184 Def->getDef()->appendReferenceLoc(NameLoc);1185 }1186 return I;1187 }1188 1189 // Allow self-references of concrete defs, but delay the lookup so that we1190 // get the correct type.1191 if (CurRec && !CurRec->isClass() && !CurMultiClass &&1192 CurRec->getNameInit() == Name)1193 return UnOpInit::get(UnOpInit::CAST, Name, CurRec->getType());1194 1195 Error(NameLoc.Start, "Variable not defined: '" + Name->getValue() + "'");1196 return nullptr;1197}1198 1199/// ParseOperation - Parse an operator. This returns null on error.1200///1201/// Operation ::= XOperator ['<' Type '>'] '(' Args ')'1202///1203const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {1204 switch (Lex.getCode()) {1205 default:1206 TokError("unknown bang operator");1207 return nullptr;1208 case tgtok::XNOT:1209 case tgtok::XToLower:1210 case tgtok::XToUpper:1211 case tgtok::XListFlatten:1212 case tgtok::XLOG2:1213 case tgtok::XHead:1214 case tgtok::XTail:1215 case tgtok::XSize:1216 case tgtok::XEmpty:1217 case tgtok::XCast:1218 case tgtok::XRepr:1219 case tgtok::XGetDagOp:1220 case tgtok::XGetDagOpName:1221 case tgtok::XInitialized: { // Value ::= !unop '(' Value ')'1222 UnOpInit::UnaryOp Code;1223 const RecTy *Type = nullptr;1224 1225 switch (Lex.getCode()) {1226 default:1227 llvm_unreachable("Unhandled code!");1228 case tgtok::XCast:1229 Lex.Lex(); // eat the operation1230 Code = UnOpInit::CAST;1231 1232 Type = ParseOperatorType();1233 1234 if (!Type) {1235 TokError("did not get type for unary operator");1236 return nullptr;1237 }1238 1239 break;1240 case tgtok::XRepr:1241 Lex.Lex(); // eat the operation1242 Code = UnOpInit::REPR;1243 Type = StringRecTy::get(Records);1244 break;1245 case tgtok::XToLower:1246 Lex.Lex(); // eat the operation1247 Code = UnOpInit::TOLOWER;1248 Type = StringRecTy::get(Records);1249 break;1250 case tgtok::XToUpper:1251 Lex.Lex(); // eat the operation1252 Code = UnOpInit::TOUPPER;1253 Type = StringRecTy::get(Records);1254 break;1255 case tgtok::XNOT:1256 Lex.Lex(); // eat the operation1257 Code = UnOpInit::NOT;1258 Type = IntRecTy::get(Records);1259 break;1260 case tgtok::XListFlatten:1261 Lex.Lex(); // eat the operation.1262 Code = UnOpInit::LISTFLATTEN;1263 Type = IntRecTy::get(Records); // Bogus type used here.1264 break;1265 case tgtok::XLOG2:1266 Lex.Lex(); // eat the operation1267 Code = UnOpInit::LOG2;1268 Type = IntRecTy::get(Records);1269 break;1270 case tgtok::XHead:1271 Lex.Lex(); // eat the operation1272 Code = UnOpInit::HEAD;1273 break;1274 case tgtok::XTail:1275 Lex.Lex(); // eat the operation1276 Code = UnOpInit::TAIL;1277 break;1278 case tgtok::XSize:1279 Lex.Lex();1280 Code = UnOpInit::SIZE;1281 Type = IntRecTy::get(Records);1282 break;1283 case tgtok::XEmpty:1284 Lex.Lex(); // eat the operation1285 Code = UnOpInit::EMPTY;1286 Type = IntRecTy::get(Records);1287 break;1288 case tgtok::XGetDagOp:1289 Lex.Lex(); // eat the operation1290 if (Lex.getCode() == tgtok::less) {1291 // Parse an optional type suffix, so that you can say1292 // !getdagop<BaseClass>(someDag) as a shorthand for1293 // !cast<BaseClass>(!getdagop(someDag)).1294 Type = ParseOperatorType();1295 1296 if (!Type) {1297 TokError("did not get type for unary operator");1298 return nullptr;1299 }1300 1301 if (!isa<RecordRecTy>(Type)) {1302 TokError("type for !getdagop must be a record type");1303 // but keep parsing, to consume the operand1304 }1305 } else {1306 Type = RecordRecTy::get(Records, {});1307 }1308 Code = UnOpInit::GETDAGOP;1309 break;1310 case tgtok::XGetDagOpName:1311 Lex.Lex(); // eat the operation1312 Type = StringRecTy::get(Records);1313 Code = UnOpInit::GETDAGOPNAME;1314 break;1315 case tgtok::XInitialized:1316 Lex.Lex(); // eat the operation1317 Code = UnOpInit::INITIALIZED;1318 Type = IntRecTy::get(Records);1319 break;1320 }1321 if (!consume(tgtok::l_paren)) {1322 TokError("expected '(' after unary operator");1323 return nullptr;1324 }1325 1326 const Init *LHS = ParseValue(CurRec);1327 if (!LHS)1328 return nullptr;1329 1330 if (Code == UnOpInit::EMPTY || Code == UnOpInit::SIZE) {1331 const auto *LHSl = dyn_cast<ListInit>(LHS);1332 const auto *LHSs = dyn_cast<StringInit>(LHS);1333 const auto *LHSd = dyn_cast<DagInit>(LHS);1334 const auto *LHSt = dyn_cast<TypedInit>(LHS);1335 if (!LHSl && !LHSs && !LHSd && !LHSt) {1336 TokError(1337 "expected string, list, or dag type argument in unary operator");1338 return nullptr;1339 }1340 if (LHSt) {1341 if (!isa<ListRecTy, StringRecTy, DagRecTy>(LHSt->getType())) {1342 TokError(1343 "expected string, list, or dag type argument in unary operator");1344 return nullptr;1345 }1346 }1347 }1348 1349 if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL ||1350 Code == UnOpInit::LISTFLATTEN) {1351 const auto *LHSl = dyn_cast<ListInit>(LHS);1352 const auto *LHSt = dyn_cast<TypedInit>(LHS);1353 if (!LHSl && !LHSt) {1354 TokError("expected list type argument in unary operator");1355 return nullptr;1356 }1357 if (LHSt) {1358 if (!isa<ListRecTy>(LHSt->getType())) {1359 TokError("expected list type argument in unary operator");1360 return nullptr;1361 }1362 }1363 1364 if (LHSl && LHSl->empty()) {1365 TokError("empty list argument in unary operator");1366 return nullptr;1367 }1368 bool UseElementType =1369 Code == UnOpInit::HEAD || Code == UnOpInit::LISTFLATTEN;1370 if (LHSl) {1371 const Init *Item = LHSl->getElement(0);1372 const auto *Itemt = dyn_cast<TypedInit>(Item);1373 if (!Itemt) {1374 TokError("untyped list element in unary operator");1375 return nullptr;1376 }1377 Type = UseElementType ? Itemt->getType()1378 : ListRecTy::get(Itemt->getType());1379 } else {1380 assert(LHSt && "expected list type argument in unary operator");1381 const auto *LType = dyn_cast<ListRecTy>(LHSt->getType());1382 Type = UseElementType ? LType->getElementType() : LType;1383 }1384 1385 // for !listflatten, we expect a list of lists, but also support a list of1386 // non-lists, where !listflatten will be a NOP.1387 if (Code == UnOpInit::LISTFLATTEN) {1388 const auto *InnerListTy = dyn_cast<ListRecTy>(Type);1389 if (InnerListTy) {1390 // listflatten will convert list<list<X>> to list<X>.1391 Type = ListRecTy::get(InnerListTy->getElementType());1392 } else {1393 // If its a list of non-lists, !listflatten will be a NOP.1394 Type = ListRecTy::get(Type);1395 }1396 }1397 }1398 1399 if (!consume(tgtok::r_paren)) {1400 TokError("expected ')' in unary operator");1401 return nullptr;1402 }1403 return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec);1404 }1405 1406 case tgtok::XIsA: {1407 // Value ::= !isa '<' Type '>' '(' Value ')'1408 Lex.Lex(); // eat the operation1409 1410 const RecTy *Type = ParseOperatorType();1411 if (!Type)1412 return nullptr;1413 1414 if (!consume(tgtok::l_paren)) {1415 TokError("expected '(' after type of !isa");1416 return nullptr;1417 }1418 1419 const Init *LHS = ParseValue(CurRec);1420 if (!LHS)1421 return nullptr;1422 1423 if (!consume(tgtok::r_paren)) {1424 TokError("expected ')' in !isa");1425 return nullptr;1426 }1427 1428 return IsAOpInit::get(Type, LHS)->Fold();1429 }1430 1431 case tgtok::XExists: {1432 // Value ::= !exists '<' Type '>' '(' Value ')'1433 Lex.Lex(); // eat the operation.1434 1435 const RecTy *Type = ParseOperatorType();1436 if (!Type)1437 return nullptr;1438 1439 if (!consume(tgtok::l_paren)) {1440 TokError("expected '(' after type of !exists");1441 return nullptr;1442 }1443 1444 SMLoc ExprLoc = Lex.getLoc();1445 const Init *Expr = ParseValue(CurRec);1446 if (!Expr)1447 return nullptr;1448 1449 const auto *ExprType = dyn_cast<TypedInit>(Expr);1450 if (!ExprType) {1451 Error(ExprLoc, "expected string type argument in !exists operator");1452 return nullptr;1453 }1454 1455 const auto *RecType = dyn_cast<RecordRecTy>(ExprType->getType());1456 if (RecType) {1457 Error(ExprLoc,1458 "expected string type argument in !exists operator, please "1459 "use !isa instead");1460 return nullptr;1461 }1462 1463 const auto *SType = dyn_cast<StringRecTy>(ExprType->getType());1464 if (!SType) {1465 Error(ExprLoc, "expected string type argument in !exists operator");1466 return nullptr;1467 }1468 1469 if (!consume(tgtok::r_paren)) {1470 TokError("expected ')' in !exists");1471 return nullptr;1472 }1473 1474 return (ExistsOpInit::get(Type, Expr))->Fold(CurRec);1475 }1476 1477 case tgtok::XInstances: {1478 // Value ::= !instances '<' Type '>' '(' Regex? ')'1479 Lex.Lex(); // eat the operation.1480 1481 const RecTy *Type = ParseOperatorType();1482 if (!Type)1483 return nullptr;1484 1485 if (!consume(tgtok::l_paren)) {1486 TokError("expected '(' after type of !instances");1487 return nullptr;1488 }1489 1490 // The Regex can be optional.1491 const Init *Regex;1492 if (Lex.getCode() != tgtok::r_paren) {1493 SMLoc RegexLoc = Lex.getLoc();1494 Regex = ParseValue(CurRec);1495 1496 const auto *RegexType = dyn_cast<TypedInit>(Regex);1497 if (!RegexType) {1498 Error(RegexLoc, "expected string type argument in !instances operator");1499 return nullptr;1500 }1501 1502 const auto *SType = dyn_cast<StringRecTy>(RegexType->getType());1503 if (!SType) {1504 Error(RegexLoc, "expected string type argument in !instances operator");1505 return nullptr;1506 }1507 } else {1508 // Use wildcard when Regex is not specified.1509 Regex = StringInit::get(Records, ".*");1510 }1511 1512 if (!consume(tgtok::r_paren)) {1513 TokError("expected ')' in !instances");1514 return nullptr;1515 }1516 1517 return InstancesOpInit::get(Type, Regex)->Fold(CurRec);1518 }1519 1520 case tgtok::XConcat:1521 case tgtok::XMatch:1522 case tgtok::XADD:1523 case tgtok::XSUB:1524 case tgtok::XMUL:1525 case tgtok::XDIV:1526 case tgtok::XAND:1527 case tgtok::XOR:1528 case tgtok::XXOR:1529 case tgtok::XSRA:1530 case tgtok::XSRL:1531 case tgtok::XSHL:1532 case tgtok::XEq:1533 case tgtok::XNe:1534 case tgtok::XLe:1535 case tgtok::XLt:1536 case tgtok::XGe:1537 case tgtok::XGt:1538 case tgtok::XListConcat:1539 case tgtok::XListSplat:1540 case tgtok::XListRemove:1541 case tgtok::XStrConcat:1542 case tgtok::XInterleave:1543 case tgtok::XGetDagArg:1544 case tgtok::XGetDagName:1545 case tgtok::XSetDagOp:1546 case tgtok::XSetDagOpName: { // Value ::= !binop '(' Value ',' Value ')'1547 tgtok::TokKind OpTok = Lex.getCode();1548 SMLoc OpLoc = Lex.getLoc();1549 Lex.Lex(); // eat the operation1550 1551 BinOpInit::BinaryOp Code;1552 switch (OpTok) {1553 default:1554 llvm_unreachable("Unhandled code!");1555 case tgtok::XConcat:1556 Code = BinOpInit::CONCAT;1557 break;1558 case tgtok::XMatch:1559 Code = BinOpInit::MATCH;1560 break;1561 case tgtok::XADD:1562 Code = BinOpInit::ADD;1563 break;1564 case tgtok::XSUB:1565 Code = BinOpInit::SUB;1566 break;1567 case tgtok::XMUL:1568 Code = BinOpInit::MUL;1569 break;1570 case tgtok::XDIV:1571 Code = BinOpInit::DIV;1572 break;1573 case tgtok::XAND:1574 Code = BinOpInit::AND;1575 break;1576 case tgtok::XOR:1577 Code = BinOpInit::OR;1578 break;1579 case tgtok::XXOR:1580 Code = BinOpInit::XOR;1581 break;1582 case tgtok::XSRA:1583 Code = BinOpInit::SRA;1584 break;1585 case tgtok::XSRL:1586 Code = BinOpInit::SRL;1587 break;1588 case tgtok::XSHL:1589 Code = BinOpInit::SHL;1590 break;1591 case tgtok::XEq:1592 Code = BinOpInit::EQ;1593 break;1594 case tgtok::XNe:1595 Code = BinOpInit::NE;1596 break;1597 case tgtok::XLe:1598 Code = BinOpInit::LE;1599 break;1600 case tgtok::XLt:1601 Code = BinOpInit::LT;1602 break;1603 case tgtok::XGe:1604 Code = BinOpInit::GE;1605 break;1606 case tgtok::XGt:1607 Code = BinOpInit::GT;1608 break;1609 case tgtok::XListConcat:1610 Code = BinOpInit::LISTCONCAT;1611 break;1612 case tgtok::XListSplat:1613 Code = BinOpInit::LISTSPLAT;1614 break;1615 case tgtok::XListRemove:1616 Code = BinOpInit::LISTREMOVE;1617 break;1618 case tgtok::XStrConcat:1619 Code = BinOpInit::STRCONCAT;1620 break;1621 case tgtok::XInterleave:1622 Code = BinOpInit::INTERLEAVE;1623 break;1624 case tgtok::XSetDagOp:1625 Code = BinOpInit::SETDAGOP;1626 break;1627 case tgtok::XSetDagOpName:1628 Code = BinOpInit::SETDAGOPNAME;1629 break;1630 case tgtok::XGetDagArg:1631 Code = BinOpInit::GETDAGARG;1632 break;1633 case tgtok::XGetDagName:1634 Code = BinOpInit::GETDAGNAME;1635 break;1636 }1637 1638 const RecTy *Type = nullptr;1639 const RecTy *ArgType = nullptr;1640 switch (OpTok) {1641 default:1642 llvm_unreachable("Unhandled code!");1643 case tgtok::XMatch:1644 Type = BitRecTy::get(Records);1645 ArgType = StringRecTy::get(Records);1646 break;1647 case tgtok::XConcat:1648 case tgtok::XSetDagOp:1649 Type = DagRecTy::get(Records);1650 ArgType = DagRecTy::get(Records);1651 break;1652 case tgtok::XGetDagArg:1653 Type = ParseOperatorType();1654 if (!Type) {1655 TokError("did not get type for !getdagarg operator");1656 return nullptr;1657 }1658 ArgType = DagRecTy::get(Records);1659 break;1660 case tgtok::XSetDagOpName:1661 Type = DagRecTy::get(Records);1662 ArgType = DagRecTy::get(Records);1663 break;1664 case tgtok::XGetDagName:1665 Type = StringRecTy::get(Records);1666 ArgType = DagRecTy::get(Records);1667 break;1668 case tgtok::XAND:1669 case tgtok::XOR:1670 case tgtok::XXOR:1671 case tgtok::XSRA:1672 case tgtok::XSRL:1673 case tgtok::XSHL:1674 case tgtok::XADD:1675 case tgtok::XSUB:1676 case tgtok::XMUL:1677 case tgtok::XDIV:1678 Type = IntRecTy::get(Records);1679 ArgType = IntRecTy::get(Records);1680 break;1681 case tgtok::XEq:1682 case tgtok::XNe:1683 case tgtok::XLe:1684 case tgtok::XLt:1685 case tgtok::XGe:1686 case tgtok::XGt:1687 Type = BitRecTy::get(Records);1688 // ArgType for the comparison operators is not yet known.1689 break;1690 case tgtok::XListConcat:1691 // We don't know the list type until we parse the first argument.1692 ArgType = ItemType;1693 break;1694 case tgtok::XListSplat:1695 // Can't do any typechecking until we parse the first argument.1696 break;1697 case tgtok::XListRemove:1698 // We don't know the list type until we parse the first argument.1699 ArgType = ItemType;1700 break;1701 case tgtok::XStrConcat:1702 Type = StringRecTy::get(Records);1703 ArgType = StringRecTy::get(Records);1704 break;1705 case tgtok::XInterleave:1706 Type = StringRecTy::get(Records);1707 // The first argument type is not yet known.1708 }1709 1710 if (Type && ItemType && !Type->typeIsConvertibleTo(ItemType)) {1711 Error(OpLoc, Twine("expected value of type '") + ItemType->getAsString() +1712 "', got '" + Type->getAsString() + "'");1713 return nullptr;1714 }1715 1716 if (!consume(tgtok::l_paren)) {1717 TokError("expected '(' after binary operator");1718 return nullptr;1719 }1720 1721 SmallVector<const Init *, 2> InitList;1722 1723 // Note that this loop consumes an arbitrary number of arguments.1724 // The actual count is checked later.1725 for (;;) {1726 SMLoc InitLoc = Lex.getLoc();1727 InitList.push_back(ParseValue(CurRec, ArgType));1728 if (!InitList.back())1729 return nullptr;1730 1731 const auto *InitListBack = dyn_cast<TypedInit>(InitList.back());1732 if (!InitListBack) {1733 Error(OpLoc, Twine("expected value to be a typed value, got '" +1734 InitList.back()->getAsString() + "'"));1735 return nullptr;1736 }1737 const RecTy *ListType = InitListBack->getType();1738 1739 if (!ArgType) {1740 // Argument type must be determined from the argument itself.1741 ArgType = ListType;1742 1743 switch (Code) {1744 case BinOpInit::LISTCONCAT:1745 if (!isa<ListRecTy>(ArgType)) {1746 Error(InitLoc, Twine("expected a list, got value of type '") +1747 ArgType->getAsString() + "'");1748 return nullptr;1749 }1750 break;1751 case BinOpInit::LISTSPLAT:1752 if (ItemType && InitList.size() == 1) {1753 if (!isa<ListRecTy>(ItemType)) {1754 Error(OpLoc,1755 Twine("expected output type to be a list, got type '") +1756 ItemType->getAsString() + "'");1757 return nullptr;1758 }1759 if (!ArgType->getListTy()->typeIsConvertibleTo(ItemType)) {1760 Error(OpLoc, Twine("expected first arg type to be '") +1761 ArgType->getAsString() +1762 "', got value of type '" +1763 cast<ListRecTy>(ItemType)1764 ->getElementType()1765 ->getAsString() +1766 "'");1767 return nullptr;1768 }1769 }1770 if (InitList.size() == 2 && !isa<IntRecTy>(ArgType)) {1771 Error(InitLoc, Twine("expected second parameter to be an int, got "1772 "value of type '") +1773 ArgType->getAsString() + "'");1774 return nullptr;1775 }1776 ArgType = nullptr; // Broken invariant: types not identical.1777 break;1778 case BinOpInit::LISTREMOVE:1779 if (!isa<ListRecTy>(ArgType)) {1780 Error(InitLoc, Twine("expected a list, got value of type '") +1781 ArgType->getAsString() + "'");1782 return nullptr;1783 }1784 break;1785 case BinOpInit::EQ:1786 case BinOpInit::NE:1787 if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) &&1788 !ArgType->typeIsConvertibleTo(StringRecTy::get(Records)) &&1789 !ArgType->typeIsConvertibleTo(RecordRecTy::get(Records, {}))) {1790 Error(InitLoc, Twine("expected bit, bits, int, string, or record; "1791 "got value of type '") +1792 ArgType->getAsString() + "'");1793 return nullptr;1794 }1795 break;1796 case BinOpInit::GETDAGARG: // The 2nd argument of !getdagarg could be1797 // index or name.1798 case BinOpInit::LE:1799 case BinOpInit::LT:1800 case BinOpInit::GE:1801 case BinOpInit::GT:1802 if (!ArgType->typeIsConvertibleTo(IntRecTy::get(Records)) &&1803 !ArgType->typeIsConvertibleTo(StringRecTy::get(Records))) {1804 Error(InitLoc, Twine("expected bit, bits, int, or string; "1805 "got value of type '") +1806 ArgType->getAsString() + "'");1807 return nullptr;1808 }1809 break;1810 case BinOpInit::INTERLEAVE:1811 switch (InitList.size()) {1812 case 1: // First argument must be a list of strings or integers.1813 if (ArgType != StringRecTy::get(Records)->getListTy() &&1814 !ArgType->typeIsConvertibleTo(1815 IntRecTy::get(Records)->getListTy())) {1816 Error(InitLoc,1817 Twine("expected list of string, int, bits, or bit; "1818 "got value of type '") +1819 ArgType->getAsString() + "'");1820 return nullptr;1821 }1822 break;1823 case 2: // Second argument must be a string.1824 if (!isa<StringRecTy>(ArgType)) {1825 Error(InitLoc, Twine("expected second argument to be a string, "1826 "got value of type '") +1827 ArgType->getAsString() + "'");1828 return nullptr;1829 }1830 break;1831 default:;1832 }1833 ArgType = nullptr; // Broken invariant: types not identical.1834 break;1835 default:1836 llvm_unreachable("other ops have fixed argument types");1837 }1838 1839 } else {1840 // Desired argument type is a known and in ArgType.1841 const RecTy *Resolved = resolveTypes(ArgType, ListType);1842 if (!Resolved) {1843 Error(InitLoc, Twine("expected value of type '") +1844 ArgType->getAsString() + "', got '" +1845 ListType->getAsString() + "'");1846 return nullptr;1847 }1848 if (Code != BinOpInit::ADD && Code != BinOpInit::SUB &&1849 Code != BinOpInit::AND && Code != BinOpInit::OR &&1850 Code != BinOpInit::XOR && Code != BinOpInit::SRA &&1851 Code != BinOpInit::SRL && Code != BinOpInit::SHL &&1852 Code != BinOpInit::MUL && Code != BinOpInit::DIV)1853 ArgType = Resolved;1854 }1855 1856 // Deal with BinOps whose arguments have different types, by1857 // rewriting ArgType in between them.1858 switch (Code) {1859 case BinOpInit::SETDAGOPNAME:1860 // After parsing the first dag argument, expect a string.1861 ArgType = StringRecTy::get(Records);1862 break;1863 case BinOpInit::SETDAGOP:1864 // After parsing the first dag argument, switch to expecting1865 // a record, with no restriction on its superclasses.1866 ArgType = RecordRecTy::get(Records, {});1867 break;1868 case BinOpInit::GETDAGARG:1869 // After parsing the first dag argument, expect an index integer or a1870 // name string.1871 ArgType = nullptr;1872 break;1873 case BinOpInit::GETDAGNAME:1874 // After parsing the first dag argument, expect an index integer.1875 ArgType = IntRecTy::get(Records);1876 break;1877 default:1878 break;1879 }1880 1881 if (!consume(tgtok::comma))1882 break;1883 }1884 1885 if (!consume(tgtok::r_paren)) {1886 TokError("expected ')' in operator");1887 return nullptr;1888 }1889 1890 // listconcat returns a list with type of the argument.1891 if (Code == BinOpInit::LISTCONCAT)1892 Type = ArgType;1893 // listsplat returns a list of type of the *first* argument.1894 if (Code == BinOpInit::LISTSPLAT)1895 Type = cast<TypedInit>(InitList.front())->getType()->getListTy();1896 // listremove returns a list with type of the argument.1897 if (Code == BinOpInit::LISTREMOVE)1898 Type = ArgType;1899 1900 // We allow multiple operands to associative operators like !strconcat as1901 // shorthand for nesting them.1902 if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT ||1903 Code == BinOpInit::CONCAT || Code == BinOpInit::ADD ||1904 Code == BinOpInit::AND || Code == BinOpInit::OR ||1905 Code == BinOpInit::XOR || Code == BinOpInit::MUL) {1906 while (InitList.size() > 2) {1907 const Init *RHS = InitList.pop_back_val();1908 RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec);1909 InitList.back() = RHS;1910 }1911 }1912 1913 if (InitList.size() == 2)1914 return (BinOpInit::get(Code, InitList[0], InitList[1], Type))1915 ->Fold(CurRec);1916 1917 Error(OpLoc, "expected two operands to operator");1918 return nullptr;1919 }1920 1921 case tgtok::XForEach:1922 case tgtok::XFilter: {1923 return ParseOperationForEachFilter(CurRec, ItemType);1924 }1925 1926 case tgtok::XRange: {1927 SMLoc OpLoc = Lex.getLoc();1928 Lex.Lex(); // eat the operation1929 1930 if (!consume(tgtok::l_paren)) {1931 TokError("expected '(' after !range operator");1932 return nullptr;1933 }1934 1935 SmallVector<const Init *, 2> Args;1936 bool FirstArgIsList = false;1937 for (;;) {1938 if (Args.size() >= 3) {1939 TokError("expected at most three values of integer");1940 return nullptr;1941 }1942 1943 SMLoc InitLoc = Lex.getLoc();1944 Args.push_back(ParseValue(CurRec));1945 if (!Args.back())1946 return nullptr;1947 1948 const auto *ArgBack = dyn_cast<TypedInit>(Args.back());1949 if (!ArgBack) {1950 Error(OpLoc, Twine("expected value to be a typed value, got '" +1951 Args.back()->getAsString() + "'"));1952 return nullptr;1953 }1954 1955 const RecTy *ArgBackType = ArgBack->getType();1956 if (!FirstArgIsList || Args.size() == 1) {1957 if (Args.size() == 1 && isa<ListRecTy>(ArgBackType)) {1958 FirstArgIsList = true; // Detect error if 2nd arg were present.1959 } else if (isa<IntRecTy>(ArgBackType)) {1960 // Assume 2nd arg should be IntRecTy1961 } else {1962 if (Args.size() != 1)1963 Error(InitLoc, Twine("expected value of type 'int', got '" +1964 ArgBackType->getAsString() + "'"));1965 else1966 Error(InitLoc, Twine("expected list or int, got value of type '") +1967 ArgBackType->getAsString() + "'");1968 return nullptr;1969 }1970 } else {1971 // Don't come here unless 1st arg is ListRecTy.1972 assert(isa<ListRecTy>(cast<TypedInit>(Args[0])->getType()));1973 Error(InitLoc, Twine("expected one list, got extra value of type '") +1974 ArgBackType->getAsString() + "'");1975 return nullptr;1976 }1977 if (!consume(tgtok::comma))1978 break;1979 }1980 1981 if (!consume(tgtok::r_paren)) {1982 TokError("expected ')' in operator");1983 return nullptr;1984 }1985 1986 const Init *LHS, *MHS, *RHS;1987 auto ArgCount = Args.size();1988 assert(ArgCount >= 1);1989 const auto *Arg0 = cast<TypedInit>(Args[0]);1990 const auto *Arg0Ty = Arg0->getType();1991 if (ArgCount == 1) {1992 if (isa<ListRecTy>(Arg0Ty)) {1993 // (0, !size(arg), 1)1994 LHS = IntInit::get(Records, 0);1995 MHS = UnOpInit::get(UnOpInit::SIZE, Arg0, IntRecTy::get(Records))1996 ->Fold(CurRec);1997 RHS = IntInit::get(Records, 1);1998 } else {1999 assert(isa<IntRecTy>(Arg0Ty));2000 // (0, arg, 1)2001 LHS = IntInit::get(Records, 0);2002 MHS = Arg0;2003 RHS = IntInit::get(Records, 1);2004 }2005 } else {2006 assert(isa<IntRecTy>(Arg0Ty));2007 const auto *Arg1 = cast<TypedInit>(Args[1]);2008 assert(isa<IntRecTy>(Arg1->getType()));2009 LHS = Arg0;2010 MHS = Arg1;2011 if (ArgCount == 3) {2012 // (start, end, step)2013 const auto *Arg2 = cast<TypedInit>(Args[2]);2014 assert(isa<IntRecTy>(Arg2->getType()));2015 RHS = Arg2;2016 } else {2017 // (start, end, 1)2018 RHS = IntInit::get(Records, 1);2019 }2020 }2021 return TernOpInit::get(TernOpInit::RANGE, LHS, MHS, RHS,2022 IntRecTy::get(Records)->getListTy())2023 ->Fold(CurRec);2024 }2025 2026 case tgtok::XSetDagArg:2027 case tgtok::XSetDagName:2028 case tgtok::XDag:2029 case tgtok::XIf:2030 case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'2031 TernOpInit::TernaryOp Code;2032 const RecTy *Type = nullptr;2033 2034 tgtok::TokKind LexCode = Lex.getCode();2035 Lex.Lex(); // Eat the operation.2036 switch (LexCode) {2037 default:2038 llvm_unreachable("Unhandled code!");2039 case tgtok::XDag:2040 Code = TernOpInit::DAG;2041 Type = DagRecTy::get(Records);2042 ItemType = nullptr;2043 break;2044 case tgtok::XIf:2045 Code = TernOpInit::IF;2046 break;2047 case tgtok::XSubst:2048 Code = TernOpInit::SUBST;2049 break;2050 case tgtok::XSetDagArg:2051 Code = TernOpInit::SETDAGARG;2052 Type = DagRecTy::get(Records);2053 ItemType = nullptr;2054 break;2055 case tgtok::XSetDagName:2056 Code = TernOpInit::SETDAGNAME;2057 Type = DagRecTy::get(Records);2058 ItemType = nullptr;2059 break;2060 }2061 if (!consume(tgtok::l_paren)) {2062 TokError("expected '(' after ternary operator");2063 return nullptr;2064 }2065 2066 const Init *LHS = ParseValue(CurRec);2067 if (!LHS)2068 return nullptr;2069 2070 if (!consume(tgtok::comma)) {2071 TokError("expected ',' in ternary operator");2072 return nullptr;2073 }2074 2075 SMLoc MHSLoc = Lex.getLoc();2076 const Init *MHS = ParseValue(CurRec, ItemType);2077 if (!MHS)2078 return nullptr;2079 2080 if (!consume(tgtok::comma)) {2081 TokError("expected ',' in ternary operator");2082 return nullptr;2083 }2084 2085 SMLoc RHSLoc = Lex.getLoc();2086 const Init *RHS = ParseValue(CurRec, ItemType);2087 if (!RHS)2088 return nullptr;2089 2090 if (!consume(tgtok::r_paren)) {2091 TokError("expected ')' in binary operator");2092 return nullptr;2093 }2094 2095 switch (LexCode) {2096 default:2097 llvm_unreachable("Unhandled code!");2098 case tgtok::XDag: {2099 const auto *MHSt = dyn_cast<TypedInit>(MHS);2100 if (!MHSt && !isa<UnsetInit>(MHS)) {2101 Error(MHSLoc, "could not determine type of the child list in !dag");2102 return nullptr;2103 }2104 if (MHSt && !isa<ListRecTy>(MHSt->getType())) {2105 Error(MHSLoc, Twine("expected list of children, got type '") +2106 MHSt->getType()->getAsString() + "'");2107 return nullptr;2108 }2109 2110 const auto *RHSt = dyn_cast<TypedInit>(RHS);2111 if (!RHSt && !isa<UnsetInit>(RHS)) {2112 Error(RHSLoc, "could not determine type of the name list in !dag");2113 return nullptr;2114 }2115 if (RHSt && StringRecTy::get(Records)->getListTy() != RHSt->getType()) {2116 Error(RHSLoc, Twine("expected list<string>, got type '") +2117 RHSt->getType()->getAsString() + "'");2118 return nullptr;2119 }2120 2121 if (!MHSt && !RHSt) {2122 Error(MHSLoc,2123 "cannot have both unset children and unset names in !dag");2124 return nullptr;2125 }2126 break;2127 }2128 case tgtok::XIf: {2129 const RecTy *MHSTy = nullptr;2130 const RecTy *RHSTy = nullptr;2131 2132 if (const auto *MHSt = dyn_cast<TypedInit>(MHS))2133 MHSTy = MHSt->getType();2134 if (const auto *MHSbits = dyn_cast<BitsInit>(MHS))2135 MHSTy = BitsRecTy::get(Records, MHSbits->getNumBits());2136 if (isa<BitInit>(MHS))2137 MHSTy = BitRecTy::get(Records);2138 2139 if (const auto *RHSt = dyn_cast<TypedInit>(RHS))2140 RHSTy = RHSt->getType();2141 if (const auto *RHSbits = dyn_cast<BitsInit>(RHS))2142 RHSTy = BitsRecTy::get(Records, RHSbits->getNumBits());2143 if (isa<BitInit>(RHS))2144 RHSTy = BitRecTy::get(Records);2145 2146 // For UnsetInit, it's typed from the other hand.2147 if (isa<UnsetInit>(MHS))2148 MHSTy = RHSTy;2149 if (isa<UnsetInit>(RHS))2150 RHSTy = MHSTy;2151 2152 if (!MHSTy || !RHSTy) {2153 TokError("could not get type for !if");2154 return nullptr;2155 }2156 2157 Type = resolveTypes(MHSTy, RHSTy);2158 if (!Type) {2159 TokError(Twine("inconsistent types '") + MHSTy->getAsString() +2160 "' and '" + RHSTy->getAsString() + "' for !if");2161 return nullptr;2162 }2163 break;2164 }2165 case tgtok::XSubst: {2166 const auto *RHSt = dyn_cast<TypedInit>(RHS);2167 if (!RHSt) {2168 TokError("could not get type for !subst");2169 return nullptr;2170 }2171 Type = RHSt->getType();2172 break;2173 }2174 case tgtok::XSetDagArg: {2175 const auto *MHSt = dyn_cast<TypedInit>(MHS);2176 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {2177 Error(MHSLoc, Twine("expected integer index or string name, got ") +2178 (MHSt ? ("type '" + MHSt->getType()->getAsString())2179 : ("'" + MHS->getAsString())) +2180 "'");2181 return nullptr;2182 }2183 break;2184 }2185 case tgtok::XSetDagName: {2186 const auto *MHSt = dyn_cast<TypedInit>(MHS);2187 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {2188 Error(MHSLoc, Twine("expected integer index or string name, got ") +2189 (MHSt ? ("type '" + MHSt->getType()->getAsString())2190 : ("'" + MHS->getAsString())) +2191 "'");2192 return nullptr;2193 }2194 const auto *RHSt = dyn_cast<TypedInit>(RHS);2195 // The name could be a string or unset.2196 if (RHSt && !isa<StringRecTy>(RHSt->getType())) {2197 Error(RHSLoc, Twine("expected string or unset name, got type '") +2198 RHSt->getType()->getAsString() + "'");2199 return nullptr;2200 }2201 break;2202 }2203 }2204 return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);2205 }2206 2207 case tgtok::XSubstr:2208 return ParseOperationSubstr(CurRec, ItemType);2209 2210 case tgtok::XFind:2211 return ParseOperationFind(CurRec, ItemType);2212 2213 case tgtok::XCond:2214 return ParseOperationCond(CurRec, ItemType);2215 2216 case tgtok::XFoldl: {2217 // Value ::= !foldl '(' Value ',' Value ',' Id ',' Id ',' Expr ')'2218 Lex.Lex(); // eat the operation2219 if (!consume(tgtok::l_paren)) {2220 TokError("expected '(' after !foldl");2221 return nullptr;2222 }2223 2224 const Init *StartUntyped = ParseValue(CurRec);2225 if (!StartUntyped)2226 return nullptr;2227 2228 const auto *Start = dyn_cast<TypedInit>(StartUntyped);2229 if (!Start) {2230 TokError(Twine("could not get type of !foldl start: '") +2231 StartUntyped->getAsString() + "'");2232 return nullptr;2233 }2234 2235 if (!consume(tgtok::comma)) {2236 TokError("expected ',' in !foldl");2237 return nullptr;2238 }2239 2240 const Init *ListUntyped = ParseValue(CurRec);2241 if (!ListUntyped)2242 return nullptr;2243 2244 const auto *List = dyn_cast<TypedInit>(ListUntyped);2245 if (!List) {2246 TokError(Twine("could not get type of !foldl list: '") +2247 ListUntyped->getAsString() + "'");2248 return nullptr;2249 }2250 2251 const auto *ListType = dyn_cast<ListRecTy>(List->getType());2252 if (!ListType) {2253 TokError(Twine("!foldl list must be a list, but is of type '") +2254 List->getType()->getAsString());2255 return nullptr;2256 }2257 2258 if (Lex.getCode() != tgtok::comma) {2259 TokError("expected ',' in !foldl");2260 return nullptr;2261 }2262 2263 if (Lex.Lex() != tgtok::Id) { // eat the ','2264 TokError("third argument of !foldl must be an identifier");2265 return nullptr;2266 }2267 2268 const Init *A = StringInit::get(Records, Lex.getCurStrVal());2269 if (CurRec && CurRec->getValue(A)) {2270 TokError((Twine("left !foldl variable '") + A->getAsString() +2271 "' already defined")2272 .str());2273 return nullptr;2274 }2275 2276 if (Lex.Lex() != tgtok::comma) { // eat the id2277 TokError("expected ',' in !foldl");2278 return nullptr;2279 }2280 2281 if (Lex.Lex() != tgtok::Id) { // eat the ','2282 TokError("fourth argument of !foldl must be an identifier");2283 return nullptr;2284 }2285 2286 const Init *B = StringInit::get(Records, Lex.getCurStrVal());2287 if (CurRec && CurRec->getValue(B)) {2288 TokError((Twine("right !foldl variable '") + B->getAsString() +2289 "' already defined")2290 .str());2291 return nullptr;2292 }2293 2294 if (Lex.Lex() != tgtok::comma) { // eat the id2295 TokError("expected ',' in !foldl");2296 return nullptr;2297 }2298 Lex.Lex(); // eat the ','2299 2300 // We need to create a temporary record to provide a scope for the2301 // two variables.2302 std::unique_ptr<Record> ParseRecTmp;2303 Record *ParseRec = CurRec;2304 if (!ParseRec) {2305 ParseRecTmp =2306 std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);2307 ParseRec = ParseRecTmp.get();2308 }2309 2310 TGVarScope *FoldScope = PushScope(ParseRec);2311 ParseRec->addValue(RecordVal(A, Start->getType(), RecordVal::FK_Normal));2312 ParseRec->addValue(2313 RecordVal(B, ListType->getElementType(), RecordVal::FK_Normal));2314 const Init *ExprUntyped = ParseValue(ParseRec);2315 ParseRec->removeValue(A);2316 ParseRec->removeValue(B);2317 PopScope(FoldScope);2318 if (!ExprUntyped)2319 return nullptr;2320 2321 const auto *Expr = dyn_cast<TypedInit>(ExprUntyped);2322 if (!Expr) {2323 TokError("could not get type of !foldl expression");2324 return nullptr;2325 }2326 2327 if (Expr->getType() != Start->getType()) {2328 TokError(Twine("!foldl expression must be of same type as start (") +2329 Start->getType()->getAsString() + "), but is of type " +2330 Expr->getType()->getAsString());2331 return nullptr;2332 }2333 2334 if (!consume(tgtok::r_paren)) {2335 TokError("expected ')' in fold operator");2336 return nullptr;2337 }2338 2339 return FoldOpInit::get(Start, List, A, B, Expr, Start->getType())2340 ->Fold(CurRec);2341 }2342 }2343}2344 2345/// ParseOperatorType - Parse a type for an operator. This returns2346/// null on error.2347///2348/// OperatorType ::= '<' Type '>'2349///2350const RecTy *TGParser::ParseOperatorType() {2351 const RecTy *Type = nullptr;2352 2353 if (!consume(tgtok::less)) {2354 TokError("expected type name for operator");2355 return nullptr;2356 }2357 2358 if (Lex.getCode() == tgtok::Code)2359 TokError("the 'code' type is not allowed in bang operators; use 'string'");2360 2361 Type = ParseType();2362 2363 if (!Type) {2364 TokError("expected type name for operator");2365 return nullptr;2366 }2367 2368 if (!consume(tgtok::greater)) {2369 TokError("expected type name for operator");2370 return nullptr;2371 }2372 2373 return Type;2374}2375 2376/// Parse the !substr operation. Return null on error.2377///2378/// Substr ::= !substr(string, start-int [, length-int]) => string2379const Init *TGParser::ParseOperationSubstr(Record *CurRec,2380 const RecTy *ItemType) {2381 TernOpInit::TernaryOp Code = TernOpInit::SUBSTR;2382 const RecTy *Type = StringRecTy::get(Records);2383 2384 Lex.Lex(); // eat the operation2385 2386 if (!consume(tgtok::l_paren)) {2387 TokError("expected '(' after !substr operator");2388 return nullptr;2389 }2390 2391 const Init *LHS = ParseValue(CurRec);2392 if (!LHS)2393 return nullptr;2394 2395 if (!consume(tgtok::comma)) {2396 TokError("expected ',' in !substr operator");2397 return nullptr;2398 }2399 2400 SMLoc MHSLoc = Lex.getLoc();2401 const Init *MHS = ParseValue(CurRec);2402 if (!MHS)2403 return nullptr;2404 2405 SMLoc RHSLoc = Lex.getLoc();2406 const Init *RHS;2407 if (consume(tgtok::comma)) {2408 RHSLoc = Lex.getLoc();2409 RHS = ParseValue(CurRec);2410 if (!RHS)2411 return nullptr;2412 } else {2413 RHS = IntInit::get(Records, std::numeric_limits<int64_t>::max());2414 }2415 2416 if (!consume(tgtok::r_paren)) {2417 TokError("expected ')' in !substr operator");2418 return nullptr;2419 }2420 2421 if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {2422 Error(RHSLoc, Twine("expected value of type '") + ItemType->getAsString() +2423 "', got '" + Type->getAsString() + "'");2424 }2425 2426 const auto *LHSt = dyn_cast<TypedInit>(LHS);2427 if (!LHSt && !isa<UnsetInit>(LHS)) {2428 TokError("could not determine type of the string in !substr");2429 return nullptr;2430 }2431 if (LHSt && !isa<StringRecTy>(LHSt->getType())) {2432 TokError(Twine("expected string, got type '") +2433 LHSt->getType()->getAsString() + "'");2434 return nullptr;2435 }2436 2437 const auto *MHSt = dyn_cast<TypedInit>(MHS);2438 if (!MHSt && !isa<UnsetInit>(MHS)) {2439 TokError("could not determine type of the start position in !substr");2440 return nullptr;2441 }2442 if (MHSt && !isa<IntRecTy>(MHSt->getType())) {2443 Error(MHSLoc, Twine("expected int, got type '") +2444 MHSt->getType()->getAsString() + "'");2445 return nullptr;2446 }2447 2448 if (RHS) {2449 const auto *RHSt = dyn_cast<TypedInit>(RHS);2450 if (!RHSt && !isa<UnsetInit>(RHS)) {2451 TokError("could not determine type of the length in !substr");2452 return nullptr;2453 }2454 if (RHSt && !isa<IntRecTy>(RHSt->getType())) {2455 TokError(Twine("expected int, got type '") +2456 RHSt->getType()->getAsString() + "'");2457 return nullptr;2458 }2459 }2460 2461 return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);2462}2463 2464/// Parse the !find operation. Return null on error.2465///2466/// Substr ::= !find(string, string [, start-int]) => int2467const Init *TGParser::ParseOperationFind(Record *CurRec,2468 const RecTy *ItemType) {2469 TernOpInit::TernaryOp Code = TernOpInit::FIND;2470 const RecTy *Type = IntRecTy::get(Records);2471 2472 Lex.Lex(); // eat the operation2473 2474 if (!consume(tgtok::l_paren)) {2475 TokError("expected '(' after !find operator");2476 return nullptr;2477 }2478 2479 const Init *LHS = ParseValue(CurRec);2480 if (!LHS)2481 return nullptr;2482 2483 if (!consume(tgtok::comma)) {2484 TokError("expected ',' in !find operator");2485 return nullptr;2486 }2487 2488 SMLoc MHSLoc = Lex.getLoc();2489 const Init *MHS = ParseValue(CurRec);2490 if (!MHS)2491 return nullptr;2492 2493 SMLoc RHSLoc = Lex.getLoc();2494 const Init *RHS;2495 if (consume(tgtok::comma)) {2496 RHSLoc = Lex.getLoc();2497 RHS = ParseValue(CurRec);2498 if (!RHS)2499 return nullptr;2500 } else {2501 RHS = IntInit::get(Records, 0);2502 }2503 2504 if (!consume(tgtok::r_paren)) {2505 TokError("expected ')' in !find operator");2506 return nullptr;2507 }2508 2509 if (ItemType && !Type->typeIsConvertibleTo(ItemType)) {2510 Error(RHSLoc, Twine("expected value of type '") + ItemType->getAsString() +2511 "', got '" + Type->getAsString() + "'");2512 }2513 2514 const auto *LHSt = dyn_cast<TypedInit>(LHS);2515 if (!LHSt && !isa<UnsetInit>(LHS)) {2516 TokError("could not determine type of the source string in !find");2517 return nullptr;2518 }2519 if (LHSt && !isa<StringRecTy>(LHSt->getType())) {2520 TokError(Twine("expected string, got type '") +2521 LHSt->getType()->getAsString() + "'");2522 return nullptr;2523 }2524 2525 const auto *MHSt = dyn_cast<TypedInit>(MHS);2526 if (!MHSt && !isa<UnsetInit>(MHS)) {2527 TokError("could not determine type of the target string in !find");2528 return nullptr;2529 }2530 if (MHSt && !isa<StringRecTy>(MHSt->getType())) {2531 Error(MHSLoc, Twine("expected string, got type '") +2532 MHSt->getType()->getAsString() + "'");2533 return nullptr;2534 }2535 2536 if (RHS) {2537 const auto *RHSt = dyn_cast<TypedInit>(RHS);2538 if (!RHSt && !isa<UnsetInit>(RHS)) {2539 TokError("could not determine type of the start position in !find");2540 return nullptr;2541 }2542 if (RHSt && !isa<IntRecTy>(RHSt->getType())) {2543 TokError(Twine("expected int, got type '") +2544 RHSt->getType()->getAsString() + "'");2545 return nullptr;2546 }2547 }2548 2549 return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec);2550}2551 2552/// Parse the !foreach and !filter operations. Return null on error.2553///2554/// ForEach ::= !foreach(ID, list-or-dag, expr) => list<expr type>2555/// Filter ::= !foreach(ID, list, predicate) ==> list<list type>2556const Init *TGParser::ParseOperationForEachFilter(Record *CurRec,2557 const RecTy *ItemType) {2558 SMLoc OpLoc = Lex.getLoc();2559 tgtok::TokKind Operation = Lex.getCode();2560 Lex.Lex(); // eat the operation2561 if (Lex.getCode() != tgtok::l_paren) {2562 TokError("expected '(' after !foreach/!filter");2563 return nullptr;2564 }2565 2566 if (Lex.Lex() != tgtok::Id) { // eat the '('2567 TokError("first argument of !foreach/!filter must be an identifier");2568 return nullptr;2569 }2570 2571 const Init *LHS = StringInit::get(Records, Lex.getCurStrVal());2572 Lex.Lex(); // eat the ID.2573 2574 if (CurRec && CurRec->getValue(LHS)) {2575 TokError((Twine("iteration variable '") + LHS->getAsString() +2576 "' is already defined")2577 .str());2578 return nullptr;2579 }2580 2581 if (!consume(tgtok::comma)) {2582 TokError("expected ',' in !foreach/!filter");2583 return nullptr;2584 }2585 2586 const Init *MHS = ParseValue(CurRec);2587 if (!MHS)2588 return nullptr;2589 2590 if (!consume(tgtok::comma)) {2591 TokError("expected ',' in !foreach/!filter");2592 return nullptr;2593 }2594 2595 const auto *MHSt = dyn_cast<TypedInit>(MHS);2596 if (!MHSt) {2597 TokError("could not get type of !foreach/!filter list or dag");2598 return nullptr;2599 }2600 2601 const RecTy *InEltType = nullptr;2602 const RecTy *ExprEltType = nullptr;2603 bool IsDAG = false;2604 2605 if (const auto *InListTy = dyn_cast<ListRecTy>(MHSt->getType())) {2606 InEltType = InListTy->getElementType();2607 if (ItemType) {2608 if (const auto *OutListTy = dyn_cast<ListRecTy>(ItemType)) {2609 ExprEltType = (Operation == tgtok::XForEach)2610 ? OutListTy->getElementType()2611 : IntRecTy::get(Records);2612 } else {2613 Error(OpLoc, "expected value of type '" +2614 Twine(ItemType->getAsString()) +2615 "', but got list type");2616 return nullptr;2617 }2618 }2619 } else if (const auto *InDagTy = dyn_cast<DagRecTy>(MHSt->getType())) {2620 if (Operation == tgtok::XFilter) {2621 TokError("!filter must have a list argument");2622 return nullptr;2623 }2624 InEltType = InDagTy;2625 if (ItemType && !isa<DagRecTy>(ItemType)) {2626 Error(OpLoc, "expected value of type '" + Twine(ItemType->getAsString()) +2627 "', but got dag type");2628 return nullptr;2629 }2630 IsDAG = true;2631 } else {2632 if (Operation == tgtok::XForEach)2633 TokError("!foreach must have a list or dag argument");2634 else2635 TokError("!filter must have a list argument");2636 return nullptr;2637 }2638 2639 // We need to create a temporary record to provide a scope for the2640 // iteration variable.2641 std::unique_ptr<Record> ParseRecTmp;2642 Record *ParseRec = CurRec;2643 if (!ParseRec) {2644 ParseRecTmp =2645 std::make_unique<Record>(".parse", ArrayRef<SMLoc>{}, Records);2646 ParseRec = ParseRecTmp.get();2647 }2648 TGVarScope *TempScope = PushScope(ParseRec);2649 ParseRec->addValue(RecordVal(LHS, InEltType, RecordVal::FK_Normal));2650 const Init *RHS = ParseValue(ParseRec, ExprEltType);2651 ParseRec->removeValue(LHS);2652 PopScope(TempScope);2653 if (!RHS)2654 return nullptr;2655 2656 if (!consume(tgtok::r_paren)) {2657 TokError("expected ')' in !foreach/!filter");2658 return nullptr;2659 }2660 2661 const RecTy *OutType = InEltType;2662 if (Operation == tgtok::XForEach && !IsDAG) {2663 const auto *RHSt = dyn_cast<TypedInit>(RHS);2664 if (!RHSt) {2665 TokError("could not get type of !foreach result expression");2666 return nullptr;2667 }2668 OutType = RHSt->getType()->getListTy();2669 } else if (Operation == tgtok::XFilter) {2670 OutType = InEltType->getListTy();2671 }2672 2673 return (TernOpInit::get((Operation == tgtok::XForEach) ? TernOpInit::FOREACH2674 : TernOpInit::FILTER,2675 LHS, MHS, RHS, OutType))2676 ->Fold(CurRec);2677}2678 2679const Init *TGParser::ParseOperationCond(Record *CurRec,2680 const RecTy *ItemType) {2681 Lex.Lex(); // eat the operation 'cond'2682 2683 if (!consume(tgtok::l_paren)) {2684 TokError("expected '(' after !cond operator");2685 return nullptr;2686 }2687 2688 // Parse through '[Case: Val,]+'2689 SmallVector<const Init *, 4> Case;2690 SmallVector<const Init *, 4> Val;2691 while (true) {2692 if (consume(tgtok::r_paren))2693 break;2694 2695 const Init *V = ParseValue(CurRec);2696 if (!V)2697 return nullptr;2698 Case.push_back(V);2699 2700 if (!consume(tgtok::colon)) {2701 TokError("expected ':' following a condition in !cond operator");2702 return nullptr;2703 }2704 2705 V = ParseValue(CurRec, ItemType);2706 if (!V)2707 return nullptr;2708 Val.push_back(V);2709 2710 if (consume(tgtok::r_paren))2711 break;2712 2713 if (!consume(tgtok::comma)) {2714 TokError("expected ',' or ')' following a value in !cond operator");2715 return nullptr;2716 }2717 }2718 2719 if (Case.size() < 1) {2720 TokError(2721 "there should be at least 1 'condition : value' in the !cond operator");2722 return nullptr;2723 }2724 2725 // resolve type2726 const RecTy *Type = nullptr;2727 for (const Init *V : Val) {2728 const RecTy *VTy = nullptr;2729 if (const auto *Vt = dyn_cast<TypedInit>(V))2730 VTy = Vt->getType();2731 if (const auto *Vbits = dyn_cast<BitsInit>(V))2732 VTy = BitsRecTy::get(Records, Vbits->getNumBits());2733 if (isa<BitInit>(V))2734 VTy = BitRecTy::get(Records);2735 2736 if (Type == nullptr) {2737 if (!isa<UnsetInit>(V))2738 Type = VTy;2739 } else {2740 if (!isa<UnsetInit>(V)) {2741 const RecTy *RType = resolveTypes(Type, VTy);2742 if (!RType) {2743 TokError(Twine("inconsistent types '") + Type->getAsString() +2744 "' and '" + VTy->getAsString() + "' for !cond");2745 return nullptr;2746 }2747 Type = RType;2748 }2749 }2750 }2751 2752 if (!Type) {2753 TokError("could not determine type for !cond from its arguments");2754 return nullptr;2755 }2756 return CondOpInit::get(Case, Val, Type)->Fold(CurRec);2757}2758 2759/// ParseSimpleValue - Parse a tblgen value. This returns null on error.2760///2761/// SimpleValue ::= IDValue2762/// SimpleValue ::= INTVAL2763/// SimpleValue ::= STRVAL+2764/// SimpleValue ::= CODEFRAGMENT2765/// SimpleValue ::= '?'2766/// SimpleValue ::= '{' ValueList '}'2767/// SimpleValue ::= ID '<' ValueListNE '>'2768/// SimpleValue ::= '[' ValueList ']'2769/// SimpleValue ::= '(' IDValue DagArgList ')'2770/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')'2771/// SimpleValue ::= ADDTOK '(' Value ',' Value ')'2772/// SimpleValue ::= DIVTOK '(' Value ',' Value ')'2773/// SimpleValue ::= SUBTOK '(' Value ',' Value ')'2774/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'2775/// SimpleValue ::= SRATOK '(' Value ',' Value ')'2776/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'2777/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'2778/// SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')'2779/// SimpleValue ::= LISTREMOVETOK '(' Value ',' Value ')'2780/// SimpleValue ::= RANGE '(' Value ')'2781/// SimpleValue ::= RANGE '(' Value ',' Value ')'2782/// SimpleValue ::= RANGE '(' Value ',' Value ',' Value ')'2783/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'2784/// SimpleValue ::= COND '(' [Value ':' Value,]+ ')'2785///2786const Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,2787 IDParseMode Mode) {2788 const Init *R = nullptr;2789 tgtok::TokKind Code = Lex.getCode();2790 2791 // Parse bang operators.2792 if (tgtok::isBangOperator(Code))2793 return ParseOperation(CurRec, ItemType);2794 2795 switch (Code) {2796 default:2797 TokError("Unknown or reserved token when parsing a value");2798 break;2799 2800 case tgtok::TrueVal:2801 R = IntInit::get(Records, 1);2802 Lex.Lex();2803 break;2804 case tgtok::FalseVal:2805 R = IntInit::get(Records, 0);2806 Lex.Lex();2807 break;2808 case tgtok::IntVal:2809 R = IntInit::get(Records, Lex.getCurIntVal());2810 Lex.Lex();2811 break;2812 case tgtok::BinaryIntVal: {2813 auto BinaryVal = Lex.getCurBinaryIntVal();2814 SmallVector<Init *, 16> Bits(BinaryVal.second);2815 for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)2816 Bits[i] = BitInit::get(Records, BinaryVal.first & (1LL << i));2817 R = BitsInit::get(Records, Bits);2818 Lex.Lex();2819 break;2820 }2821 case tgtok::StrVal: {2822 std::string Val = Lex.getCurStrVal();2823 Lex.Lex();2824 2825 // Handle multiple consecutive concatenated strings.2826 while (Lex.getCode() == tgtok::StrVal) {2827 Val += Lex.getCurStrVal();2828 Lex.Lex();2829 }2830 2831 R = StringInit::get(Records, Val);2832 break;2833 }2834 case tgtok::CodeFragment:2835 R = StringInit::get(Records, Lex.getCurStrVal(), StringInit::SF_Code);2836 Lex.Lex();2837 break;2838 case tgtok::question:2839 R = UnsetInit::get(Records);2840 Lex.Lex();2841 break;2842 case tgtok::Id: {2843 SMRange NameLoc = Lex.getLocRange();2844 const StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());2845 tgtok::TokKind Next = Lex.Lex();2846 if (Next == tgtok::equal) // Named argument.2847 return Name;2848 if (Next != tgtok::less) // consume the Id.2849 return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue2850 2851 // Value ::= CLASSID '<' ArgValueList '>' (CLASSID has been consumed)2852 // This is supposed to synthesize a new anonymous definition, deriving2853 // from the class with the template arguments, but no body.2854 const Record *Class = Records.getClass(Name->getValue());2855 if (!Class) {2856 Error(NameLoc.Start,2857 "Expected a class name, got '" + Name->getValue() + "'");2858 return nullptr;2859 }2860 2861 SmallVector<const ArgumentInit *, 8> Args;2862 SmallVector<SMLoc> ArgLocs;2863 Lex.Lex(); // consume the <2864 if (ParseTemplateArgValueList(Args, ArgLocs, CurRec, Class))2865 return nullptr; // Error parsing value list.2866 2867 if (CheckTemplateArgValues(Args, ArgLocs, Class))2868 return nullptr; // Error checking template argument values.2869 2870 if (resolveArguments(Class, Args, NameLoc.Start))2871 return nullptr;2872 2873 if (TrackReferenceLocs)2874 Class->appendReferenceLoc(NameLoc);2875 return VarDefInit::get(NameLoc.Start, Class, Args)->Fold();2876 }2877 case tgtok::l_brace: { // Value ::= '{' ValueList '}'2878 SMLoc BraceLoc = Lex.getLoc();2879 Lex.Lex(); // eat the '{'2880 SmallVector<const Init *, 16> Vals;2881 2882 if (Lex.getCode() != tgtok::r_brace) {2883 ParseValueList(Vals, CurRec);2884 if (Vals.empty())2885 return nullptr;2886 }2887 if (!consume(tgtok::r_brace)) {2888 TokError("expected '}' at end of bit list value");2889 return nullptr;2890 }2891 2892 SmallVector<const Init *, 16> NewBits;2893 2894 // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it2895 // first. We'll first read everything in to a vector, then we can reverse2896 // it to get the bits in the correct order for the BitsInit value.2897 for (unsigned i = 0, e = Vals.size(); i != e; ++i) {2898 // FIXME: The following two loops would not be duplicated2899 // if the API was a little more orthogonal.2900 2901 // bits<n> values are allowed to initialize n bits.2902 if (const auto *BI = dyn_cast<BitsInit>(Vals[i])) {2903 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)2904 NewBits.push_back(BI->getBit((e - i) - 1));2905 continue;2906 }2907 // bits<n> can also come from variable initializers.2908 if (const auto *VI = dyn_cast<VarInit>(Vals[i])) {2909 if (const auto *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) {2910 for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)2911 NewBits.push_back(VI->getBit((e - i) - 1));2912 continue;2913 }2914 // Fallthrough to try convert this to a bit.2915 }2916 // All other values must be convertible to just a single bit.2917 const Init *Bit = Vals[i]->getCastTo(BitRecTy::get(Records));2918 if (!Bit) {2919 Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +2920 ") is not convertable to a bit");2921 return nullptr;2922 }2923 NewBits.push_back(Bit);2924 }2925 std::reverse(NewBits.begin(), NewBits.end());2926 return BitsInit::get(Records, NewBits);2927 }2928 case tgtok::l_square: { // Value ::= '[' ValueList ']'2929 Lex.Lex(); // eat the '['2930 SmallVector<const Init *, 16> Vals;2931 2932 const RecTy *DeducedEltTy = nullptr;2933 const ListRecTy *GivenListTy = nullptr;2934 2935 if (ItemType) {2936 const auto *ListType = dyn_cast<ListRecTy>(ItemType);2937 if (!ListType) {2938 TokError(Twine("Encountered a list when expecting a ") +2939 ItemType->getAsString());2940 return nullptr;2941 }2942 GivenListTy = ListType;2943 }2944 2945 if (Lex.getCode() != tgtok::r_square) {2946 ParseValueList(Vals, CurRec,2947 GivenListTy ? GivenListTy->getElementType() : nullptr);2948 if (Vals.empty())2949 return nullptr;2950 }2951 if (!consume(tgtok::r_square)) {2952 TokError("expected ']' at end of list value");2953 return nullptr;2954 }2955 2956 const RecTy *GivenEltTy = nullptr;2957 if (consume(tgtok::less)) {2958 // Optional list element type2959 GivenEltTy = ParseType();2960 if (!GivenEltTy) {2961 // Couldn't parse element type2962 return nullptr;2963 }2964 2965 if (!consume(tgtok::greater)) {2966 TokError("expected '>' at end of list element type");2967 return nullptr;2968 }2969 }2970 2971 // Check elements2972 const RecTy *EltTy = nullptr;2973 for (const Init *V : Vals) {2974 const auto *TArg = dyn_cast<TypedInit>(V);2975 if (TArg) {2976 if (EltTy) {2977 EltTy = resolveTypes(EltTy, TArg->getType());2978 if (!EltTy) {2979 TokError("Incompatible types in list elements");2980 return nullptr;2981 }2982 } else {2983 EltTy = TArg->getType();2984 }2985 }2986 }2987 2988 if (GivenEltTy) {2989 if (EltTy) {2990 // Verify consistency2991 if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {2992 TokError("Incompatible types in list elements");2993 return nullptr;2994 }2995 }2996 EltTy = GivenEltTy;2997 }2998 2999 if (!EltTy) {3000 if (!ItemType) {3001 TokError("No type for list");3002 return nullptr;3003 }3004 DeducedEltTy = GivenListTy->getElementType();3005 } else {3006 // Make sure the deduced type is compatible with the given type3007 if (GivenListTy) {3008 if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {3009 TokError(Twine("Element type mismatch for list: element type '") +3010 EltTy->getAsString() + "' not convertible to '" +3011 GivenListTy->getElementType()->getAsString());3012 return nullptr;3013 }3014 }3015 DeducedEltTy = EltTy;3016 }3017 3018 return ListInit::get(Vals, DeducedEltTy);3019 }3020 case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'3021 // Value ::= '(' '[' ValueList ']' DagArgList ')'3022 Lex.Lex(); // eat the '('3023 if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&3024 Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp &&3025 Lex.getCode() != tgtok::l_square) {3026 TokError("expected identifier or list of value types in dag init");3027 return nullptr;3028 }3029 3030 const Init *Operator = ParseValue(CurRec);3031 if (!Operator)3032 return nullptr;3033 3034 // If the operator name is present, parse it.3035 const StringInit *OperatorName = nullptr;3036 if (consume(tgtok::colon)) {3037 if (Lex.getCode() != tgtok::VarName) { // eat the ':'3038 TokError("expected variable name in dag operator");3039 return nullptr;3040 }3041 OperatorName = StringInit::get(Records, Lex.getCurStrVal());3042 Lex.Lex(); // eat the VarName.3043 }3044 3045 SmallVector<std::pair<const Init *, const StringInit *>, 8> DagArgs;3046 if (Lex.getCode() != tgtok::r_paren) {3047 ParseDagArgList(DagArgs, CurRec);3048 if (DagArgs.empty())3049 return nullptr;3050 }3051 3052 if (!consume(tgtok::r_paren)) {3053 TokError("expected ')' in dag init");3054 return nullptr;3055 }3056 3057 return DagInit::get(Operator, OperatorName, DagArgs);3058 }3059 }3060 3061 return R;3062}3063 3064/// ParseValue - Parse a TableGen value. This returns null on error.3065///3066/// Value ::= SimpleValue ValueSuffix*3067/// ValueSuffix ::= '{' BitList '}'3068/// ValueSuffix ::= '[' SliceElements ']'3069/// ValueSuffix ::= '.' ID3070///3071const Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,3072 IDParseMode Mode) {3073 SMLoc LHSLoc = Lex.getLoc();3074 const Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);3075 if (!Result)3076 return nullptr;3077 3078 // Parse the suffixes now if present.3079 while (true) {3080 switch (Lex.getCode()) {3081 default:3082 return Result;3083 case tgtok::l_brace: {3084 if (Mode == ParseNameMode)3085 // This is the beginning of the object body.3086 return Result;3087 3088 SMLoc CurlyLoc = Lex.getLoc();3089 Lex.Lex(); // eat the '{'3090 SmallVector<unsigned, 16> Ranges;3091 ParseRangeList(Ranges);3092 if (Ranges.empty())3093 return nullptr;3094 3095 // Reverse the bitlist.3096 std::reverse(Ranges.begin(), Ranges.end());3097 Result = Result->convertInitializerBitRange(Ranges);3098 if (!Result) {3099 Error(CurlyLoc, "Invalid bit range for value");3100 return nullptr;3101 }3102 3103 // Eat the '}'.3104 if (!consume(tgtok::r_brace)) {3105 TokError("expected '}' at end of bit range list");3106 return nullptr;3107 }3108 break;3109 }3110 case tgtok::l_square: {3111 const auto *LHS = dyn_cast<TypedInit>(Result);3112 if (!LHS) {3113 Error(LHSLoc, "Invalid value, list expected");3114 return nullptr;3115 }3116 3117 const auto *LHSTy = dyn_cast<ListRecTy>(LHS->getType());3118 if (!LHSTy) {3119 Error(LHSLoc, "Type '" + Twine(LHS->getType()->getAsString()) +3120 "' is invalid, list expected");3121 return nullptr;3122 }3123 3124 Lex.Lex(); // eat the '['3125 const TypedInit *RHS = ParseSliceElements(CurRec, /*Single=*/true);3126 if (!RHS)3127 return nullptr;3128 3129 if (isa<ListRecTy>(RHS->getType())) {3130 Result =3131 BinOpInit::get(BinOpInit::LISTSLICE, LHS, RHS, LHSTy)->Fold(CurRec);3132 } else {3133 Result = BinOpInit::get(BinOpInit::LISTELEM, LHS, RHS,3134 LHSTy->getElementType())3135 ->Fold(CurRec);3136 }3137 3138 assert(Result);3139 3140 // Eat the ']'.3141 if (!consume(tgtok::r_square)) {3142 TokError("expected ']' at end of list slice");3143 return nullptr;3144 }3145 break;3146 }3147 case tgtok::dot: {3148 if (Lex.Lex() != tgtok::Id) { // eat the .3149 TokError("expected field identifier after '.'");3150 return nullptr;3151 }3152 SMRange FieldNameLoc = Lex.getLocRange();3153 const StringInit *FieldName =3154 StringInit::get(Records, Lex.getCurStrVal());3155 if (!Result->getFieldType(FieldName)) {3156 TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +3157 Result->getAsString() + "'");3158 return nullptr;3159 }3160 3161 // Add a reference to this field if we know the record class.3162 if (TrackReferenceLocs) {3163 if (const auto *DI = dyn_cast<DefInit>(Result)) {3164 const RecordVal *V = DI->getDef()->getValue(FieldName);3165 const_cast<RecordVal *>(V)->addReferenceLoc(FieldNameLoc);3166 } else if (const auto *TI = dyn_cast<TypedInit>(Result)) {3167 if (const auto *RecTy = dyn_cast<RecordRecTy>(TI->getType())) {3168 for (const Record *R : RecTy->getClasses())3169 if (const auto *RV = R->getValue(FieldName))3170 const_cast<RecordVal *>(RV)->addReferenceLoc(FieldNameLoc);3171 }3172 }3173 }3174 3175 Result = FieldInit::get(Result, FieldName)->Fold(CurRec);3176 Lex.Lex(); // eat field name3177 break;3178 }3179 3180 case tgtok::paste:3181 SMLoc PasteLoc = Lex.getLoc();3182 const auto *LHS = dyn_cast<TypedInit>(Result);3183 if (!LHS) {3184 Error(PasteLoc, "LHS of paste is not typed!");3185 return nullptr;3186 }3187 3188 // Check if it's a 'listA # listB'3189 if (isa<ListRecTy>(LHS->getType())) {3190 Lex.Lex(); // Eat the '#'.3191 3192 assert(Mode == ParseValueMode && "encountered paste of lists in name");3193 3194 switch (Lex.getCode()) {3195 case tgtok::colon:3196 case tgtok::semi:3197 case tgtok::l_brace:3198 Result = LHS; // trailing paste, ignore.3199 break;3200 default:3201 const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);3202 if (!RHSResult)3203 return nullptr;3204 Result = BinOpInit::getListConcat(LHS, RHSResult);3205 break;3206 }3207 break;3208 }3209 3210 // Create a !strconcat() operation, first casting each operand to3211 // a string if necessary.3212 if (LHS->getType() != StringRecTy::get(Records)) {3213 auto CastLHS = dyn_cast<TypedInit>(3214 UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get(Records))3215 ->Fold(CurRec));3216 if (!CastLHS) {3217 Error(PasteLoc,3218 Twine("can't cast '") + LHS->getAsString() + "' to string");3219 return nullptr;3220 }3221 LHS = CastLHS;3222 }3223 3224 const TypedInit *RHS = nullptr;3225 3226 Lex.Lex(); // Eat the '#'.3227 switch (Lex.getCode()) {3228 case tgtok::colon:3229 case tgtok::semi:3230 case tgtok::l_brace:3231 // These are all of the tokens that can begin an object body.3232 // Some of these can also begin values but we disallow those cases3233 // because they are unlikely to be useful.3234 3235 // Trailing paste, concat with an empty string.3236 RHS = StringInit::get(Records, "");3237 break;3238 3239 default:3240 const Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);3241 if (!RHSResult)3242 return nullptr;3243 RHS = dyn_cast<TypedInit>(RHSResult);3244 if (!RHS) {3245 Error(PasteLoc, "RHS of paste is not typed!");3246 return nullptr;3247 }3248 3249 if (RHS->getType() != StringRecTy::get(Records)) {3250 auto CastRHS = dyn_cast<TypedInit>(3251 UnOpInit::get(UnOpInit::CAST, RHS, StringRecTy::get(Records))3252 ->Fold(CurRec));3253 if (!CastRHS) {3254 Error(PasteLoc,3255 Twine("can't cast '") + RHS->getAsString() + "' to string");3256 return nullptr;3257 }3258 RHS = CastRHS;3259 }3260 3261 break;3262 }3263 3264 Result = BinOpInit::getStrConcat(LHS, RHS);3265 break;3266 }3267 }3268}3269 3270/// ParseDagArgList - Parse the argument list for a dag literal expression.3271///3272/// DagArg ::= Value (':' VARNAME)?3273/// DagArg ::= VARNAME3274/// DagArgList ::= DagArg3275/// DagArgList ::= DagArgList ',' DagArg3276void TGParser::ParseDagArgList(3277 SmallVectorImpl<std::pair<const Init *, const StringInit *>> &Result,3278 Record *CurRec) {3279 3280 while (true) {3281 // DagArg ::= VARNAME3282 if (Lex.getCode() == tgtok::VarName) {3283 // A missing value is treated like '?'.3284 const StringInit *VarName = StringInit::get(Records, Lex.getCurStrVal());3285 Result.emplace_back(UnsetInit::get(Records), VarName);3286 Lex.Lex();3287 } else {3288 // DagArg ::= Value (':' VARNAME)?3289 const Init *Val = ParseValue(CurRec);3290 if (!Val) {3291 Result.clear();3292 return;3293 }3294 3295 // If the variable name is present, add it.3296 const StringInit *VarName = nullptr;3297 if (Lex.getCode() == tgtok::colon) {3298 if (Lex.Lex() != tgtok::VarName) { // eat the ':'3299 TokError("expected variable name in dag literal");3300 Result.clear();3301 return;3302 }3303 VarName = StringInit::get(Records, Lex.getCurStrVal());3304 Lex.Lex(); // eat the VarName.3305 }3306 3307 Result.emplace_back(Val, VarName);3308 }3309 if (!consume(tgtok::comma))3310 break;3311 }3312}3313 3314/// ParseValueList - Parse a comma separated list of values, returning them3315/// in a vector. Note that this always expects to be able to parse at least one3316/// value. It returns an empty list if this is not possible.3317///3318/// ValueList ::= Value (',' Value)3319///3320void TGParser::ParseValueList(SmallVectorImpl<const Init *> &Result,3321 Record *CurRec, const RecTy *ItemType) {3322 Result.push_back(ParseValue(CurRec, ItemType));3323 if (!Result.back()) {3324 Result.clear();3325 return;3326 }3327 3328 while (consume(tgtok::comma)) {3329 // ignore trailing comma for lists3330 if (Lex.getCode() == tgtok::r_square)3331 return;3332 Result.push_back(ParseValue(CurRec, ItemType));3333 if (!Result.back()) {3334 Result.clear();3335 return;3336 }3337 }3338}3339 3340// ParseTemplateArgValueList - Parse a template argument list with the syntax3341// shown, filling in the Result vector. The open angle has been consumed.3342// An empty argument list is allowed. Return false if okay, true if an3343// error was detected.3344//3345// ArgValueList ::= '<' PostionalArgValueList [','] NamedArgValueList '>'3346// PostionalArgValueList ::= [Value {',' Value}*]3347// NamedArgValueList ::= [NameValue '=' Value {',' NameValue '=' Value}*]3348bool TGParser::ParseTemplateArgValueList(3349 SmallVectorImpl<const ArgumentInit *> &Result,3350 SmallVectorImpl<SMLoc> &ArgLocs, Record *CurRec, const Record *ArgsRec) {3351 assert(Result.empty() && "Result vector is not empty");3352 ArrayRef<const Init *> TArgs = ArgsRec->getTemplateArgs();3353 3354 if (consume(tgtok::greater)) // empty value list3355 return false;3356 3357 bool HasNamedArg = false;3358 unsigned ArgIndex = 0;3359 while (true) {3360 if (ArgIndex >= TArgs.size()) {3361 TokError("Too many template arguments: " + utostr(ArgIndex + 1));3362 return true;3363 }3364 3365 SMLoc ValueLoc = ArgLocs.emplace_back(Lex.getLoc());3366 // If we are parsing named argument, we don't need to know the argument name3367 // and argument type will be resolved after we know the name.3368 const Init *Value = ParseValue(3369 CurRec,3370 HasNamedArg ? nullptr : ArgsRec->getValue(TArgs[ArgIndex])->getType());3371 if (!Value)3372 return true;3373 3374 // If we meet '=', then we are parsing named arguments.3375 if (Lex.getCode() == tgtok::equal) {3376 if (!isa<StringInit>(Value))3377 return Error(ValueLoc,3378 "The name of named argument should be a valid identifier");3379 3380 auto *Name = cast<StringInit>(Value);3381 const Init *QualifiedName = QualifyName(*ArgsRec, Name);3382 auto *NamedArg = ArgsRec->getValue(QualifiedName);3383 if (!NamedArg)3384 return Error(ValueLoc,3385 "Argument " + Name->getAsString() + " doesn't exist");3386 3387 Lex.Lex(); // eat the '='.3388 ValueLoc = Lex.getLoc();3389 Value = ParseValue(CurRec, NamedArg->getType());3390 // Named value can't be uninitialized.3391 if (isa<UnsetInit>(Value))3392 return Error(ValueLoc,3393 "The value of named argument should be initialized, "3394 "but we got '" +3395 Value->getAsString() + "'");3396 3397 Result.push_back(ArgumentInit::get(Value, QualifiedName));3398 HasNamedArg = true;3399 } else {3400 // Positional arguments should be put before named arguments.3401 if (HasNamedArg)3402 return Error(ValueLoc,3403 "Positional argument should be put before named argument");3404 3405 Result.push_back(ArgumentInit::get(Value, ArgIndex));3406 }3407 3408 if (consume(tgtok::greater)) // end of argument list?3409 return false;3410 if (!consume(tgtok::comma))3411 return TokError("Expected comma before next argument");3412 ++ArgIndex;3413 }3414}3415 3416/// ParseDeclaration - Read a declaration, returning the name of field ID, or an3417/// empty string on error. This can happen in a number of different contexts,3418/// including within a def or in the template args for a class (in which case3419/// CurRec will be non-null) and within the template args for a multiclass (in3420/// which case CurRec will be null, but CurMultiClass will be set). This can3421/// also happen within a def that is within a multiclass, which will set both3422/// CurRec and CurMultiClass.3423///3424/// Declaration ::= FIELD? Type ID ('=' Value)?3425///3426const Init *TGParser::ParseDeclaration(Record *CurRec,3427 bool ParsingTemplateArgs) {3428 // Read the field prefix if present.3429 bool HasField = consume(tgtok::Field);3430 3431 const RecTy *Type = ParseType();3432 if (!Type)3433 return nullptr;3434 3435 if (Lex.getCode() != tgtok::Id) {3436 TokError("Expected identifier in declaration");3437 return nullptr;3438 }3439 3440 std::string Str = Lex.getCurStrVal();3441 if (Str == "NAME") {3442 TokError("'" + Str + "' is a reserved variable name");3443 return nullptr;3444 }3445 3446 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {3447 TokError("local variable of this name already exists");3448 return nullptr;3449 }3450 3451 SMLoc IdLoc = Lex.getLoc();3452 const Init *DeclName = StringInit::get(Records, Str);3453 Lex.Lex();3454 3455 bool BadField;3456 if (!ParsingTemplateArgs) { // def, possibly in a multiclass3457 BadField = AddValue(CurRec, IdLoc,3458 RecordVal(DeclName, IdLoc, Type,3459 HasField ? RecordVal::FK_NonconcreteOK3460 : RecordVal::FK_Normal));3461 } else if (CurRec) { // class template argument3462 DeclName = QualifyName(*CurRec, DeclName);3463 BadField =3464 AddValue(CurRec, IdLoc,3465 RecordVal(DeclName, IdLoc, Type, RecordVal::FK_TemplateArg));3466 } else { // multiclass template argument3467 assert(CurMultiClass && "invalid context for template argument");3468 DeclName = QualifyName(CurMultiClass, DeclName);3469 BadField =3470 AddValue(CurRec, IdLoc,3471 RecordVal(DeclName, IdLoc, Type, RecordVal::FK_TemplateArg));3472 }3473 if (BadField)3474 return nullptr;3475 3476 // If a value is present, parse it and set new field's value.3477 if (consume(tgtok::equal)) {3478 SMLoc ValLoc = Lex.getLoc();3479 const Init *Val = ParseValue(CurRec, Type);3480 if (!Val ||3481 SetValue(CurRec, ValLoc, DeclName, {}, Val,3482 /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/false)) {3483 // Return the name, even if an error is thrown. This is so that we can3484 // continue to make some progress, even without the value having been3485 // initialized.3486 return DeclName;3487 }3488 }3489 3490 return DeclName;3491}3492 3493/// ParseForeachDeclaration - Read a foreach declaration, returning3494/// the name of the declared object or a NULL Init on error. Return3495/// the name of the parsed initializer list through ForeachListName.3496///3497/// ForeachDeclaration ::= ID '=' '{' RangeList '}'3498/// ForeachDeclaration ::= ID '=' RangePiece3499/// ForeachDeclaration ::= ID '=' Value3500///3501const VarInit *3502TGParser::ParseForeachDeclaration(const Init *&ForeachListValue) {3503 if (Lex.getCode() != tgtok::Id) {3504 TokError("Expected identifier in foreach declaration");3505 return nullptr;3506 }3507 3508 const Init *DeclName = StringInit::get(Records, Lex.getCurStrVal());3509 Lex.Lex();3510 3511 // If a value is present, parse it.3512 if (!consume(tgtok::equal)) {3513 TokError("Expected '=' in foreach declaration");3514 return nullptr;3515 }3516 3517 const RecTy *IterType = nullptr;3518 SmallVector<unsigned, 16> Ranges;3519 3520 switch (Lex.getCode()) {3521 case tgtok::l_brace: { // '{' RangeList '}'3522 Lex.Lex(); // eat the '{'3523 ParseRangeList(Ranges);3524 if (!consume(tgtok::r_brace)) {3525 TokError("expected '}' at end of bit range list");3526 return nullptr;3527 }3528 break;3529 }3530 3531 default: {3532 SMLoc ValueLoc = Lex.getLoc();3533 const Init *I = ParseValue(nullptr);3534 if (!I)3535 return nullptr;3536 3537 const auto *TI = dyn_cast<TypedInit>(I);3538 if (TI && isa<ListRecTy>(TI->getType())) {3539 ForeachListValue = I;3540 IterType = cast<ListRecTy>(TI->getType())->getElementType();3541 break;3542 }3543 3544 if (TI) {3545 if (ParseRangePiece(Ranges, TI))3546 return nullptr;3547 break;3548 }3549 3550 Error(ValueLoc, "expected a list, got '" + I->getAsString() + "'");3551 if (CurMultiClass) {3552 PrintNote({}, "references to multiclass template arguments cannot be "3553 "resolved at this time");3554 }3555 return nullptr;3556 }3557 }3558 3559 if (!Ranges.empty()) {3560 assert(!IterType && "Type already initialized?");3561 IterType = IntRecTy::get(Records);3562 std::vector<Init *> Values;3563 for (unsigned R : Ranges)3564 Values.push_back(IntInit::get(Records, R));3565 ForeachListValue = ListInit::get(Values, IterType);3566 }3567 3568 if (!IterType)3569 return nullptr;3570 3571 return VarInit::get(DeclName, IterType);3572}3573 3574/// ParseTemplateArgList - Read a template argument list, which is a non-empty3575/// sequence of template-declarations in <>'s. If CurRec is non-null, these are3576/// template args for a class. If null, these are the template args for a3577/// multiclass.3578///3579/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>'3580///3581bool TGParser::ParseTemplateArgList(Record *CurRec) {3582 assert(Lex.getCode() == tgtok::less && "Not a template arg list!");3583 Lex.Lex(); // eat the '<'3584 3585 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;3586 3587 // Read the first declaration.3588 const Init *TemplArg = ParseDeclaration(CurRec, true /*templateargs*/);3589 if (!TemplArg)3590 return true;3591 3592 TheRecToAddTo->addTemplateArg(TemplArg);3593 3594 while (consume(tgtok::comma)) {3595 // Read the following declarations.3596 SMLoc Loc = Lex.getLoc();3597 TemplArg = ParseDeclaration(CurRec, true /*templateargs*/);3598 if (!TemplArg)3599 return true;3600 3601 if (TheRecToAddTo->isTemplateArg(TemplArg))3602 return Error(Loc, "template argument with the same name has already been "3603 "defined");3604 3605 TheRecToAddTo->addTemplateArg(TemplArg);3606 }3607 3608 if (!consume(tgtok::greater))3609 return TokError("expected '>' at end of template argument list");3610 return false;3611}3612 3613/// ParseBodyItem - Parse a single item within the body of a def or class.3614///3615/// BodyItem ::= Declaration ';'3616/// BodyItem ::= LET ID OptionalBitList '=' Value ';'3617/// BodyItem ::= Defvar3618/// BodyItem ::= Dump3619/// BodyItem ::= Assert3620///3621bool TGParser::ParseBodyItem(Record *CurRec) {3622 if (Lex.getCode() == tgtok::Assert)3623 return ParseAssert(nullptr, CurRec);3624 3625 if (Lex.getCode() == tgtok::Defvar)3626 return ParseDefvar(CurRec);3627 3628 if (Lex.getCode() == tgtok::Dump)3629 return ParseDump(nullptr, CurRec);3630 3631 if (Lex.getCode() != tgtok::Let) {3632 if (!ParseDeclaration(CurRec, false))3633 return true;3634 3635 if (!consume(tgtok::semi))3636 return TokError("expected ';' after declaration");3637 return false;3638 }3639 3640 // LET ID OptionalRangeList '=' Value ';'3641 if (Lex.Lex() != tgtok::Id)3642 return TokError("expected field identifier after let");3643 3644 SMLoc IdLoc = Lex.getLoc();3645 const StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());3646 Lex.Lex(); // eat the field name.3647 3648 SmallVector<unsigned, 16> BitList;3649 if (ParseOptionalBitList(BitList))3650 return true;3651 std::reverse(BitList.begin(), BitList.end());3652 3653 if (!consume(tgtok::equal))3654 return TokError("expected '=' in let expression");3655 3656 RecordVal *Field = CurRec->getValue(FieldName);3657 if (!Field)3658 return Error(IdLoc, "Value '" + FieldName->getValue() + "' unknown!");3659 3660 const RecTy *Type = Field->getType();3661 if (!BitList.empty() && isa<BitsRecTy>(Type)) {3662 // When assigning to a subset of a 'bits' object, expect the RHS to have3663 // the type of that subset instead of the type of the whole object.3664 Type = BitsRecTy::get(Records, BitList.size());3665 }3666 3667 const Init *Val = ParseValue(CurRec, Type);3668 if (!Val)3669 return true;3670 3671 if (!consume(tgtok::semi))3672 return TokError("expected ';' after let expression");3673 3674 return SetValue(CurRec, IdLoc, FieldName, BitList, Val);3675}3676 3677/// ParseBody - Read the body of a class or def. Return true on error, false on3678/// success.3679///3680/// Body ::= ';'3681/// Body ::= '{' BodyList '}'3682/// BodyList BodyItem*3683///3684bool TGParser::ParseBody(Record *CurRec) {3685 // If this is a null definition, just eat the semi and return.3686 if (consume(tgtok::semi))3687 return false;3688 3689 if (!consume(tgtok::l_brace))3690 return TokError("Expected '{' to start body or ';' for declaration only");3691 3692 while (Lex.getCode() != tgtok::r_brace)3693 if (ParseBodyItem(CurRec))3694 return true;3695 3696 // Eat the '}'.3697 Lex.Lex();3698 3699 // If we have a semicolon, print a gentle error.3700 SMLoc SemiLoc = Lex.getLoc();3701 if (consume(tgtok::semi)) {3702 PrintError(SemiLoc, "A class or def body should not end with a semicolon");3703 PrintNote("Semicolon ignored; remove to eliminate this error");3704 }3705 3706 return false;3707}3708 3709/// Apply the current let bindings to \a CurRec.3710/// \returns true on error, false otherwise.3711bool TGParser::ApplyLetStack(Record *CurRec) {3712 for (SmallVectorImpl<LetRecord> &LetInfo : LetStack)3713 for (LetRecord &LR : LetInfo)3714 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))3715 return true;3716 return false;3717}3718 3719/// Apply the current let bindings to the RecordsEntry.3720bool TGParser::ApplyLetStack(RecordsEntry &Entry) {3721 if (Entry.Rec)3722 return ApplyLetStack(Entry.Rec.get());3723 3724 // Let bindings are not applied to assertions.3725 if (Entry.Assertion)3726 return false;3727 3728 // Let bindings are not applied to dumps.3729 if (Entry.Dump)3730 return false;3731 3732 for (auto &E : Entry.Loop->Entries) {3733 if (ApplyLetStack(E))3734 return true;3735 }3736 3737 return false;3738}3739 3740/// ParseObjectBody - Parse the body of a def or class. This consists of an3741/// optional ClassList followed by a Body. CurRec is the current def or class3742/// that is being parsed.3743///3744/// ObjectBody ::= BaseClassList Body3745/// BaseClassList ::= /*empty*/3746/// BaseClassList ::= ':' BaseClassListNE3747/// BaseClassListNE ::= SubClassRef (',' SubClassRef)*3748///3749bool TGParser::ParseObjectBody(Record *CurRec) {3750 // An object body introduces a new scope for local variables.3751 TGVarScope *ObjectScope = PushScope(CurRec);3752 // If there is a baseclass list, read it.3753 if (consume(tgtok::colon)) {3754 3755 // Read all of the subclasses.3756 SubClassReference SubClass = ParseSubClassReference(CurRec, false);3757 while (true) {3758 // Check for error.3759 if (!SubClass.Rec)3760 return true;3761 3762 // Add it.3763 if (AddSubClass(CurRec, SubClass))3764 return true;3765 3766 if (!consume(tgtok::comma))3767 break;3768 SubClass = ParseSubClassReference(CurRec, false);3769 }3770 }3771 3772 if (ApplyLetStack(CurRec))3773 return true;3774 3775 bool Result = ParseBody(CurRec);3776 PopScope(ObjectScope);3777 return Result;3778}3779 3780/// ParseDef - Parse and return a top level or multiclass record definition.3781/// Return false if okay, true if error.3782///3783/// DefInst ::= DEF ObjectName ObjectBody3784///3785bool TGParser::ParseDef(MultiClass *CurMultiClass) {3786 SMLoc DefLoc = Lex.getLoc();3787 assert(Lex.getCode() == tgtok::Def && "Unknown tok");3788 Lex.Lex(); // Eat the 'def' token.3789 3790 // If the name of the def is an Id token, use that for the location.3791 // Otherwise, the name is more complex and we use the location of the 'def'3792 // token.3793 SMLoc NameLoc = Lex.getCode() == tgtok::Id ? Lex.getLoc() : DefLoc;3794 3795 // Parse ObjectName and make a record for it.3796 std::unique_ptr<Record> CurRec;3797 const Init *Name = ParseObjectName(CurMultiClass);3798 if (!Name)3799 return true;3800 3801 if (isa<UnsetInit>(Name)) {3802 CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc,3803 Records, Record::RK_AnonymousDef);3804 } else {3805 CurRec = std::make_unique<Record>(Name, NameLoc, Records);3806 }3807 3808 if (ParseObjectBody(CurRec.get()))3809 return true;3810 3811 return addEntry(std::move(CurRec));3812}3813 3814/// ParseDefset - Parse a defset statement.3815///3816/// Defset ::= DEFSET Type Id '=' '{' ObjectList '}'3817///3818bool TGParser::ParseDefset() {3819 assert(Lex.getCode() == tgtok::Defset);3820 Lex.Lex(); // Eat the 'defset' token3821 3822 DefsetRecord Defset;3823 Defset.Loc = Lex.getLoc();3824 const RecTy *Type = ParseType();3825 if (!Type)3826 return true;3827 if (!isa<ListRecTy>(Type))3828 return Error(Defset.Loc, "expected list type");3829 Defset.EltTy = cast<ListRecTy>(Type)->getElementType();3830 3831 if (Lex.getCode() != tgtok::Id)3832 return TokError("expected identifier");3833 const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());3834 if (Records.getGlobal(DeclName->getValue()))3835 return TokError("def or global variable of this name already exists");3836 3837 if (Lex.Lex() != tgtok::equal) // Eat the identifier3838 return TokError("expected '='");3839 if (Lex.Lex() != tgtok::l_brace) // Eat the '='3840 return TokError("expected '{'");3841 SMLoc BraceLoc = Lex.getLoc();3842 Lex.Lex(); // Eat the '{'3843 3844 Defsets.push_back(&Defset);3845 bool Err = ParseObjectList(nullptr);3846 Defsets.pop_back();3847 if (Err)3848 return true;3849 3850 if (!consume(tgtok::r_brace)) {3851 TokError("expected '}' at end of defset");3852 return Error(BraceLoc, "to match this '{'");3853 }3854 3855 Records.addExtraGlobal(DeclName->getValue(),3856 ListInit::get(Defset.Elements, Defset.EltTy));3857 return false;3858}3859 3860/// ParseDeftype - Parse a defvar statement.3861///3862/// Deftype ::= DEFTYPE Id '=' Type ';'3863///3864bool TGParser::ParseDeftype() {3865 assert(Lex.getCode() == tgtok::Deftype);3866 Lex.Lex(); // Eat the 'deftype' token3867 3868 if (Lex.getCode() != tgtok::Id)3869 return TokError("expected identifier");3870 3871 const std::string TypeName = Lex.getCurStrVal();3872 if (TypeAliases.count(TypeName) || Records.getClass(TypeName))3873 return TokError("type of this name '" + TypeName + "' already exists");3874 3875 Lex.Lex();3876 if (!consume(tgtok::equal))3877 return TokError("expected '='");3878 3879 SMLoc Loc = Lex.getLoc();3880 const RecTy *Type = ParseType();3881 if (!Type)3882 return true;3883 3884 if (Type->getRecTyKind() == RecTy::RecordRecTyKind)3885 return Error(Loc, "cannot define type alias for class type '" +3886 Type->getAsString() + "'");3887 3888 TypeAliases[TypeName] = Type;3889 3890 if (!consume(tgtok::semi))3891 return TokError("expected ';'");3892 3893 return false;3894}3895 3896/// ParseDefvar - Parse a defvar statement.3897///3898/// Defvar ::= DEFVAR Id '=' Value ';'3899///3900bool TGParser::ParseDefvar(Record *CurRec) {3901 assert(Lex.getCode() == tgtok::Defvar);3902 Lex.Lex(); // Eat the 'defvar' token3903 3904 if (Lex.getCode() != tgtok::Id)3905 return TokError("expected identifier");3906 const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());3907 if (CurScope->varAlreadyDefined(DeclName->getValue()))3908 return TokError("local variable of this name already exists");3909 3910 // The name should not be conflicted with existed field names.3911 if (CurRec) {3912 auto *V = CurRec->getValue(DeclName->getValue());3913 if (V && !V->isTemplateArg())3914 return TokError("field of this name already exists");3915 }3916 3917 // If this defvar is in the top level, the name should not be conflicted3918 // with existed global names.3919 if (CurScope->isOutermost() && Records.getGlobal(DeclName->getValue()))3920 return TokError("def or global variable of this name already exists");3921 3922 Lex.Lex();3923 if (!consume(tgtok::equal))3924 return TokError("expected '='");3925 3926 const Init *Value = ParseValue(CurRec);3927 if (!Value)3928 return true;3929 3930 if (!consume(tgtok::semi))3931 return TokError("expected ';'");3932 3933 if (!CurScope->isOutermost())3934 CurScope->addVar(DeclName->getValue(), Value);3935 else3936 Records.addExtraGlobal(DeclName->getValue(), Value);3937 3938 return false;3939}3940 3941/// ParseForeach - Parse a for statement. Return the record corresponding3942/// to it. This returns true on error.3943///3944/// Foreach ::= FOREACH Declaration IN '{ ObjectList '}'3945/// Foreach ::= FOREACH Declaration IN Object3946///3947bool TGParser::ParseForeach(MultiClass *CurMultiClass) {3948 SMLoc Loc = Lex.getLoc();3949 assert(Lex.getCode() == tgtok::Foreach && "Unknown tok");3950 Lex.Lex(); // Eat the 'for' token.3951 3952 // Make a temporary object to record items associated with the for3953 // loop.3954 const Init *ListValue = nullptr;3955 const VarInit *IterName = ParseForeachDeclaration(ListValue);3956 if (!IterName)3957 return TokError("expected declaration in for");3958 3959 if (!consume(tgtok::In))3960 return TokError("Unknown tok");3961 3962 // Create a loop object and remember it.3963 auto TheLoop = std::make_unique<ForeachLoop>(Loc, IterName, ListValue);3964 // A foreach loop introduces a new scope for local variables.3965 TGVarScope *ForeachScope = PushScope(TheLoop.get());3966 Loops.push_back(std::move(TheLoop));3967 3968 if (Lex.getCode() != tgtok::l_brace) {3969 // FOREACH Declaration IN Object3970 if (ParseObject(CurMultiClass))3971 return true;3972 } else {3973 SMLoc BraceLoc = Lex.getLoc();3974 // Otherwise, this is a group foreach.3975 Lex.Lex(); // eat the '{'.3976 3977 // Parse the object list.3978 if (ParseObjectList(CurMultiClass))3979 return true;3980 3981 if (!consume(tgtok::r_brace)) {3982 TokError("expected '}' at end of foreach command");3983 return Error(BraceLoc, "to match this '{'");3984 }3985 }3986 3987 PopScope(ForeachScope);3988 3989 // Resolve the loop or store it for later resolution.3990 std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());3991 Loops.pop_back();3992 3993 return addEntry(std::move(Loop));3994}3995 3996/// ParseIf - Parse an if statement.3997///3998/// If ::= IF Value THEN IfBody3999/// If ::= IF Value THEN IfBody ELSE IfBody4000///4001bool TGParser::ParseIf(MultiClass *CurMultiClass) {4002 SMLoc Loc = Lex.getLoc();4003 assert(Lex.getCode() == tgtok::If && "Unknown tok");4004 Lex.Lex(); // Eat the 'if' token.4005 4006 // Make a temporary object to record items associated with the for4007 // loop.4008 const Init *Condition = ParseValue(nullptr);4009 if (!Condition)4010 return true;4011 4012 if (!consume(tgtok::Then))4013 return TokError("Unknown tok");4014 4015 // We have to be able to save if statements to execute later, and they have4016 // to live on the same stack as foreach loops. The simplest implementation4017 // technique is to convert each 'then' or 'else' clause *into* a foreach4018 // loop, over a list of length 0 or 1 depending on the condition, and with no4019 // iteration variable being assigned.4020 4021 const ListInit *EmptyList = ListInit::get({}, BitRecTy::get(Records));4022 const ListInit *SingletonList =4023 ListInit::get({BitInit::get(Records, true)}, BitRecTy::get(Records));4024 const RecTy *BitListTy = ListRecTy::get(BitRecTy::get(Records));4025 4026 // The foreach containing the then-clause selects SingletonList if4027 // the condition is true.4028 const Init *ThenClauseList =4029 TernOpInit::get(TernOpInit::IF, Condition, SingletonList, EmptyList,4030 BitListTy)4031 ->Fold(nullptr);4032 Loops.push_back(std::make_unique<ForeachLoop>(Loc, nullptr, ThenClauseList));4033 4034 if (ParseIfBody(CurMultiClass, "then"))4035 return true;4036 4037 std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());4038 Loops.pop_back();4039 4040 if (addEntry(std::move(Loop)))4041 return true;4042 4043 // Now look for an optional else clause. The if-else syntax has the usual4044 // dangling-else ambiguity, and by greedily matching an else here if we can,4045 // we implement the usual resolution of pairing with the innermost unmatched4046 // if.4047 if (consume(tgtok::ElseKW)) {4048 // The foreach containing the else-clause uses the same pair of lists as4049 // above, but this time, selects SingletonList if the condition is *false*.4050 const Init *ElseClauseList =4051 TernOpInit::get(TernOpInit::IF, Condition, EmptyList, SingletonList,4052 BitListTy)4053 ->Fold(nullptr);4054 Loops.push_back(4055 std::make_unique<ForeachLoop>(Loc, nullptr, ElseClauseList));4056 4057 if (ParseIfBody(CurMultiClass, "else"))4058 return true;4059 4060 Loop = std::move(Loops.back());4061 Loops.pop_back();4062 4063 if (addEntry(std::move(Loop)))4064 return true;4065 }4066 4067 return false;4068}4069 4070/// ParseIfBody - Parse the then-clause or else-clause of an if statement.4071///4072/// IfBody ::= Object4073/// IfBody ::= '{' ObjectList '}'4074///4075bool TGParser::ParseIfBody(MultiClass *CurMultiClass, StringRef Kind) {4076 // An if-statement introduces a new scope for local variables.4077 TGVarScope *BodyScope = PushScope();4078 4079 if (Lex.getCode() != tgtok::l_brace) {4080 // A single object.4081 if (ParseObject(CurMultiClass))4082 return true;4083 } else {4084 SMLoc BraceLoc = Lex.getLoc();4085 // A braced block.4086 Lex.Lex(); // eat the '{'.4087 4088 // Parse the object list.4089 if (ParseObjectList(CurMultiClass))4090 return true;4091 4092 if (!consume(tgtok::r_brace)) {4093 TokError("expected '}' at end of '" + Kind + "' clause");4094 return Error(BraceLoc, "to match this '{'");4095 }4096 }4097 4098 PopScope(BodyScope);4099 return false;4100}4101 4102/// ParseAssert - Parse an assert statement.4103///4104/// Assert ::= ASSERT condition , message ;4105bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {4106 assert(Lex.getCode() == tgtok::Assert && "Unknown tok");4107 Lex.Lex(); // Eat the 'assert' token.4108 4109 SMLoc ConditionLoc = Lex.getLoc();4110 const Init *Condition = ParseValue(CurRec);4111 if (!Condition)4112 return true;4113 4114 if (!consume(tgtok::comma)) {4115 TokError("expected ',' in assert statement");4116 return true;4117 }4118 4119 const Init *Message = ParseValue(CurRec);4120 if (!Message)4121 return true;4122 4123 if (!consume(tgtok::semi))4124 return TokError("expected ';'");4125 4126 if (CurRec)4127 CurRec->addAssertion(ConditionLoc, Condition, Message);4128 else4129 addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,4130 Message));4131 return false;4132}4133 4134/// ParseClass - Parse a tblgen class definition.4135///4136/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody4137///4138bool TGParser::ParseClass() {4139 assert(Lex.getCode() == tgtok::Class && "Unexpected token!");4140 Lex.Lex();4141 4142 if (Lex.getCode() != tgtok::Id)4143 return TokError("expected class name after 'class' keyword");4144 4145 const std::string &Name = Lex.getCurStrVal();4146 Record *CurRec = const_cast<Record *>(Records.getClass(Name));4147 if (CurRec) {4148 // If the body was previously defined, this is an error.4149 if (!CurRec->getValues().empty() ||4150 !CurRec->getDirectSuperClasses().empty() ||4151 !CurRec->getTemplateArgs().empty())4152 return TokError("Class '" + CurRec->getNameInitAsString() +4153 "' already defined");4154 4155 CurRec->updateClassLoc(Lex.getLoc());4156 } else {4157 // If this is the first reference to this class, create and add it.4158 auto NewRec = std::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(),4159 Records, Record::RK_Class);4160 CurRec = NewRec.get();4161 Records.addClass(std::move(NewRec));4162 }4163 4164 if (TypeAliases.count(Name))4165 return TokError("there is already a defined type alias '" + Name + "'");4166 4167 Lex.Lex(); // eat the name.4168 4169 // A class definition introduces a new scope.4170 TGVarScope *ClassScope = PushScope(CurRec);4171 // If there are template args, parse them.4172 if (Lex.getCode() == tgtok::less)4173 if (ParseTemplateArgList(CurRec))4174 return true;4175 4176 if (ParseObjectBody(CurRec))4177 return true;4178 4179 if (!NoWarnOnUnusedTemplateArgs)4180 CurRec->checkUnusedTemplateArgs();4181 4182 PopScope(ClassScope);4183 return false;4184}4185 4186/// ParseLetList - Parse a non-empty list of assignment expressions into a list4187/// of LetRecords.4188///4189/// LetList ::= LetItem (',' LetItem)*4190/// LetItem ::= ID OptionalRangeList '=' Value4191///4192void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) {4193 do {4194 if (Lex.getCode() != tgtok::Id) {4195 TokError("expected identifier in let definition");4196 Result.clear();4197 return;4198 }4199 4200 const StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());4201 SMLoc NameLoc = Lex.getLoc();4202 Lex.Lex(); // Eat the identifier.4203 4204 // Check for an optional RangeList.4205 SmallVector<unsigned, 16> Bits;4206 if (ParseOptionalRangeList(Bits)) {4207 Result.clear();4208 return;4209 }4210 std::reverse(Bits.begin(), Bits.end());4211 4212 if (!consume(tgtok::equal)) {4213 TokError("expected '=' in let expression");4214 Result.clear();4215 return;4216 }4217 4218 const Init *Val = ParseValue(nullptr);4219 if (!Val) {4220 Result.clear();4221 return;4222 }4223 4224 // Now that we have everything, add the record.4225 Result.emplace_back(Name, Bits, Val, NameLoc);4226 } while (consume(tgtok::comma));4227}4228 4229/// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of4230/// different related productions. This works inside multiclasses too.4231///4232/// Object ::= LET LetList IN '{' ObjectList '}'4233/// Object ::= LET LetList IN Object4234///4235bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {4236 assert(Lex.getCode() == tgtok::Let && "Unexpected token");4237 Lex.Lex();4238 4239 // Add this entry to the let stack.4240 SmallVector<LetRecord, 8> LetInfo;4241 ParseLetList(LetInfo);4242 if (LetInfo.empty())4243 return true;4244 LetStack.push_back(std::move(LetInfo));4245 4246 if (!consume(tgtok::In))4247 return TokError("expected 'in' at end of top-level 'let'");4248 4249 // If this is a scalar let, just handle it now4250 if (Lex.getCode() != tgtok::l_brace) {4251 // LET LetList IN Object4252 if (ParseObject(CurMultiClass))4253 return true;4254 } else { // Object ::= LETCommand '{' ObjectList '}'4255 SMLoc BraceLoc = Lex.getLoc();4256 // Otherwise, this is a group let.4257 Lex.Lex(); // eat the '{'.4258 4259 // A group let introduces a new scope for local variables.4260 TGVarScope *LetScope = PushScope();4261 4262 // Parse the object list.4263 if (ParseObjectList(CurMultiClass))4264 return true;4265 4266 if (!consume(tgtok::r_brace)) {4267 TokError("expected '}' at end of top level let command");4268 return Error(BraceLoc, "to match this '{'");4269 }4270 4271 PopScope(LetScope);4272 }4273 4274 // Outside this let scope, this let block is not active.4275 LetStack.pop_back();4276 return false;4277}4278 4279/// ParseMultiClass - Parse a multiclass definition.4280///4281/// MultiClassInst ::= MULTICLASS ID TemplateArgList?4282/// ':' BaseMultiClassList '{' MultiClassObject+ '}'4283/// MultiClassObject ::= Assert4284/// MultiClassObject ::= DefInst4285/// MultiClassObject ::= DefMInst4286/// MultiClassObject ::= Defvar4287/// MultiClassObject ::= Foreach4288/// MultiClassObject ::= If4289/// MultiClassObject ::= LETCommand '{' ObjectList '}'4290/// MultiClassObject ::= LETCommand Object4291///4292bool TGParser::ParseMultiClass() {4293 assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");4294 Lex.Lex(); // Eat the multiclass token.4295 4296 if (Lex.getCode() != tgtok::Id)4297 return TokError("expected identifier after multiclass for name");4298 std::string Name = Lex.getCurStrVal();4299 4300 auto Result = MultiClasses.try_emplace(4301 Name, std::make_unique<MultiClass>(Name, Lex.getLoc(), Records));4302 4303 if (!Result.second)4304 return TokError("multiclass '" + Name + "' already defined");4305 4306 CurMultiClass = Result.first->second.get();4307 Lex.Lex(); // Eat the identifier.4308 4309 // A multiclass body introduces a new scope for local variables.4310 TGVarScope *MulticlassScope = PushScope(CurMultiClass);4311 4312 // If there are template args, parse them.4313 if (Lex.getCode() == tgtok::less)4314 if (ParseTemplateArgList(nullptr))4315 return true;4316 4317 bool inherits = false;4318 4319 // If there are submulticlasses, parse them.4320 if (consume(tgtok::colon)) {4321 inherits = true;4322 4323 // Read all of the submulticlasses.4324 SubMultiClassReference SubMultiClass =4325 ParseSubMultiClassReference(CurMultiClass);4326 while (true) {4327 // Check for error.4328 if (!SubMultiClass.MC)4329 return true;4330 4331 // Add it.4332 if (AddSubMultiClass(CurMultiClass, SubMultiClass))4333 return true;4334 4335 if (!consume(tgtok::comma))4336 break;4337 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);4338 }4339 }4340 4341 if (Lex.getCode() != tgtok::l_brace) {4342 if (!inherits)4343 return TokError("expected '{' in multiclass definition");4344 if (!consume(tgtok::semi))4345 return TokError("expected ';' in multiclass definition");4346 } else {4347 if (Lex.Lex() == tgtok::r_brace) // eat the '{'.4348 return TokError("multiclass must contain at least one def");4349 4350 while (Lex.getCode() != tgtok::r_brace) {4351 switch (Lex.getCode()) {4352 default:4353 return TokError("expected 'assert', 'def', 'defm', 'defvar', 'dump', "4354 "'foreach', 'if', or 'let' in multiclass body");4355 4356 case tgtok::Assert:4357 case tgtok::Def:4358 case tgtok::Defm:4359 case tgtok::Defvar:4360 case tgtok::Dump:4361 case tgtok::Foreach:4362 case tgtok::If:4363 case tgtok::Let:4364 if (ParseObject(CurMultiClass))4365 return true;4366 break;4367 }4368 }4369 Lex.Lex(); // eat the '}'.4370 4371 // If we have a semicolon, print a gentle error.4372 SMLoc SemiLoc = Lex.getLoc();4373 if (consume(tgtok::semi)) {4374 PrintError(SemiLoc, "A multiclass body should not end with a semicolon");4375 PrintNote("Semicolon ignored; remove to eliminate this error");4376 }4377 }4378 4379 if (!NoWarnOnUnusedTemplateArgs)4380 CurMultiClass->Rec.checkUnusedTemplateArgs();4381 4382 PopScope(MulticlassScope);4383 CurMultiClass = nullptr;4384 return false;4385}4386 4387/// ParseDefm - Parse the instantiation of a multiclass.4388///4389/// DefMInst ::= DEFM ID ':' DefmSubClassRef ';'4390///4391bool TGParser::ParseDefm(MultiClass *CurMultiClass) {4392 assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");4393 Lex.Lex(); // eat the defm4394 4395 const Init *DefmName = ParseObjectName(CurMultiClass);4396 if (!DefmName)4397 return true;4398 if (isa<UnsetInit>(DefmName)) {4399 DefmName = Records.getNewAnonymousName();4400 if (CurMultiClass)4401 DefmName = BinOpInit::getStrConcat(4402 VarInit::get(QualifiedNameOfImplicitName(CurMultiClass),4403 StringRecTy::get(Records)),4404 DefmName);4405 }4406 4407 if (Lex.getCode() != tgtok::colon)4408 return TokError("expected ':' after defm identifier");4409 4410 // Keep track of the new generated record definitions.4411 std::vector<RecordsEntry> NewEntries;4412 4413 // This record also inherits from a regular class (non-multiclass)?4414 bool InheritFromClass = false;4415 4416 // eat the colon.4417 Lex.Lex();4418 4419 SMLoc SubClassLoc = Lex.getLoc();4420 SubClassReference Ref = ParseSubClassReference(nullptr, true);4421 4422 while (true) {4423 if (!Ref.Rec)4424 return true;4425 4426 // To instantiate a multiclass, we get the multiclass and then loop4427 // through its template argument names. Substs contains a substitution4428 // value for each argument, either the value specified or the default.4429 // Then we can resolve the template arguments.4430 MultiClass *MC = MultiClasses[Ref.Rec->getName().str()].get();4431 assert(MC && "Didn't lookup multiclass correctly?");4432 4433 SubstStack Substs;4434 if (resolveArgumentsOfMultiClass(Substs, MC, Ref.TemplateArgs, DefmName,4435 SubClassLoc))4436 return true;4437 4438 if (resolve(MC->Entries, Substs, !CurMultiClass && Loops.empty(),4439 &NewEntries, &SubClassLoc))4440 return true;4441 4442 if (!consume(tgtok::comma))4443 break;4444 4445 if (Lex.getCode() != tgtok::Id)4446 return TokError("expected identifier");4447 4448 SubClassLoc = Lex.getLoc();4449 4450 // A defm can inherit from regular classes (non-multiclasses) as4451 // long as they come in the end of the inheritance list.4452 InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr);4453 4454 if (InheritFromClass)4455 break;4456 4457 Ref = ParseSubClassReference(nullptr, true);4458 }4459 4460 if (InheritFromClass) {4461 // Process all the classes to inherit as if they were part of a4462 // regular 'def' and inherit all record values.4463 SubClassReference SubClass = ParseSubClassReference(nullptr, false);4464 while (true) {4465 // Check for error.4466 if (!SubClass.Rec)4467 return true;4468 4469 // Get the expanded definition prototypes and teach them about4470 // the record values the current class to inherit has4471 for (auto &E : NewEntries) {4472 // Add it.4473 if (AddSubClass(E, SubClass))4474 return true;4475 }4476 4477 if (!consume(tgtok::comma))4478 break;4479 SubClass = ParseSubClassReference(nullptr, false);4480 }4481 }4482 4483 for (auto &E : NewEntries) {4484 if (ApplyLetStack(E))4485 return true;4486 4487 addEntry(std::move(E));4488 }4489 4490 if (!consume(tgtok::semi))4491 return TokError("expected ';' at end of defm");4492 4493 return false;4494}4495 4496/// ParseObject4497/// Object ::= ClassInst4498/// Object ::= DefInst4499/// Object ::= MultiClassInst4500/// Object ::= DefMInst4501/// Object ::= LETCommand '{' ObjectList '}'4502/// Object ::= LETCommand Object4503/// Object ::= Defset4504/// Object ::= Deftype4505/// Object ::= Defvar4506/// Object ::= Assert4507/// Object ::= Dump4508bool TGParser::ParseObject(MultiClass *MC) {4509 switch (Lex.getCode()) {4510 default:4511 return TokError(4512 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");4513 case tgtok::Assert:4514 return ParseAssert(MC);4515 case tgtok::Def:4516 return ParseDef(MC);4517 case tgtok::Defm:4518 return ParseDefm(MC);4519 case tgtok::Deftype:4520 return ParseDeftype();4521 case tgtok::Defvar:4522 return ParseDefvar();4523 case tgtok::Dump:4524 return ParseDump(MC);4525 case tgtok::Foreach:4526 return ParseForeach(MC);4527 case tgtok::If:4528 return ParseIf(MC);4529 case tgtok::Let:4530 return ParseTopLevelLet(MC);4531 case tgtok::Defset:4532 if (MC)4533 return TokError("defset is not allowed inside multiclass");4534 return ParseDefset();4535 case tgtok::Class:4536 if (MC)4537 return TokError("class is not allowed inside multiclass");4538 if (!Loops.empty())4539 return TokError("class is not allowed inside foreach loop");4540 return ParseClass();4541 case tgtok::MultiClass:4542 if (!Loops.empty())4543 return TokError("multiclass is not allowed inside foreach loop");4544 return ParseMultiClass();4545 }4546}4547 4548/// ParseObjectList4549/// ObjectList :== Object*4550bool TGParser::ParseObjectList(MultiClass *MC) {4551 while (tgtok::isObjectStart(Lex.getCode())) {4552 if (ParseObject(MC))4553 return true;4554 }4555 return false;4556}4557 4558bool TGParser::ParseFile() {4559 Lex.Lex(); // Prime the lexer.4560 TGVarScope *GlobalScope = PushScope();4561 if (ParseObjectList())4562 return true;4563 PopScope(GlobalScope);4564 4565 // If we have unread input at the end of the file, report it.4566 if (Lex.getCode() == tgtok::Eof)4567 return false;4568 4569 return TokError("Unexpected token at top level");4570}4571 4572// Check the types of the template argument values for a class4573// inheritance, multiclass invocation, or anonymous class invocation.4574// If necessary, replace an argument with a cast to the required type.4575// The argument count has already been checked.4576bool TGParser::CheckTemplateArgValues(4577 SmallVectorImpl<const ArgumentInit *> &Values, ArrayRef<SMLoc> ValuesLocs,4578 const Record *ArgsRec) {4579 assert(Values.size() == ValuesLocs.size() &&4580 "expected as many values as locations");4581 4582 ArrayRef<const Init *> TArgs = ArgsRec->getTemplateArgs();4583 4584 bool HasError = false;4585 for (auto [Value, Loc] : llvm::zip_equal(Values, ValuesLocs)) {4586 const Init *ArgName = nullptr;4587 if (Value->isPositional())4588 ArgName = TArgs[Value->getIndex()];4589 if (Value->isNamed())4590 ArgName = Value->getName();4591 4592 const RecordVal *Arg = ArgsRec->getValue(ArgName);4593 const RecTy *ArgType = Arg->getType();4594 4595 if (const auto *ArgValue = dyn_cast<TypedInit>(Value->getValue())) {4596 auto *CastValue = ArgValue->getCastTo(ArgType);4597 if (CastValue) {4598 assert((!isa<TypedInit>(CastValue) ||4599 cast<TypedInit>(CastValue)->getType()->typeIsA(ArgType)) &&4600 "result of template arg value cast has wrong type");4601 Value = Value->cloneWithValue(CastValue);4602 } else {4603 HasError |= Error(4604 Loc, "Value specified for template argument '" +4605 Arg->getNameInitAsString() + "' is of type " +4606 ArgValue->getType()->getAsString() + "; expected type " +4607 ArgType->getAsString() + ": " + ArgValue->getAsString());4608 }4609 }4610 }4611 4612 return HasError;4613}4614 4615#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)4616LLVM_DUMP_METHOD void RecordsEntry::dump() const {4617 if (Loop)4618 Loop->dump();4619 if (Rec)4620 Rec->dump();4621}4622 4623LLVM_DUMP_METHOD void ForeachLoop::dump() const {4624 errs() << "foreach " << IterVar->getAsString() << " = "4625 << ListValue->getAsString() << " in {\n";4626 4627 for (const auto &E : Entries)4628 E.dump();4629 4630 errs() << "}\n";4631}4632 4633LLVM_DUMP_METHOD void MultiClass::dump() const {4634 errs() << "Record:\n";4635 Rec.dump();4636 4637 errs() << "Defs:\n";4638 for (const auto &E : Entries)4639 E.dump();4640}4641#endif4642 4643bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {4644 // Location of the `dump` statement.4645 SMLoc Loc = Lex.getLoc();4646 assert(Lex.getCode() == tgtok::Dump && "Unknown tok");4647 Lex.Lex(); // eat the operation4648 4649 const Init *Message = ParseValue(CurRec);4650 if (!Message)4651 return true;4652 4653 // Allow to use dump directly on `defvar` and `def`, by wrapping4654 // them with a `!repl`.4655 if (isa<DefInit>(Message))4656 Message = UnOpInit::get(UnOpInit::REPR, Message, StringRecTy::get(Records))4657 ->Fold(CurRec);4658 4659 if (!consume(tgtok::semi))4660 return TokError("expected ';'");4661 4662 if (CurRec)4663 CurRec->addDump(Loc, Message);4664 else {4665 HasReferenceResolver resolver{nullptr};4666 resolver.setFinal(true);4667 // force a resolution with a dummy resolver4668 const Init *ResolvedMessage = Message->resolveReferences(resolver);4669 addEntry(std::make_unique<Record::DumpInfo>(Loc, ResolvedMessage));4670 }4671 4672 return false;4673}4674