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