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