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
2760 if (!Type) {
2761 Type = VTy;
2762 continue;
2763 }
2764 const RecTy *RType = resolveTypes(Type, VTy);
2765 if (!RType) {
2766 TokError(Twine("inconsistent types '") + Type->getAsString() + "' and '" +
2767 VTy->getAsString() + "' " + ErrCtx);
2768 return std::nullopt;
2769 }
2770 Type = RType;
2771 }
2772 return Type;
2773}
2774
2775/// Parse the !cond operation. Return null on error.
2776///
2777/// Cond ::= !cond([cond: val,]+) => val type
2778const Init *TGParser::ParseOperationCond(Record *CurRec,
2779 const RecTy *ItemType) {
2780 Lex.Lex(); // eat the operation 'cond'
2781
2782 if (!consume(tgtok::l_paren)) {
2783 TokError("expected '(' after !cond operator");
2784 return nullptr;
2785 }
2786
2787 // Parse through '[Case: Val,]+'
2790 while (true) {
2792 break;
2793
2794 const Init *V = ParseValue(CurRec);
2795 if (!V)
2796 return nullptr;
2797 Cases.push_back(V);
2798
2799 if (!consume(tgtok::colon)) {
2800 TokError("expected ':' following a condition in !cond operator");
2801 return nullptr;
2802 }
2803
2804 V = ParseValue(CurRec, ItemType);
2805 if (!V)
2806 return nullptr;
2807 Vals.push_back(V);
2808
2810 break;
2811
2812 if (!consume(tgtok::comma)) {
2813 TokError("expected ',' or ')' following a value in !cond operator");
2814 return nullptr;
2815 }
2816 }
2817
2818 if (Cases.size() < 1) {
2819 TokError(
2820 "there should be at least 1 'condition : value' in the !cond operator");
2821 return nullptr;
2822 }
2823
2824 // resolve type
2825 std::optional<const RecTy *> TypeOpt = resolveInitTypes(Vals, "for !cond");
2826 if (!TypeOpt)
2827 return nullptr;
2828 const RecTy *Type = *TypeOpt;
2829 if (!Type) {
2830 TokError("could not determine type for !cond from its arguments");
2831 return nullptr;
2832 }
2833 return CondOpInit::get(Cases, Vals, Type)->Fold(CurRec);
2834}
2835
2836/// Switch ::= !switch(key, [case : val,]+ default-val) => val type
2837const Init *TGParser::ParseOperationSwitch(Record *CurRec,
2838 const RecTy *ItemType) {
2839 Lex.Lex(); // eat the operation 'switch'
2840
2841 if (!consume(tgtok::l_paren)) {
2842 TokError("expected '(' after !switch operator");
2843 return nullptr;
2844 }
2845
2846 SmallVector<const Init *, 4> KeyAndCases;
2847 const Init *Key = ParseValue(CurRec);
2848 if (!Key)
2849 return nullptr;
2850 // Push the key as the first element of the vector for type-checking.
2851 KeyAndCases.push_back(Key);
2852
2853 if (!consume(tgtok::comma)) {
2854 TokError("expected ',' after key in !switch operator");
2855 return nullptr;
2856 }
2857
2858 // After parsing each Value, the next token disambiguates: ')' means it was
2859 // the default; ':' means it was a case key whose value follows.
2861 while (true) {
2862 const Init *V = ParseValue(CurRec);
2863 if (!V)
2864 return nullptr;
2865
2866 // Parse the mandatory default value.
2867 if (consume(tgtok::r_paren)) {
2868 if (ItemType) {
2869 // The default value was parsed without the ItemType hint. Coerce it now
2870 // to match case-value parses.
2871 if (const Init *Coerced = V->convertInitializerTo(ItemType))
2872 V = Coerced;
2873 }
2874 // Push the default value as the last element of the vector for
2875 // type-checking.
2876 Vals.push_back(V);
2877 break;
2878 }
2879
2880 if (!consume(tgtok::colon)) {
2881 TokError("expected ':' after case key, or ')' to close !switch operator");
2882 return nullptr;
2883 }
2884 KeyAndCases.push_back(V);
2885
2886 V = ParseValue(CurRec, ItemType);
2887 if (!V)
2888 return nullptr;
2889 Vals.push_back(V);
2890
2891 if (!consume(tgtok::comma)) {
2892 TokError("expected ',' after case value in !switch operator");
2893 return nullptr;
2894 }
2895 }
2896 assert(KeyAndCases.size() == Vals.size() &&
2897 "inconsistent keys and values for !switch");
2898
2899 if (KeyAndCases.size() < 2) {
2900 TokError(
2901 "there should be at least 1 'case: value' in the !switch operator");
2902 return nullptr;
2903 }
2904
2905 // Check value type consistency.
2906 std::optional<const RecTy *> ValTypeOpt =
2907 resolveInitTypes(Vals, "for !switch values");
2908 if (!ValTypeOpt)
2909 return nullptr;
2910 const RecTy *ValType = *ValTypeOpt;
2911 if (!ValType) {
2912 TokError("could not determine type for !switch from its arguments");
2913 return nullptr;
2914 }
2915
2916 // Check key/case-key type consistency. We only care about conflicts here.
2917 // The all-unset case should be fine because no downstream code uses the key
2918 // type.
2919 if (!resolveInitTypes(KeyAndCases, "between !switch key and case keys"))
2920 return nullptr;
2921
2922 // Reduce !switch to !cond: each case becomes !eq(Key, c_i) -> v_i, with a
2923 // trailing 'true' arm carrying the default value.
2925 size_t ValsSize = Vals.size();
2926 Conds.reserve(ValsSize);
2927 const RecTy *BitTy = BitRecTy::get(Records);
2928 for (const Init *CaseKey : llvm::drop_begin(KeyAndCases))
2929 Conds.push_back(
2930 BinOpInit::get(BinOpInit::EQ, Key, CaseKey, BitTy)->Fold(CurRec));
2931 Conds.push_back(IntInit::get(Records, 1));
2932 assert(Conds.size() == ValsSize && "inconsistent !switch to !cond reduction");
2933 return CondOpInit::get(Conds, Vals, ValType)->Fold(CurRec);
2934}
2935
2936/// ParseSimpleValue - Parse a tblgen value. This returns null on error.
2937///
2938/// SimpleValue ::= IDValue
2939/// SimpleValue ::= INTVAL
2940/// SimpleValue ::= STRVAL+
2941/// SimpleValue ::= CODEFRAGMENT
2942/// SimpleValue ::= '?'
2943/// SimpleValue ::= '{' ValueList '}'
2944/// SimpleValue ::= ID '<' ValueListNE '>'
2945/// SimpleValue ::= '[' ValueList ']'
2946/// SimpleValue ::= '(' IDValue DagArgList ')'
2947/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
2948/// SimpleValue ::= ADDTOK '(' Value ',' Value ')'
2949/// SimpleValue ::= DIVTOK '(' Value ',' Value ')'
2950/// SimpleValue ::= SUBTOK '(' Value ',' Value ')'
2951/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
2952/// SimpleValue ::= SRATOK '(' Value ',' Value ')'
2953/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
2954/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
2955/// SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')'
2956/// SimpleValue ::= LISTREMOVETOK '(' Value ',' Value ')'
2957/// SimpleValue ::= RANGE '(' Value ')'
2958/// SimpleValue ::= RANGE '(' Value ',' Value ')'
2959/// SimpleValue ::= RANGE '(' Value ',' Value ',' Value ')'
2960/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
2961/// SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
2962///
2963const Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
2964 IDParseMode Mode) {
2965 const Init *R = nullptr;
2966 tgtok::TokKind Code = Lex.getCode();
2967
2968 // Parse bang operators.
2969 if (tgtok::isBangOperator(Code))
2970 return ParseOperation(CurRec, ItemType);
2971
2972 switch (Code) {
2973 default:
2974 TokError("Unknown or reserved token when parsing a value");
2975 break;
2976
2977 case tgtok::TrueVal:
2978 R = IntInit::get(Records, 1);
2979 Lex.Lex();
2980 break;
2981 case tgtok::FalseVal:
2982 R = IntInit::get(Records, 0);
2983 Lex.Lex();
2984 break;
2985 case tgtok::IntVal:
2986 R = IntInit::get(Records, Lex.getCurIntVal());
2987 Lex.Lex();
2988 break;
2989 case tgtok::BinaryIntVal: {
2990 auto BinaryVal = Lex.getCurBinaryIntVal();
2991 SmallVector<Init *, 16> Bits(BinaryVal.second);
2992 for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2993 Bits[i] = BitInit::get(Records, BinaryVal.first & (1LL << i));
2994 R = BitsInit::get(Records, Bits);
2995 Lex.Lex();
2996 break;
2997 }
2998 case tgtok::StrVal: {
2999 std::string Val = Lex.getCurStrVal();
3000 Lex.Lex();
3001
3002 // Handle multiple consecutive concatenated strings.
3003 while (Lex.getCode() == tgtok::StrVal) {
3004 Val += Lex.getCurStrVal();
3005 Lex.Lex();
3006 }
3007
3008 R = StringInit::get(Records, Val);
3009 break;
3010 }
3012 R = StringInit::get(Records, Lex.getCurStrVal(), StringInit::SF_Code);
3013 Lex.Lex();
3014 break;
3015 case tgtok::question:
3016 R = UnsetInit::get(Records);
3017 Lex.Lex();
3018 break;
3019 case tgtok::Id: {
3020 SMRange NameLoc = Lex.getLocRange();
3021 const StringInit *Name = StringInit::get(Records, Lex.getCurStrVal());
3022 tgtok::TokKind Next = Lex.Lex();
3023 if (Next == tgtok::equal) // Named argument.
3024 return Name;
3025 if (Next != tgtok::less) // consume the Id.
3026 return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue
3027
3028 // Value ::= CLASSID '<' ArgValueList '>' (CLASSID has been consumed)
3029 // This is supposed to synthesize a new anonymous definition, deriving
3030 // from the class with the template arguments, but no body.
3031 const Record *Class = Records.getClass(Name->getValue());
3032 if (!Class) {
3033 Error(NameLoc.Start,
3034 "Expected a class name, got '" + Name->getValue() + "'");
3035 return nullptr;
3036 }
3037
3039 SmallVector<SMLoc> ArgLocs;
3040 Lex.Lex(); // consume the <
3041 if (ParseTemplateArgValueList(Args, ArgLocs, CurRec, Class))
3042 return nullptr; // Error parsing value list.
3043
3044 if (CheckTemplateArgValues(Args, ArgLocs, Class))
3045 return nullptr; // Error checking template argument values.
3046
3047 if (resolveArguments(Class, Args, NameLoc.Start))
3048 return nullptr;
3049
3050 if (TrackReferenceLocs)
3051 Class->appendReferenceLoc(NameLoc);
3052 return VarDefInit::get(NameLoc.Start, Class, Args)->Fold();
3053 }
3054 case tgtok::l_brace: { // Value ::= '{' ValueList '}'
3055 SMLoc BraceLoc = Lex.getLoc();
3056 Lex.Lex(); // eat the '{'
3058
3059 if (Lex.getCode() != tgtok::r_brace) {
3060 ParseValueList(Vals, CurRec);
3061 if (Vals.empty())
3062 return nullptr;
3063 }
3064 if (!consume(tgtok::r_brace)) {
3065 TokError("expected '}' at end of bit list value");
3066 return nullptr;
3067 }
3068
3070
3071 // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it
3072 // first. We'll first read everything in to a vector, then we can reverse
3073 // it to get the bits in the correct order for the BitsInit value.
3074 for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
3075 // FIXME: The following two loops would not be duplicated
3076 // if the API was a little more orthogonal.
3077
3078 // bits<n> values are allowed to initialize n bits.
3079 if (const auto *BI = dyn_cast<BitsInit>(Vals[i])) {
3080 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
3081 NewBits.push_back(BI->getBit((e - i) - 1));
3082 continue;
3083 }
3084 // bits<n> can also come from variable initializers.
3085 if (const auto *VI = dyn_cast<VarInit>(Vals[i])) {
3086 if (const auto *BitsRec = dyn_cast<BitsRecTy>(VI->getType())) {
3087 for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
3088 NewBits.push_back(VI->getBit((e - i) - 1));
3089 continue;
3090 }
3091 // Fallthrough to try convert this to a bit.
3092 }
3093 // All other values must be convertible to just a single bit.
3094 const Init *Bit = Vals[i]->getCastTo(BitRecTy::get(Records));
3095 if (!Bit) {
3096 Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
3097 ") is not convertable to a bit");
3098 return nullptr;
3099 }
3100 NewBits.push_back(Bit);
3101 }
3102 std::reverse(NewBits.begin(), NewBits.end());
3103 return BitsInit::get(Records, NewBits);
3104 }
3105 case tgtok::l_square: { // Value ::= '[' ValueList ']'
3106 Lex.Lex(); // eat the '['
3108
3109 const RecTy *DeducedEltTy = nullptr;
3110 const ListRecTy *GivenListTy = nullptr;
3111
3112 if (ItemType) {
3113 const auto *ListType = dyn_cast<ListRecTy>(ItemType);
3114 if (!ListType) {
3115 TokError(Twine("Encountered a list when expecting a ") +
3116 ItemType->getAsString());
3117 return nullptr;
3118 }
3119 GivenListTy = ListType;
3120 }
3121
3122 if (Lex.getCode() != tgtok::r_square) {
3123 ParseValueList(Vals, CurRec,
3124 GivenListTy ? GivenListTy->getElementType() : nullptr);
3125 if (Vals.empty())
3126 return nullptr;
3127 }
3128 if (!consume(tgtok::r_square)) {
3129 TokError("expected ']' at end of list value");
3130 return nullptr;
3131 }
3132
3133 const RecTy *GivenEltTy = nullptr;
3134 if (consume(tgtok::less)) {
3135 // Optional list element type
3136 GivenEltTy = ParseType();
3137 if (!GivenEltTy) {
3138 // Couldn't parse element type
3139 return nullptr;
3140 }
3141
3142 if (!consume(tgtok::greater)) {
3143 TokError("expected '>' at end of list element type");
3144 return nullptr;
3145 }
3146 }
3147
3148 // Check elements
3149 const RecTy *EltTy = nullptr;
3150 for (const Init *V : Vals) {
3151 const auto *TArg = dyn_cast<TypedInit>(V);
3152 if (TArg) {
3153 if (EltTy) {
3154 EltTy = resolveTypes(EltTy, TArg->getType());
3155 if (!EltTy) {
3156 TokError("Incompatible types in list elements");
3157 return nullptr;
3158 }
3159 } else {
3160 EltTy = TArg->getType();
3161 }
3162 }
3163 }
3164
3165 if (GivenEltTy) {
3166 if (EltTy) {
3167 // Verify consistency
3168 if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
3169 TokError("Incompatible types in list elements");
3170 return nullptr;
3171 }
3172 }
3173 EltTy = GivenEltTy;
3174 }
3175
3176 if (!EltTy) {
3177 if (!ItemType) {
3178 TokError("No type for list");
3179 return nullptr;
3180 }
3181 DeducedEltTy = GivenListTy->getElementType();
3182 } else {
3183 // Make sure the deduced type is compatible with the given type
3184 if (GivenListTy) {
3185 if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
3186 TokError(Twine("Element type mismatch for list: element type '") +
3187 EltTy->getAsString() + "' not convertible to '" +
3188 GivenListTy->getElementType()->getAsString());
3189 return nullptr;
3190 }
3191 }
3192 DeducedEltTy = EltTy;
3193 }
3194
3195 return ListInit::get(Vals, DeducedEltTy);
3196 }
3197 case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
3198 // Value ::= '(' '[' ValueList ']' DagArgList ')'
3199 Lex.Lex(); // eat the '('
3200 if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&
3201 Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp &&
3202 Lex.getCode() != tgtok::l_square) {
3203 TokError("expected identifier or list of value types in dag init");
3204 return nullptr;
3205 }
3206
3207 const Init *Operator = ParseValue(CurRec);
3208 if (!Operator)
3209 return nullptr;
3210
3211 // If the operator name is present, parse it.
3212 const StringInit *OperatorName = nullptr;
3213 if (consume(tgtok::colon)) {
3214 if (Lex.getCode() != tgtok::VarName) { // eat the ':'
3215 TokError("expected variable name in dag operator");
3216 return nullptr;
3217 }
3218 OperatorName = StringInit::get(Records, Lex.getCurStrVal());
3219 Lex.Lex(); // eat the VarName.
3220 }
3221
3223 if (Lex.getCode() != tgtok::r_paren) {
3224 ParseDagArgList(DagArgs, CurRec);
3225 if (DagArgs.empty())
3226 return nullptr;
3227 }
3228
3229 if (!consume(tgtok::r_paren)) {
3230 TokError("expected ')' in dag init");
3231 return nullptr;
3232 }
3233
3234 return DagInit::get(Operator, OperatorName, DagArgs);
3235 }
3236 }
3237
3238 return R;
3239}
3240
3241/// ParseValue - Parse a TableGen value. This returns null on error.
3242///
3243/// Value ::= SimpleValue ValueSuffix*
3244/// ValueSuffix ::= '{' BitList '}'
3245/// ValueSuffix ::= '[' SliceElements ']'
3246/// ValueSuffix ::= '.' ID
3247///
3248const Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
3249 IDParseMode Mode) {
3250 SMLoc LHSLoc = Lex.getLoc();
3251 const Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
3252 if (!Result)
3253 return nullptr;
3254
3255 // Parse the suffixes now if present.
3256 while (true) {
3257 switch (Lex.getCode()) {
3258 default:
3259 return Result;
3260 case tgtok::l_brace: {
3261 if (Mode == ParseNameMode)
3262 // This is the beginning of the object body.
3263 return Result;
3264
3265 SMLoc CurlyLoc = Lex.getLoc();
3266 Lex.Lex(); // eat the '{'
3267 SmallVector<unsigned, 16> Ranges;
3268 ParseRangeList(Ranges);
3269 if (Ranges.empty())
3270 return nullptr;
3271
3272 // Reverse the bitlist.
3273 std::reverse(Ranges.begin(), Ranges.end());
3274 Result = Result->convertInitializerBitRange(Ranges);
3275 if (!Result) {
3276 Error(CurlyLoc, "Invalid bit range for value");
3277 return nullptr;
3278 }
3279
3280 // Eat the '}'.
3281 if (!consume(tgtok::r_brace)) {
3282 TokError("expected '}' at end of bit range list");
3283 return nullptr;
3284 }
3285 break;
3286 }
3287 case tgtok::l_square: {
3288 const auto *LHS = dyn_cast<TypedInit>(Result);
3289 if (!LHS) {
3290 Error(LHSLoc, "Invalid value, list expected");
3291 return nullptr;
3292 }
3293
3294 const auto *LHSTy = dyn_cast<ListRecTy>(LHS->getType());
3295 if (!LHSTy) {
3296 Error(LHSLoc, "Type '" + Twine(LHS->getType()->getAsString()) +
3297 "' is invalid, list expected");
3298 return nullptr;
3299 }
3300
3301 Lex.Lex(); // eat the '['
3302 const TypedInit *RHS = ParseSliceElements(CurRec, /*Single=*/true);
3303 if (!RHS)
3304 return nullptr;
3305
3306 if (isa<ListRecTy>(RHS->getType())) {
3307 Result =
3308 BinOpInit::get(BinOpInit::LISTSLICE, LHS, RHS, LHSTy)->Fold(CurRec);
3309 } else {
3311 LHSTy->getElementType())
3312 ->Fold(CurRec);
3313 }
3314
3315 assert(Result);
3316
3317 // Eat the ']'.
3318 if (!consume(tgtok::r_square)) {
3319 TokError("expected ']' at end of list slice");
3320 return nullptr;
3321 }
3322 break;
3323 }
3324 case tgtok::dot: {
3325 if (Lex.Lex() != tgtok::Id) { // eat the .
3326 TokError("expected field identifier after '.'");
3327 return nullptr;
3328 }
3329 SMRange FieldNameLoc = Lex.getLocRange();
3330 const StringInit *FieldName =
3331 StringInit::get(Records, Lex.getCurStrVal());
3332 if (!Result->getFieldType(FieldName)) {
3333 TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
3334 Result->getAsString() + "'");
3335 return nullptr;
3336 }
3337
3338 // Add a reference to this field if we know the record class.
3339 if (TrackReferenceLocs) {
3340 if (const auto *DI = dyn_cast<DefInit>(Result)) {
3341 const RecordVal *V = DI->getDef()->getValue(FieldName);
3342 const_cast<RecordVal *>(V)->addReferenceLoc(FieldNameLoc);
3343 } else if (const auto *TI = dyn_cast<TypedInit>(Result)) {
3344 if (const auto *RecTy = dyn_cast<RecordRecTy>(TI->getType())) {
3345 for (const Record *R : RecTy->getClasses())
3346 if (const auto *RV = R->getValue(FieldName))
3347 const_cast<RecordVal *>(RV)->addReferenceLoc(FieldNameLoc);
3348 }
3349 }
3350 }
3351
3352 Result = FieldInit::get(Result, FieldName)->Fold(CurRec);
3353 Lex.Lex(); // eat field name
3354 break;
3355 }
3356
3357 case tgtok::paste:
3358 SMLoc PasteLoc = Lex.getLoc();
3359 const auto *LHS = dyn_cast<TypedInit>(Result);
3360 if (!LHS) {
3361 Error(PasteLoc, "LHS of paste is not typed!");
3362 return nullptr;
3363 }
3364
3365 // Check if it's a 'listA # listB'
3366 if (isa<ListRecTy>(LHS->getType())) {
3367 Lex.Lex(); // Eat the '#'.
3368
3369 assert(Mode == ParseValueMode && "encountered paste of lists in name");
3370
3371 switch (Lex.getCode()) {
3372 case tgtok::colon:
3373 case tgtok::semi:
3374 case tgtok::l_brace:
3375 Result = LHS; // trailing paste, ignore.
3376 break;
3377 default:
3378 const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3379 if (!RHSResult)
3380 return nullptr;
3381 Result = BinOpInit::getListConcat(LHS, RHSResult);
3382 break;
3383 }
3384 break;
3385 }
3386
3387 // Create a !strconcat() operation, first casting each operand to
3388 // a string if necessary.
3389 if (LHS->getType() != StringRecTy::get(Records)) {
3390 auto CastLHS = dyn_cast<TypedInit>(
3392 ->Fold(CurRec));
3393 if (!CastLHS) {
3394 Error(PasteLoc,
3395 Twine("can't cast '") + LHS->getAsString() + "' to string");
3396 return nullptr;
3397 }
3398 LHS = CastLHS;
3399 }
3400
3401 const TypedInit *RHS = nullptr;
3402
3403 Lex.Lex(); // Eat the '#'.
3404 switch (Lex.getCode()) {
3405 case tgtok::colon:
3406 case tgtok::semi:
3407 case tgtok::l_brace:
3408 // These are all of the tokens that can begin an object body.
3409 // Some of these can also begin values but we disallow those cases
3410 // because they are unlikely to be useful.
3411
3412 // Trailing paste, concat with an empty string.
3413 RHS = StringInit::get(Records, "");
3414 break;
3415
3416 default:
3417 const Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
3418 if (!RHSResult)
3419 return nullptr;
3420 RHS = dyn_cast<TypedInit>(RHSResult);
3421 if (!RHS) {
3422 Error(PasteLoc, "RHS of paste is not typed!");
3423 return nullptr;
3424 }
3425
3426 if (RHS->getType() != StringRecTy::get(Records)) {
3427 auto CastRHS = dyn_cast<TypedInit>(
3429 ->Fold(CurRec));
3430 if (!CastRHS) {
3431 Error(PasteLoc,
3432 Twine("can't cast '") + RHS->getAsString() + "' to string");
3433 return nullptr;
3434 }
3435 RHS = CastRHS;
3436 }
3437
3438 break;
3439 }
3440
3442 break;
3443 }
3444 }
3445}
3446
3447/// ParseDagArgList - Parse the argument list for a dag literal expression.
3448///
3449/// DagArg ::= Value (':' VARNAME)?
3450/// DagArg ::= VARNAME
3451/// DagArgList ::= DagArg
3452/// DagArgList ::= DagArgList ',' DagArg
3453void TGParser::ParseDagArgList(
3454 SmallVectorImpl<std::pair<const Init *, const StringInit *>> &Result,
3455 Record *CurRec) {
3456
3457 while (true) {
3458 // DagArg ::= VARNAME
3459 if (Lex.getCode() == tgtok::VarName) {
3460 // A missing value is treated like '?'.
3461 const StringInit *VarName = StringInit::get(Records, Lex.getCurStrVal());
3462 Result.emplace_back(UnsetInit::get(Records), VarName);
3463 Lex.Lex();
3464 } else {
3465 // DagArg ::= Value (':' VARNAME)?
3466 const Init *Val = ParseValue(CurRec);
3467 if (!Val) {
3468 Result.clear();
3469 return;
3470 }
3471
3472 // If the variable name is present, add it.
3473 const StringInit *VarName = nullptr;
3474 if (Lex.getCode() == tgtok::colon) {
3475 if (Lex.Lex() != tgtok::VarName) { // eat the ':'
3476 TokError("expected variable name in dag literal");
3477 Result.clear();
3478 return;
3479 }
3480 VarName = StringInit::get(Records, Lex.getCurStrVal());
3481 Lex.Lex(); // eat the VarName.
3482 }
3483
3484 Result.emplace_back(Val, VarName);
3485 }
3486 if (!consume(tgtok::comma))
3487 break;
3488 }
3489}
3490
3491/// ParseValueList - Parse a comma separated list of values, returning them
3492/// in a vector. Note that this always expects to be able to parse at least one
3493/// value. It returns an empty list if this is not possible.
3494///
3495/// ValueList ::= Value (',' Value)
3496///
3497void TGParser::ParseValueList(SmallVectorImpl<const Init *> &Result,
3498 Record *CurRec, const RecTy *ItemType) {
3499 Result.push_back(ParseValue(CurRec, ItemType));
3500 if (!Result.back()) {
3501 Result.clear();
3502 return;
3503 }
3504
3505 while (consume(tgtok::comma)) {
3506 // ignore trailing comma for lists
3507 if (Lex.getCode() == tgtok::r_square)
3508 return;
3509 Result.push_back(ParseValue(CurRec, ItemType));
3510 if (!Result.back()) {
3511 Result.clear();
3512 return;
3513 }
3514 }
3515}
3516
3517// ParseTemplateArgValueList - Parse a template argument list with the syntax
3518// shown, filling in the Result vector. The open angle has been consumed.
3519// An empty argument list is allowed. Return false if okay, true if an
3520// error was detected.
3521//
3522// ArgValueList ::= '<' PostionalArgValueList [','] NamedArgValueList '>'
3523// PostionalArgValueList ::= [Value {',' Value}*]
3524// NamedArgValueList ::= [NameValue '=' Value {',' NameValue '=' Value}*]
3525bool TGParser::ParseTemplateArgValueList(
3527 SmallVectorImpl<SMLoc> &ArgLocs, Record *CurRec, const Record *ArgsRec) {
3528 assert(Result.empty() && "Result vector is not empty");
3529 ArrayRef<const Init *> TArgs = ArgsRec->getTemplateArgs();
3530
3531 if (consume(tgtok::greater)) // empty value list
3532 return false;
3533
3534 bool HasNamedArg = false;
3535 unsigned ArgIndex = 0;
3536 while (true) {
3537 if (ArgIndex >= TArgs.size()) {
3538 TokError("Too many template arguments: " + utostr(ArgIndex + 1));
3539 return true;
3540 }
3541
3542 SMLoc ValueLoc = ArgLocs.emplace_back(Lex.getLoc());
3543 // If we are parsing named argument, we don't need to know the argument name
3544 // and argument type will be resolved after we know the name.
3545 const Init *Value = ParseValue(
3546 CurRec,
3547 HasNamedArg ? nullptr : ArgsRec->getValue(TArgs[ArgIndex])->getType());
3548 if (!Value)
3549 return true;
3550
3551 // If we meet '=', then we are parsing named arguments.
3552 if (Lex.getCode() == tgtok::equal) {
3553 if (!isa<StringInit>(Value))
3554 return Error(ValueLoc,
3555 "The name of named argument should be a valid identifier");
3556
3557 auto *Name = cast<StringInit>(Value);
3558 const Init *QualifiedName = QualifyName(*ArgsRec, Name);
3559 auto *NamedArg = ArgsRec->getValue(QualifiedName);
3560 if (!NamedArg)
3561 return Error(ValueLoc,
3562 "Argument " + Name->getAsString() + " doesn't exist");
3563
3564 Lex.Lex(); // eat the '='.
3565 ValueLoc = Lex.getLoc();
3566 Value = ParseValue(CurRec, NamedArg->getType());
3567 // Named value can't be uninitialized.
3568 if (isa<UnsetInit>(Value))
3569 return Error(ValueLoc,
3570 "The value of named argument should be initialized, "
3571 "but we got '" +
3572 Value->getAsString() + "'");
3573
3574 Result.push_back(ArgumentInit::get(Value, QualifiedName));
3575 HasNamedArg = true;
3576 } else {
3577 // Positional arguments should be put before named arguments.
3578 if (HasNamedArg)
3579 return Error(ValueLoc,
3580 "Positional argument should be put before named argument");
3581
3582 Result.push_back(ArgumentInit::get(Value, ArgIndex));
3583 }
3584
3585 if (consume(tgtok::greater)) // end of argument list?
3586 return false;
3587 if (!consume(tgtok::comma))
3588 return TokError("Expected comma before next argument");
3589 ++ArgIndex;
3590 }
3591}
3592
3593/// ParseDeclaration - Read a declaration, returning the name of field ID, or an
3594/// empty string on error. This can happen in a number of different contexts,
3595/// including within a def or in the template args for a class (in which case
3596/// CurRec will be non-null) and within the template args for a multiclass (in
3597/// which case CurRec will be null, but CurMultiClass will be set). This can
3598/// also happen within a def that is within a multiclass, which will set both
3599/// CurRec and CurMultiClass.
3600///
3601/// Declaration ::= FIELD? Type ID ('=' Value)?
3602///
3603const Init *TGParser::ParseDeclaration(Record *CurRec,
3604 bool ParsingTemplateArgs) {
3605 // Read the field prefix if present.
3606 bool HasField = consume(tgtok::Field);
3607
3608 const RecTy *Type = ParseType();
3609 if (!Type)
3610 return nullptr;
3611
3612 if (Lex.getCode() != tgtok::Id) {
3613 TokError("Expected identifier in declaration");
3614 return nullptr;
3615 }
3616
3617 std::string Str = Lex.getCurStrVal();
3618 if (Str == "NAME") {
3619 TokError("'" + Str + "' is a reserved variable name");
3620 return nullptr;
3621 }
3622
3623 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {
3624 TokError("local variable of this name already exists");
3625 return nullptr;
3626 }
3627
3628 SMLoc IdLoc = Lex.getLoc();
3629 const Init *DeclName = StringInit::get(Records, Str);
3630 Lex.Lex();
3631
3632 bool BadField;
3633 if (!ParsingTemplateArgs) { // def, possibly in a multiclass
3634 BadField = AddValue(CurRec, IdLoc,
3635 RecordVal(DeclName, IdLoc, Type,
3638 } else if (CurRec) { // class template argument
3639 DeclName = QualifyName(*CurRec, DeclName);
3640 BadField =
3641 AddValue(CurRec, IdLoc,
3642 RecordVal(DeclName, IdLoc, Type, RecordVal::FK_TemplateArg));
3643 } else { // multiclass template argument
3644 assert(CurMultiClass && "invalid context for template argument");
3645 DeclName = QualifyName(CurMultiClass, DeclName);
3646 BadField =
3647 AddValue(CurRec, IdLoc,
3648 RecordVal(DeclName, IdLoc, Type, RecordVal::FK_TemplateArg));
3649 }
3650 if (BadField)
3651 return nullptr;
3652
3653 // If a value is present, parse it and set new field's value.
3654 if (consume(tgtok::equal)) {
3655 SMLoc ValLoc = Lex.getLoc();
3656 const Init *Val = ParseValue(CurRec, Type);
3657 if (!Val ||
3658 SetValue(CurRec, ValLoc, DeclName, {}, Val,
3659 /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/false)) {
3660 // Return the name, even if an error is thrown. This is so that we can
3661 // continue to make some progress, even without the value having been
3662 // initialized.
3663 return DeclName;
3664 }
3665 }
3666
3667 return DeclName;
3668}
3669
3670/// ParseForeachDeclaration - Read a foreach declaration, returning
3671/// the name of the declared object or a NULL Init on error. Return
3672/// the name of the parsed initializer list through ForeachListName.
3673///
3674/// ForeachDeclaration ::= ID '=' '{' RangeList '}'
3675/// ForeachDeclaration ::= ID '=' RangePiece
3676/// ForeachDeclaration ::= ID '=' Value
3677///
3678const VarInit *
3679TGParser::ParseForeachDeclaration(const Init *&ForeachListValue) {
3680 if (Lex.getCode() != tgtok::Id) {
3681 TokError("Expected identifier in foreach declaration");
3682 return nullptr;
3683 }
3684
3685 const Init *DeclName = StringInit::get(Records, Lex.getCurStrVal());
3686 Lex.Lex();
3687
3688 // If a value is present, parse it.
3689 if (!consume(tgtok::equal)) {
3690 TokError("Expected '=' in foreach declaration");
3691 return nullptr;
3692 }
3693
3694 const RecTy *IterType = nullptr;
3695 SmallVector<unsigned, 16> Ranges;
3696
3697 switch (Lex.getCode()) {
3698 case tgtok::l_brace: { // '{' RangeList '}'
3699 Lex.Lex(); // eat the '{'
3700 ParseRangeList(Ranges);
3701 if (!consume(tgtok::r_brace)) {
3702 TokError("expected '}' at end of bit range list");
3703 return nullptr;
3704 }
3705 break;
3706 }
3707
3708 default: {
3709 SMLoc ValueLoc = Lex.getLoc();
3710 const Init *I = ParseValue(nullptr);
3711 if (!I)
3712 return nullptr;
3713
3714 const auto *TI = dyn_cast<TypedInit>(I);
3715 if (TI && isa<ListRecTy>(TI->getType())) {
3716 ForeachListValue = I;
3717 IterType = cast<ListRecTy>(TI->getType())->getElementType();
3718 break;
3719 }
3720
3721 if (TI) {
3722 if (ParseRangePiece(Ranges, TI))
3723 return nullptr;
3724 break;
3725 }
3726
3727 Error(ValueLoc, "expected a list, got '" + I->getAsString() + "'");
3728 if (CurMultiClass) {
3729 PrintNote({}, "references to multiclass template arguments cannot be "
3730 "resolved at this time");
3731 }
3732 return nullptr;
3733 }
3734 }
3735
3736 if (!Ranges.empty()) {
3737 assert(!IterType && "Type already initialized?");
3738 IterType = IntRecTy::get(Records);
3739 std::vector<Init *> Values;
3740 for (unsigned R : Ranges)
3741 Values.push_back(IntInit::get(Records, R));
3742 ForeachListValue = ListInit::get(Values, IterType);
3743 }
3744
3745 if (!IterType)
3746 return nullptr;
3747
3748 return VarInit::get(DeclName, IterType);
3749}
3750
3751/// ParseTemplateArgList - Read a template argument list, which is a non-empty
3752/// sequence of template-declarations in <>'s. If CurRec is non-null, these are
3753/// template args for a class. If null, these are the template args for a
3754/// multiclass.
3755///
3756/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>'
3757///
3758bool TGParser::ParseTemplateArgList(Record *CurRec) {
3759 assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
3760 Lex.Lex(); // eat the '<'
3761
3762 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
3763
3764 // Read the first declaration.
3765 const Init *TemplArg = ParseDeclaration(CurRec, true /*templateargs*/);
3766 if (!TemplArg)
3767 return true;
3768
3769 TheRecToAddTo->addTemplateArg(TemplArg);
3770
3771 while (consume(tgtok::comma)) {
3772 // Read the following declarations.
3773 SMLoc Loc = Lex.getLoc();
3774 TemplArg = ParseDeclaration(CurRec, true /*templateargs*/);
3775 if (!TemplArg)
3776 return true;
3777
3778 if (TheRecToAddTo->isTemplateArg(TemplArg))
3779 return Error(Loc, "template argument with the same name has already been "
3780 "defined");
3781
3782 TheRecToAddTo->addTemplateArg(TemplArg);
3783 }
3784
3785 if (!consume(tgtok::greater))
3786 return TokError("expected '>' at end of template argument list");
3787 return false;
3788}
3789
3790/// Parse an optional 'append'/'prepend' mode followed by a field name.
3791///
3792/// The current token must be an identifier. If the identifier is 'append' or
3793/// 'prepend' and is followed by another identifier, it is interpreted as a
3794/// mode keyword and the following identifier is parsed as the field name.
3795/// Otherwise the identifier itself is treated as the field name.
3796///
3797/// These keywords are contextual: a field may still be named 'append' or
3798/// 'prepend' (e.g. `let append = ...`). In that case the keyword is not
3799/// interpreted as a mode and the identifier is parsed as the field name.
3800LetModeAndName TGParser::ParseLetModeAndName() {
3801 assert(Lex.getCode() == tgtok::Id && "expected identifier");
3802
3803 SMLoc Loc = Lex.getLoc();
3804 // Copy the identifier before Lex.Lex() invalidates the lexer buffer.
3805 std::string CurStr = Lex.getCurStrVal();
3806
3807 LetMode Mode = llvm::StringSwitch<LetMode>(CurStr)
3808 .Case("append", LetMode::Append)
3809 .Case("prepend", LetMode::Prepend)
3810 .Default(LetMode::Replace);
3811
3812 // Consume the current identifier.
3813 Lex.Lex();
3814
3815 if (Mode != LetMode::Replace && Lex.getCode() == tgtok::Id) {
3816 // 'append'/'prepend' used as a contextual keyword.
3817 LetModeAndName Result = {Mode, Lex.getLoc(), Lex.getCurStrVal()};
3818 Lex.Lex(); // Consume the field name.
3819 return Result;
3820 }
3821
3822 // Otherwise the identifier itself is the field name (including the case
3823 // where the field is literally named 'append' or 'prepend').
3824 return {LetMode::Replace, Loc, std::move(CurStr)};
3825}
3826
3827/// ParseBodyItem - Parse a single item within the body of a def or class.
3828///
3829/// BodyItem ::= Declaration ';'
3830/// BodyItem ::= LET [append|prepend] ID OptionalRangeList '=' Value ';'
3831/// BodyItem ::= Defvar
3832/// BodyItem ::= Dump
3833/// BodyItem ::= Assert
3834///
3835bool TGParser::ParseBodyItem(Record *CurRec) {
3836 if (Lex.getCode() == tgtok::Assert)
3837 return ParseAssert(nullptr, CurRec);
3838
3839 if (Lex.getCode() == tgtok::Defvar)
3840 return ParseDefvar(CurRec);
3841
3842 if (Lex.getCode() == tgtok::Dump)
3843 return ParseDump(nullptr, CurRec);
3844
3845 if (Lex.getCode() != tgtok::Let) {
3846 if (!ParseDeclaration(CurRec, false))
3847 return true;
3848
3849 if (!consume(tgtok::semi))
3850 return TokError("expected ';' after declaration");
3851 return false;
3852 }
3853
3854 // LET [append|prepend] ID OptionalBitList '=' Value ';'
3855 Lex.Lex(); // eat 'let'.
3856
3857 if (Lex.getCode() != tgtok::Id)
3858 return TokError("expected field identifier after let");
3859
3860 auto [Mode, IdLoc, FieldNameStr] = ParseLetModeAndName();
3861 const StringInit *FieldName = StringInit::get(Records, FieldNameStr);
3862
3863 SmallVector<unsigned, 16> BitList;
3864 if (ParseOptionalRangeList(BitList))
3865 return true;
3866 std::reverse(BitList.begin(), BitList.end());
3867
3868 if (!consume(tgtok::equal))
3869 return TokError("expected '=' in let expression");
3870
3871 RecordVal *Field = CurRec->getValue(FieldName);
3872 if (!Field)
3873 return Error(IdLoc, "Value '" + FieldName->getValue() + "' unknown!");
3874
3875 const RecTy *Type = Field->getType();
3876 if (!BitList.empty() && isa<BitsRecTy>(Type)) {
3877 // When assigning to a subset of a 'bits' object, expect the RHS to have
3878 // the type of that subset instead of the type of the whole object.
3879 Type = BitsRecTy::get(Records, BitList.size());
3880 }
3881
3882 const Init *Val = ParseValue(CurRec, Type);
3883 if (!Val)
3884 return true;
3885
3886 if (!consume(tgtok::semi))
3887 return TokError("expected ';' after let expression");
3888
3889 return SetValue(CurRec, IdLoc, FieldName, BitList, Val,
3890 /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/true, Mode);
3891}
3892
3893/// ParseBody - Read the body of a class or def. Return true on error, false on
3894/// success.
3895///
3896/// Body ::= ';'
3897/// Body ::= '{' BodyList '}'
3898/// BodyList BodyItem*
3899///
3900bool TGParser::ParseBody(Record *CurRec) {
3901 // If this is a null definition, just eat the semi and return.
3902 if (consume(tgtok::semi))
3903 return false;
3904
3905 if (!consume(tgtok::l_brace))
3906 return TokError("Expected '{' to start body or ';' for declaration only");
3907
3908 while (Lex.getCode() != tgtok::r_brace)
3909 if (ParseBodyItem(CurRec))
3910 return true;
3911
3912 // Eat the '}'.
3913 Lex.Lex();
3914
3915 // If we have a semicolon, print a gentle error.
3916 SMLoc SemiLoc = Lex.getLoc();
3917 if (consume(tgtok::semi)) {
3918 PrintError(SemiLoc, "A class or def body should not end with a semicolon");
3919 PrintNote("Semicolon ignored; remove to eliminate this error");
3920 }
3921
3922 return false;
3923}
3924
3925/// Apply the current let bindings to \a CurRec.
3926/// \returns true on error, false otherwise.
3927bool TGParser::ApplyLetStack(Record *CurRec) {
3928 for (SmallVectorImpl<LetRecord> &LetInfo : LetStack)
3929 for (LetRecord &LR : LetInfo)
3930 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value,
3931 /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/true,
3932 LR.Mode))
3933 return true;
3934 return false;
3935}
3936
3937/// Apply the current let bindings to the RecordsEntry.
3938bool TGParser::ApplyLetStack(RecordsEntry &Entry) {
3939 if (Entry.Rec)
3940 return ApplyLetStack(Entry.Rec.get());
3941
3942 // Let bindings are not applied to assertions.
3943 if (Entry.Assertion)
3944 return false;
3945
3946 // Let bindings are not applied to dumps.
3947 if (Entry.Dump)
3948 return false;
3949
3950 for (auto &E : Entry.Loop->Entries) {
3951 if (ApplyLetStack(E))
3952 return true;
3953 }
3954
3955 return false;
3956}
3957
3958/// ParseObjectBody - Parse the body of a def or class. This consists of an
3959/// optional ClassList followed by a Body. CurRec is the current def or class
3960/// that is being parsed.
3961///
3962/// ObjectBody ::= BaseClassList Body
3963/// BaseClassList ::= /*empty*/
3964/// BaseClassList ::= ':' BaseClassListNE
3965/// BaseClassListNE ::= SubClassRef (',' SubClassRef)*
3966///
3967bool TGParser::ParseObjectBody(Record *CurRec) {
3968 // An object body introduces a new scope for local variables.
3969 TGVarScope *ObjectScope = PushScope(CurRec);
3970 // If there is a baseclass list, read it.
3971 if (consume(tgtok::colon)) {
3972
3973 // Read all of the subclasses.
3974 SubClassReference SubClass = ParseSubClassReference(CurRec, false);
3975 while (true) {
3976 // Check for error.
3977 if (!SubClass.Rec)
3978 return true;
3979
3980 // Add it.
3981 if (AddSubClass(CurRec, SubClass))
3982 return true;
3983
3984 if (!consume(tgtok::comma))
3985 break;
3986 SubClass = ParseSubClassReference(CurRec, false);
3987 }
3988 }
3989
3990 if (ApplyLetStack(CurRec))
3991 return true;
3992
3993 bool Result = ParseBody(CurRec);
3994 PopScope(ObjectScope);
3995 return Result;
3996}
3997
3998/// ParseDef - Parse and return a top level or multiclass record definition.
3999/// Return false if okay, true if error.
4000///
4001/// DefInst ::= DEF ObjectName ObjectBody
4002///
4003bool TGParser::ParseDef(MultiClass *CurMultiClass) {
4004 SMLoc DefLoc = Lex.getLoc();
4005 assert(Lex.getCode() == tgtok::Def && "Unknown tok");
4006 Lex.Lex(); // Eat the 'def' token.
4007
4008 // If the name of the def is an Id token, use that for the location.
4009 // Otherwise, the name is more complex and we use the location of the 'def'
4010 // token.
4011 SMLoc NameLoc = Lex.getCode() == tgtok::Id ? Lex.getLoc() : DefLoc;
4012
4013 // Parse ObjectName and make a record for it.
4014 std::unique_ptr<Record> CurRec;
4015 const Init *Name = ParseObjectName(CurMultiClass);
4016 if (!Name)
4017 return true;
4018
4019 if (isa<UnsetInit>(Name)) {
4020 CurRec = std::make_unique<Record>(Records.getNewAnonymousName(), DefLoc,
4021 Records, Record::RK_AnonymousDef);
4022 } else {
4023 CurRec = std::make_unique<Record>(Name, NameLoc, Records);
4024 }
4025
4026 if (ParseObjectBody(CurRec.get()))
4027 return true;
4028
4029 return addEntry(std::move(CurRec));
4030}
4031
4032/// ParseDefset - Parse a defset statement.
4033///
4034/// Defset ::= DEFSET Type Id '=' '{' ObjectList '}'
4035///
4036bool TGParser::ParseDefset() {
4037 assert(Lex.getCode() == tgtok::Defset);
4038 Lex.Lex(); // Eat the 'defset' token
4039
4040 DefsetRecord Defset;
4041 Defset.Loc = Lex.getLoc();
4042 const RecTy *Type = ParseType();
4043 if (!Type)
4044 return true;
4045 if (!isa<ListRecTy>(Type))
4046 return Error(Defset.Loc, "expected list type");
4047 Defset.EltTy = cast<ListRecTy>(Type)->getElementType();
4048
4049 if (Lex.getCode() != tgtok::Id)
4050 return TokError("expected identifier");
4051 const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
4052 if (Records.getGlobal(DeclName->getValue()))
4053 return TokError("def or global variable of this name already exists");
4054
4055 if (Lex.Lex() != tgtok::equal) // Eat the identifier
4056 return TokError("expected '='");
4057 if (Lex.Lex() != tgtok::l_brace) // Eat the '='
4058 return TokError("expected '{'");
4059 SMLoc BraceLoc = Lex.getLoc();
4060 Lex.Lex(); // Eat the '{'
4061
4062 Defsets.push_back(&Defset);
4063 bool Err = ParseObjectList(nullptr);
4064 Defsets.pop_back();
4065 if (Err)
4066 return true;
4067
4068 if (!consume(tgtok::r_brace)) {
4069 TokError("expected '}' at end of defset");
4070 return Error(BraceLoc, "to match this '{'");
4071 }
4072
4073 Records.addExtraGlobal(DeclName->getValue(),
4074 ListInit::get(Defset.Elements, Defset.EltTy));
4075 return false;
4076}
4077
4078/// ParseDeftype - Parse a defvar statement.
4079///
4080/// Deftype ::= DEFTYPE Id '=' Type ';'
4081///
4082bool TGParser::ParseDeftype() {
4083 assert(Lex.getCode() == tgtok::Deftype);
4084 Lex.Lex(); // Eat the 'deftype' token
4085
4086 if (Lex.getCode() != tgtok::Id)
4087 return TokError("expected identifier");
4088
4089 const std::string TypeName = Lex.getCurStrVal();
4090 if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
4091 return TokError("type of this name '" + TypeName + "' already exists");
4092
4093 Lex.Lex();
4094 if (!consume(tgtok::equal))
4095 return TokError("expected '='");
4096
4097 SMLoc Loc = Lex.getLoc();
4098 const RecTy *Type = ParseType();
4099 if (!Type)
4100 return true;
4101
4102 if (Type->getRecTyKind() == RecTy::RecordRecTyKind)
4103 return Error(Loc, "cannot define type alias for class type '" +
4104 Type->getAsString() + "'");
4105
4106 TypeAliases[TypeName] = Type;
4107
4108 if (!consume(tgtok::semi))
4109 return TokError("expected ';'");
4110
4111 return false;
4112}
4113
4114/// ParseDefvar - Parse a defvar statement.
4115///
4116/// Defvar ::= DEFVAR Id '=' Value ';'
4117///
4118bool TGParser::ParseDefvar(Record *CurRec) {
4119 assert(Lex.getCode() == tgtok::Defvar);
4120 Lex.Lex(); // Eat the 'defvar' token
4121
4122 if (Lex.getCode() != tgtok::Id)
4123 return TokError("expected identifier");
4124 const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
4125 if (CurScope->varAlreadyDefined(DeclName->getValue()))
4126 return TokError("local variable of this name already exists");
4127
4128 // The name should not be conflicted with existed field names.
4129 if (CurRec) {
4130 auto *V = CurRec->getValue(DeclName->getValue());
4131 if (V && !V->isTemplateArg())
4132 return TokError("field of this name already exists");
4133 }
4134
4135 // If this defvar is in the top level, the name should not be conflicted
4136 // with existed global names.
4137 if (CurScope->isOutermost() && Records.getGlobal(DeclName->getValue()))
4138 return TokError("def or global variable of this name already exists");
4139
4140 Lex.Lex();
4141 if (!consume(tgtok::equal))
4142 return TokError("expected '='");
4143
4144 const Init *Value = ParseValue(CurRec);
4145 if (!Value)
4146 return true;
4147
4148 if (!consume(tgtok::semi))
4149 return TokError("expected ';'");
4150
4151 if (!CurScope->isOutermost())
4152 CurScope->addVar(DeclName->getValue(), Value);
4153 else
4154 Records.addExtraGlobal(DeclName->getValue(), Value);
4155
4156 return false;
4157}
4158
4159/// ParseForeach - Parse a for statement. Return the record corresponding
4160/// to it. This returns true on error.
4161///
4162/// Foreach ::= FOREACH Declaration IN '{ ObjectList '}'
4163/// Foreach ::= FOREACH Declaration IN Object
4164///
4165bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
4166 SMLoc Loc = Lex.getLoc();
4167 assert(Lex.getCode() == tgtok::Foreach && "Unknown tok");
4168 Lex.Lex(); // Eat the 'for' token.
4169
4170 // Make a temporary object to record items associated with the for
4171 // loop.
4172 const Init *ListValue = nullptr;
4173 const VarInit *IterName = ParseForeachDeclaration(ListValue);
4174 if (!IterName)
4175 return TokError("expected declaration in for");
4176
4177 if (!consume(tgtok::In))
4178 return TokError("Unknown tok");
4179
4180 // Create a loop object and remember it.
4181 auto TheLoop = std::make_unique<ForeachLoop>(Loc, IterName, ListValue);
4182 // A foreach loop introduces a new scope for local variables.
4183 TGVarScope *ForeachScope = PushScope(TheLoop.get());
4184 Loops.push_back(std::move(TheLoop));
4185
4186 if (Lex.getCode() != tgtok::l_brace) {
4187 // FOREACH Declaration IN Object
4188 if (ParseObject(CurMultiClass))
4189 return true;
4190 } else {
4191 SMLoc BraceLoc = Lex.getLoc();
4192 // Otherwise, this is a group foreach.
4193 Lex.Lex(); // eat the '{'.
4194
4195 // Parse the object list.
4196 if (ParseObjectList(CurMultiClass))
4197 return true;
4198
4199 if (!consume(tgtok::r_brace)) {
4200 TokError("expected '}' at end of foreach command");
4201 return Error(BraceLoc, "to match this '{'");
4202 }
4203 }
4204
4205 PopScope(ForeachScope);
4206
4207 // Resolve the loop or store it for later resolution.
4208 std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
4209 Loops.pop_back();
4210
4211 return addEntry(std::move(Loop));
4212}
4213
4214/// ParseIf - Parse an if statement.
4215///
4216/// If ::= IF Value THEN IfBody
4217/// If ::= IF Value THEN IfBody ELSE IfBody
4218///
4219bool TGParser::ParseIf(MultiClass *CurMultiClass) {
4220 SMLoc Loc = Lex.getLoc();
4221 assert(Lex.getCode() == tgtok::If && "Unknown tok");
4222 Lex.Lex(); // Eat the 'if' token.
4223
4224 // Make a temporary object to record items associated with the for
4225 // loop.
4226 const Init *Condition = ParseValue(nullptr);
4227 if (!Condition)
4228 return true;
4229
4230 if (!consume(tgtok::Then))
4231 return TokError("Unknown tok");
4232
4233 // We have to be able to save if statements to execute later, and they have
4234 // to live on the same stack as foreach loops. The simplest implementation
4235 // technique is to convert each 'then' or 'else' clause *into* a foreach
4236 // loop, over a list of length 0 or 1 depending on the condition, and with no
4237 // iteration variable being assigned.
4238
4239 const ListInit *EmptyList = ListInit::get({}, BitRecTy::get(Records));
4240 const ListInit *SingletonList =
4241 ListInit::get({BitInit::get(Records, true)}, BitRecTy::get(Records));
4242 const RecTy *BitListTy = ListRecTy::get(BitRecTy::get(Records));
4243
4244 // The foreach containing the then-clause selects SingletonList if
4245 // the condition is true.
4246 const Init *ThenClauseList =
4247 TernOpInit::get(TernOpInit::IF, Condition, SingletonList, EmptyList,
4248 BitListTy)
4249 ->Fold(nullptr);
4250 Loops.push_back(std::make_unique<ForeachLoop>(Loc, nullptr, ThenClauseList));
4251
4252 if (ParseIfBody(CurMultiClass, "then"))
4253 return true;
4254
4255 std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
4256 Loops.pop_back();
4257
4258 if (addEntry(std::move(Loop)))
4259 return true;
4260
4261 // Now look for an optional else clause. The if-else syntax has the usual
4262 // dangling-else ambiguity, and by greedily matching an else here if we can,
4263 // we implement the usual resolution of pairing with the innermost unmatched
4264 // if.
4265 if (consume(tgtok::ElseKW)) {
4266 // The foreach containing the else-clause uses the same pair of lists as
4267 // above, but this time, selects SingletonList if the condition is *false*.
4268 const Init *ElseClauseList =
4269 TernOpInit::get(TernOpInit::IF, Condition, EmptyList, SingletonList,
4270 BitListTy)
4271 ->Fold(nullptr);
4272 Loops.push_back(
4273 std::make_unique<ForeachLoop>(Loc, nullptr, ElseClauseList));
4274
4275 if (ParseIfBody(CurMultiClass, "else"))
4276 return true;
4277
4278 Loop = std::move(Loops.back());
4279 Loops.pop_back();
4280
4281 if (addEntry(std::move(Loop)))
4282 return true;
4283 }
4284
4285 return false;
4286}
4287
4288/// ParseIfBody - Parse the then-clause or else-clause of an if statement.
4289///
4290/// IfBody ::= Object
4291/// IfBody ::= '{' ObjectList '}'
4292///
4293bool TGParser::ParseIfBody(MultiClass *CurMultiClass, StringRef Kind) {
4294 // An if-statement introduces a new scope for local variables.
4295 TGVarScope *BodyScope = PushScope();
4296
4297 if (Lex.getCode() != tgtok::l_brace) {
4298 // A single object.
4299 if (ParseObject(CurMultiClass))
4300 return true;
4301 } else {
4302 SMLoc BraceLoc = Lex.getLoc();
4303 // A braced block.
4304 Lex.Lex(); // eat the '{'.
4305
4306 // Parse the object list.
4307 if (ParseObjectList(CurMultiClass))
4308 return true;
4309
4310 if (!consume(tgtok::r_brace)) {
4311 TokError("expected '}' at end of '" + Kind + "' clause");
4312 return Error(BraceLoc, "to match this '{'");
4313 }
4314 }
4315
4316 PopScope(BodyScope);
4317 return false;
4318}
4319
4320/// ParseAssert - Parse an assert statement.
4321///
4322/// Assert ::= ASSERT condition , message ;
4323bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
4324 assert(Lex.getCode() == tgtok::Assert && "Unknown tok");
4325 Lex.Lex(); // Eat the 'assert' token.
4326
4327 SMLoc ConditionLoc = Lex.getLoc();
4328 const Init *Condition = ParseValue(CurRec);
4329 if (!Condition)
4330 return true;
4331
4332 if (!consume(tgtok::comma)) {
4333 TokError("expected ',' in assert statement");
4334 return true;
4335 }
4336
4337 const Init *Message = ParseValue(CurRec);
4338 if (!Message)
4339 return true;
4340
4341 if (!consume(tgtok::semi))
4342 return TokError("expected ';'");
4343
4344 if (CurRec)
4345 CurRec->addAssertion(ConditionLoc, Condition, Message);
4346 else
4347 addEntry(std::make_unique<Record::AssertionInfo>(ConditionLoc, Condition,
4348 Message));
4349 return false;
4350}
4351
4352/// ParseClass - Parse a tblgen class definition.
4353///
4354/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody
4355///
4356bool TGParser::ParseClass() {
4357 assert(Lex.getCode() == tgtok::Class && "Unexpected token!");
4358 Lex.Lex();
4359
4360 if (Lex.getCode() != tgtok::Id)
4361 return TokError("expected class name after 'class' keyword");
4362
4363 const std::string &Name = Lex.getCurStrVal();
4364 Record *CurRec = const_cast<Record *>(Records.getClass(Name));
4365 if (CurRec) {
4366 // If the body was previously defined, this is an error.
4367 if (!CurRec->getValues().empty() ||
4368 !CurRec->getDirectSuperClasses().empty() ||
4369 !CurRec->getTemplateArgs().empty())
4370 return TokError("Class '" + CurRec->getNameInitAsString() +
4371 "' already defined");
4372
4373 CurRec->updateClassLoc(Lex.getLoc());
4374 } else {
4375 // If this is the first reference to this class, create and add it.
4376 auto NewRec = std::make_unique<Record>(Lex.getCurStrVal(), Lex.getLoc(),
4377 Records, Record::RK_Class);
4378 CurRec = NewRec.get();
4379 Records.addClass(std::move(NewRec));
4380 }
4381
4382 if (TypeAliases.count(Name))
4383 return TokError("there is already a defined type alias '" + Name + "'");
4384
4385 Lex.Lex(); // eat the name.
4386
4387 // A class definition introduces a new scope.
4388 TGVarScope *ClassScope = PushScope(CurRec);
4389 // If there are template args, parse them.
4390 if (Lex.getCode() == tgtok::less)
4391 if (ParseTemplateArgList(CurRec))
4392 return true;
4393
4394 if (ParseObjectBody(CurRec))
4395 return true;
4396
4397 if (!NoWarnOnUnusedTemplateArgs)
4398 CurRec->checkUnusedTemplateArgs();
4399
4400 PopScope(ClassScope);
4401 return false;
4402}
4403
4404/// ParseLetList - Parse a non-empty list of assignment expressions into a list
4405/// of LetRecords.
4406///
4407/// LetList ::= LetItem (',' LetItem)*
4408/// LetItem ::= [append|prepend] ID OptionalRangeList '=' Value
4409///
4410void TGParser::ParseLetList(SmallVectorImpl<LetRecord> &Result) {
4411 do {
4412 if (Lex.getCode() != tgtok::Id) {
4413 TokError("expected identifier in let definition");
4414 Result.clear();
4415 return;
4416 }
4417
4418 auto [Mode, NameLoc, NameStr] = ParseLetModeAndName();
4419 const StringInit *Name = StringInit::get(Records, NameStr);
4420
4421 // Check for an optional RangeList.
4422 SmallVector<unsigned, 16> Bits;
4423 if (ParseOptionalRangeList(Bits)) {
4424 Result.clear();
4425 return;
4426 }
4427 std::reverse(Bits.begin(), Bits.end());
4428
4429 if (!consume(tgtok::equal)) {
4430 TokError("expected '=' in let expression");
4431 Result.clear();
4432 return;
4433 }
4434
4435 const Init *Val = ParseValue(nullptr);
4436 if (!Val) {
4437 Result.clear();
4438 return;
4439 }
4440
4441 // Now that we have everything, add the record.
4442 Result.emplace_back(Name, Bits, Val, NameLoc, Mode);
4443 } while (consume(tgtok::comma));
4444}
4445
4446/// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of
4447/// different related productions. This works inside multiclasses too.
4448///
4449/// Object ::= LET LetList IN '{' ObjectList '}'
4450/// Object ::= LET LetList IN Object
4451///
4452bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
4453 assert(Lex.getCode() == tgtok::Let && "Unexpected token");
4454 Lex.Lex();
4455
4456 // Add this entry to the let stack.
4458 ParseLetList(LetInfo);
4459 if (LetInfo.empty())
4460 return true;
4461 LetStack.push_back(std::move(LetInfo));
4462
4463 if (!consume(tgtok::In))
4464 return TokError("expected 'in' at end of top-level 'let'");
4465
4466 // If this is a scalar let, just handle it now
4467 if (Lex.getCode() != tgtok::l_brace) {
4468 // LET LetList IN Object
4469 if (ParseObject(CurMultiClass))
4470 return true;
4471 } else { // Object ::= LETCommand '{' ObjectList '}'
4472 SMLoc BraceLoc = Lex.getLoc();
4473 // Otherwise, this is a group let.
4474 Lex.Lex(); // eat the '{'.
4475
4476 // A group let introduces a new scope for local variables.
4477 TGVarScope *LetScope = PushScope();
4478
4479 // Parse the object list.
4480 if (ParseObjectList(CurMultiClass))
4481 return true;
4482
4483 if (!consume(tgtok::r_brace)) {
4484 TokError("expected '}' at end of top level let command");
4485 return Error(BraceLoc, "to match this '{'");
4486 }
4487
4488 PopScope(LetScope);
4489 }
4490
4491 // Outside this let scope, this let block is not active.
4492 LetStack.pop_back();
4493 return false;
4494}
4495
4496/// ParseMultiClass - Parse a multiclass definition.
4497///
4498/// MultiClassInst ::= MULTICLASS ID TemplateArgList?
4499/// ':' BaseMultiClassList '{' MultiClassObject+ '}'
4500/// MultiClassObject ::= Assert
4501/// MultiClassObject ::= DefInst
4502/// MultiClassObject ::= DefMInst
4503/// MultiClassObject ::= Defvar
4504/// MultiClassObject ::= Foreach
4505/// MultiClassObject ::= If
4506/// MultiClassObject ::= LETCommand '{' ObjectList '}'
4507/// MultiClassObject ::= LETCommand Object
4508///
4509bool TGParser::ParseMultiClass() {
4510 assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
4511 Lex.Lex(); // Eat the multiclass token.
4512
4513 if (Lex.getCode() != tgtok::Id)
4514 return TokError("expected identifier after multiclass for name");
4515 std::string Name = Lex.getCurStrVal();
4516
4517 auto Result = MultiClasses.try_emplace(
4518 Name, std::make_unique<MultiClass>(Name, Lex.getLoc(), Records));
4519
4520 if (!Result.second)
4521 return TokError("multiclass '" + Name + "' already defined");
4522
4523 CurMultiClass = Result.first->second.get();
4524 Lex.Lex(); // Eat the identifier.
4525
4526 // A multiclass body introduces a new scope for local variables.
4527 TGVarScope *MulticlassScope = PushScope(CurMultiClass);
4528
4529 // If there are template args, parse them.
4530 if (Lex.getCode() == tgtok::less)
4531 if (ParseTemplateArgList(nullptr))
4532 return true;
4533
4534 bool inherits = false;
4535
4536 // If there are submulticlasses, parse them.
4537 if (consume(tgtok::colon)) {
4538 inherits = true;
4539
4540 // Read all of the submulticlasses.
4541 SubMultiClassReference SubMultiClass =
4542 ParseSubMultiClassReference(CurMultiClass);
4543 while (true) {
4544 // Check for error.
4545 if (!SubMultiClass.MC)
4546 return true;
4547
4548 // Add it.
4549 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
4550 return true;
4551
4552 if (!consume(tgtok::comma))
4553 break;
4554 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
4555 }
4556 }
4557
4558 if (Lex.getCode() != tgtok::l_brace) {
4559 if (!inherits)
4560 return TokError("expected '{' in multiclass definition");
4561 if (!consume(tgtok::semi))
4562 return TokError("expected ';' in multiclass definition");
4563 } else {
4564 if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
4565 return TokError("multiclass must contain at least one def");
4566
4567 while (Lex.getCode() != tgtok::r_brace) {
4568 switch (Lex.getCode()) {
4569 default:
4570 return TokError("expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4571 "'foreach', 'if', or 'let' in multiclass body");
4572
4573 case tgtok::Assert:
4574 case tgtok::Def:
4575 case tgtok::Defm:
4576 case tgtok::Defvar:
4577 case tgtok::Dump:
4578 case tgtok::Foreach:
4579 case tgtok::If:
4580 case tgtok::Let:
4581 if (ParseObject(CurMultiClass))
4582 return true;
4583 break;
4584 }
4585 }
4586 Lex.Lex(); // eat the '}'.
4587
4588 // If we have a semicolon, print a gentle error.
4589 SMLoc SemiLoc = Lex.getLoc();
4590 if (consume(tgtok::semi)) {
4591 PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
4592 PrintNote("Semicolon ignored; remove to eliminate this error");
4593 }
4594 }
4595
4596 if (!NoWarnOnUnusedTemplateArgs)
4597 CurMultiClass->Rec.checkUnusedTemplateArgs();
4598
4599 PopScope(MulticlassScope);
4600 CurMultiClass = nullptr;
4601 return false;
4602}
4603
4604/// ParseDefm - Parse the instantiation of a multiclass.
4605///
4606/// DefMInst ::= DEFM ID ':' DefmSubClassRef ';'
4607///
4608bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
4609 assert(Lex.getCode() == tgtok::Defm && "Unexpected token!");
4610 Lex.Lex(); // eat the defm
4611
4612 const Init *DefmName = ParseObjectName(CurMultiClass);
4613 if (!DefmName)
4614 return true;
4615 if (isa<UnsetInit>(DefmName)) {
4616 DefmName = Records.getNewAnonymousName();
4617 if (CurMultiClass)
4618 DefmName = BinOpInit::getStrConcat(
4620 StringRecTy::get(Records)),
4621 DefmName);
4622 }
4623
4624 if (Lex.getCode() != tgtok::colon)
4625 return TokError("expected ':' after defm identifier");
4626
4627 // Keep track of the new generated record definitions.
4628 std::vector<RecordsEntry> NewEntries;
4629
4630 // This record also inherits from a regular class (non-multiclass)?
4631 bool InheritFromClass = false;
4632
4633 // eat the colon.
4634 Lex.Lex();
4635
4636 SMLoc SubClassLoc = Lex.getLoc();
4637 SubClassReference Ref = ParseSubClassReference(nullptr, true);
4638
4639 while (true) {
4640 if (!Ref.Rec)
4641 return true;
4642
4643 // To instantiate a multiclass, we get the multiclass and then loop
4644 // through its template argument names. Substs contains a substitution
4645 // value for each argument, either the value specified or the default.
4646 // Then we can resolve the template arguments.
4647 MultiClass *MC = MultiClasses[Ref.Rec->getName().str()].get();
4648 assert(MC && "Didn't lookup multiclass correctly?");
4649
4650 SubstStack Substs;
4651 if (resolveArgumentsOfMultiClass(Substs, MC, Ref.TemplateArgs, DefmName,
4652 SubClassLoc))
4653 return true;
4654
4655 if (resolve(MC->Entries, Substs, !CurMultiClass && Loops.empty(),
4656 &NewEntries, &SubClassLoc))
4657 return true;
4658
4659 if (!consume(tgtok::comma))
4660 break;
4661
4662 if (Lex.getCode() != tgtok::Id)
4663 return TokError("expected identifier");
4664
4665 SubClassLoc = Lex.getLoc();
4666
4667 // A defm can inherit from regular classes (non-multiclasses) as
4668 // long as they come in the end of the inheritance list.
4669 InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr);
4670
4671 if (InheritFromClass)
4672 break;
4673
4674 Ref = ParseSubClassReference(nullptr, true);
4675 }
4676
4677 if (InheritFromClass) {
4678 // Process all the classes to inherit as if they were part of a
4679 // regular 'def' and inherit all record values.
4680 SubClassReference SubClass = ParseSubClassReference(nullptr, false);
4681 while (true) {
4682 // Check for error.
4683 if (!SubClass.Rec)
4684 return true;
4685
4686 // Get the expanded definition prototypes and teach them about
4687 // the record values the current class to inherit has
4688 for (auto &E : NewEntries) {
4689 // Add it.
4690 if (AddSubClass(E, SubClass))
4691 return true;
4692 }
4693
4694 if (!consume(tgtok::comma))
4695 break;
4696 SubClass = ParseSubClassReference(nullptr, false);
4697 }
4698 }
4699
4700 for (auto &E : NewEntries) {
4701 if (ApplyLetStack(E))
4702 return true;
4703
4704 addEntry(std::move(E));
4705 }
4706
4707 if (!consume(tgtok::semi))
4708 return TokError("expected ';' at end of defm");
4709
4710 return false;
4711}
4712
4713/// ParseObject
4714/// Object ::= ClassInst
4715/// Object ::= DefInst
4716/// Object ::= MultiClassInst
4717/// Object ::= DefMInst
4718/// Object ::= LETCommand '{' ObjectList '}'
4719/// Object ::= LETCommand Object
4720/// Object ::= Defset
4721/// Object ::= Deftype
4722/// Object ::= Defvar
4723/// Object ::= Assert
4724/// Object ::= Dump
4725bool TGParser::ParseObject(MultiClass *MC) {
4726 switch (Lex.getCode()) {
4727 default:
4728 return TokError(
4729 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4730 case tgtok::Assert:
4731 return ParseAssert(MC);
4732 case tgtok::Def:
4733 return ParseDef(MC);
4734 case tgtok::Defm:
4735 return ParseDefm(MC);
4736 case tgtok::Deftype:
4737 return ParseDeftype();
4738 case tgtok::Defvar:
4739 return ParseDefvar();
4740 case tgtok::Dump:
4741 return ParseDump(MC);
4742 case tgtok::Foreach:
4743 return ParseForeach(MC);
4744 case tgtok::If:
4745 return ParseIf(MC);
4746 case tgtok::Let:
4747 return ParseTopLevelLet(MC);
4748 case tgtok::Defset:
4749 if (MC)
4750 return TokError("defset is not allowed inside multiclass");
4751 return ParseDefset();
4752 case tgtok::Class:
4753 if (MC)
4754 return TokError("class is not allowed inside multiclass");
4755 if (!Loops.empty())
4756 return TokError("class is not allowed inside foreach loop");
4757 return ParseClass();
4758 case tgtok::MultiClass:
4759 if (!Loops.empty())
4760 return TokError("multiclass is not allowed inside foreach loop");
4761 return ParseMultiClass();
4762 }
4763}
4764
4765/// ParseObjectList
4766/// ObjectList :== Object*
4767bool TGParser::ParseObjectList(MultiClass *MC) {
4768 while (tgtok::isObjectStart(Lex.getCode())) {
4769 if (ParseObject(MC))
4770 return true;
4771 }
4772 return false;
4773}
4774
4776 Lex.Lex(); // Prime the lexer.
4777 TGVarScope *GlobalScope = PushScope();
4778 if (ParseObjectList())
4779 return true;
4780 PopScope(GlobalScope);
4781
4782 // If we have unread input at the end of the file, report it.
4783 if (Lex.getCode() == tgtok::Eof)
4784 return false;
4785
4786 return TokError("Unexpected token at top level");
4787}
4788
4789// Check the types of the template argument values for a class
4790// inheritance, multiclass invocation, or anonymous class invocation.
4791// If necessary, replace an argument with a cast to the required type.
4792// The argument count has already been checked.
4793bool TGParser::CheckTemplateArgValues(
4795 const Record *ArgsRec) {
4796 assert(Values.size() == ValuesLocs.size() &&
4797 "expected as many values as locations");
4798
4799 ArrayRef<const Init *> TArgs = ArgsRec->getTemplateArgs();
4800
4801 bool HasError = false;
4802 for (auto [Value, Loc] : llvm::zip_equal(Values, ValuesLocs)) {
4803 const Init *ArgName = nullptr;
4804 if (Value->isPositional())
4805 ArgName = TArgs[Value->getIndex()];
4806 if (Value->isNamed())
4807 ArgName = Value->getName();
4808
4809 const RecordVal *Arg = ArgsRec->getValue(ArgName);
4810 const RecTy *ArgType = Arg->getType();
4811
4812 if (const auto *ArgValue = dyn_cast<TypedInit>(Value->getValue())) {
4813 auto *CastValue = ArgValue->getCastTo(ArgType);
4814 if (CastValue) {
4815 assert((!isa<TypedInit>(CastValue) ||
4816 cast<TypedInit>(CastValue)->getType()->typeIsA(ArgType)) &&
4817 "result of template arg value cast has wrong type");
4818 Value = Value->cloneWithValue(CastValue);
4819 } else {
4820 HasError |= Error(
4821 Loc, "Value specified for template argument '" +
4822 Arg->getNameInitAsString() + "' is of type " +
4823 ArgValue->getType()->getAsString() + "; expected type " +
4824 ArgType->getAsString() + ": " + ArgValue->getAsString());
4825 }
4826 }
4827 }
4828
4829 return HasError;
4830}
4831
4832#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4834 if (Loop)
4835 Loop->dump();
4836 if (Rec)
4837 Rec->dump();
4838}
4839
4841 errs() << "foreach " << IterVar->getAsString() << " = "
4842 << ListValue->getAsString() << " in {\n";
4843
4844 for (const auto &E : Entries)
4845 E.dump();
4846
4847 errs() << "}\n";
4848}
4849
4851 errs() << "Record:\n";
4852 Rec.dump();
4853
4854 errs() << "Defs:\n";
4855 for (const auto &E : Entries)
4856 E.dump();
4857}
4858#endif
4859
4860bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {
4861 // Location of the `dump` statement.
4862 SMLoc Loc = Lex.getLoc();
4863 assert(Lex.getCode() == tgtok::Dump && "Unknown tok");
4864 Lex.Lex(); // eat the operation
4865
4866 const Init *Message = ParseValue(CurRec);
4867 if (!Message)
4868 return true;
4869
4870 // Allow to use dump directly on `defvar` and `def`, by wrapping
4871 // them with a `!repl`.
4872 if (isa<DefInit>(Message))
4873 Message = UnOpInit::get(UnOpInit::REPR, Message, StringRecTy::get(Records))
4874 ->Fold(CurRec);
4875
4876 if (!consume(tgtok::semi))
4877 return TokError("expected ';'");
4878
4879 if (CurRec)
4880 CurRec->addDump(Loc, Message);
4881 else {
4882 HasReferenceResolver resolver{nullptr};
4883 resolver.setFinal(true);
4884 // force a resolution with a dummy resolver
4885 const Init *ResolvedMessage = Message->resolveReferences(resolver);
4886 addEntry(std::make_unique<Record::DumpInfo>(Loc, ResolvedMessage));
4887 }
4888
4889 return false;
4890}
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:569
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:860
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