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