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