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