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"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/ADT/StringSwitch.h"
19#include "llvm/ADT/Twine.h"
20#include "llvm/Config/llvm-config.h"
21#include "llvm/Support/Casting.h"
22#include "llvm/Support/Compiler.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/raw_ostream.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)
40 : Assertion(std::move(Assertion)) {}
41RecordsEntry::RecordsEntry(std::unique_ptr<Record::DumpInfo> Dump)
42 : Dump(std::move(Dump)) {}
43
44namespace llvm {
45struct SubClassReference {
46 SMRange RefRange;
47 const Record *Rec = nullptr;
48 SmallVector<const ArgumentInit *, 4> TemplateArgs;
49
50 SubClassReference() = default;
51
52 bool isInvalid() const { return Rec == nullptr; }
53};
54
55struct SubMultiClassReference {
56 SMRange RefRange;
57 MultiClass *MC = nullptr;
58 SmallVector<const ArgumentInit *, 4> TemplateArgs;
59
60 SubMultiClassReference() = default;
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)
68LLVM_DUMP_METHOD void SubMultiClassReference::dump() const {
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>(Val: RV.getValue());
81 for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
82 const Init *Bit = BV->getBit(Bit: i);
83 bool IsReference = false;
84 if (const auto *VBI = dyn_cast<VarBitInit>(Val: Bit)) {
85 if (const auto *VI = dyn_cast<VarInit>(Val: VBI->getBitVar())) {
86 if (R.getValue(Name: VI->getName()))
87 IsReference = true;
88 }
89 } else if (isa<VarInit>(Val: 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>(Val: V) ? checkBitsConcrete(R, RV) : V->isConcrete();
109 if (!Ok) {
110 PrintError(ErrorLoc: R.getLoc(), Msg: 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 lhs: CurRec.getNameInit(),
126 rhs: StringInit::get(RK, CurRec.isMultiClass() ? "::" : ":"));
127 NewName = BinOpInit::getStrConcat(lhs: NewName, rhs: Name);
128
129 if (const auto *BinOp = dyn_cast<BinOpInit>(Val: NewName))
130 NewName = BinOp->Fold(CurRec: &CurRec);
131 return NewName;
132}
133
134static const Init *QualifyName(MultiClass *MC, const Init *Name) {
135 return QualifyName(CurRec: 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(CurRec: Rec, Name: StringInit::get(RK&: Rec.getRecords(), "NAME"));
141}
142
143static const Init *QualifiedNameOfImplicitName(MultiClass *MC) {
144 return QualifiedNameOfImplicitName(Rec: MC->Rec);
145}
146
147const Init *TGVarScope::getVar(RecordKeeper &Records,
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(x: 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(CurRec: *Rec, Name);
161 if (Rec->isTemplateArg(Name: ArgName)) {
162 RecordVal *RV = Rec->getValue(Name: ArgName);
163 assert(RV && "Template arg doesn't exist??");
164 RV->setUsed(true);
165 if (TrackReferenceLocs)
166 RV->addReferenceLoc(Loc: NameLoc);
167 return VarInit::get(VN: ArgName, T: RV->getType());
168 }
169 return Name->getValue() == "NAME"
170 ? VarInit::get(VN: ArgName, T: StringRecTy::get(RK&: Records))
171 : nullptr;
172 };
173
174 // If not found, we try to find the variable in additional variables like
175 // arguments, loop iterator, etc.
176 switch (Kind) {
177 case SK_Local:
178 break; /* do nothing. */
179 case SK_Record: {
180 if (CurRec) {
181 // The variable is a record field?
182 if (RecordVal *RV = CurRec->getValue(Name)) {
183 if (TrackReferenceLocs)
184 RV->addReferenceLoc(Loc: NameLoc);
185 return VarInit::get(VN: Name, T: RV->getType());
186 }
187
188 // The variable is a class template argument?
189 if (CurRec->isClass())
190 if (auto *V = FindValueInArgs(CurRec, Name))
191 return V;
192 }
193 break;
194 }
195 case SK_ForeachLoop: {
196 // The variable is a loop iterator?
197 if (CurLoop->IterVar) {
198 const VarInit *IterVar = CurLoop->IterVar;
199 if (IterVar->getNameInit() == Name)
200 return IterVar;
201 }
202 break;
203 }
204 case SK_MultiClass: {
205 // The variable is a multiclass template argument?
206 if (CurMultiClass)
207 if (auto *V = FindValueInArgs(&CurMultiClass->Rec, Name))
208 return V;
209 break;
210 }
211 }
212
213 // Then, we try to find the name in parent scope.
214 if (Parent)
215 return Parent->getVar(Records, ParsingMultiClass, Name, NameLoc,
216 TrackReferenceLocs);
217
218 return nullptr;
219}
220
221bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) {
222 if (!CurRec)
223 CurRec = &CurMultiClass->Rec;
224
225 if (RecordVal *ERV = CurRec->getValue(Name: RV.getNameInit())) {
226 // The value already exists in the class, treat this as a set.
227 if (ERV->setValue(RV.getValue()))
228 return Error(L: Loc, Msg: "New definition of '" + RV.getName() + "' of type '" +
229 RV.getType()->getAsString() +
230 "' is incompatible with " +
231 "previous definition of type '" +
232 ERV->getType()->getAsString() + "'");
233 } else {
234 CurRec->addValue(RV);
235 }
236 return false;
237}
238
239/// SetValue -
240/// Return true on error, false on success.
241bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const Init *ValName,
242 ArrayRef<unsigned> BitList, const Init *V,
243 bool AllowSelfAssignment, bool OverrideDefLoc,
244 LetMode Mode) {
245 if (!V)
246 return false;
247
248 if (!CurRec)
249 CurRec = &CurMultiClass->Rec;
250
251 RecordVal *RV = CurRec->getValue(Name: ValName);
252 if (!RV)
253 return Error(L: Loc,
254 Msg: "Value '" + ValName->getAsUnquotedString() + "' unknown!");
255
256 // Handle append/prepend by concatenating with the current value.
257 if (Mode != LetMode::Replace) {
258 assert(Mode == LetMode::Append || Mode == LetMode::Prepend);
259
260 if (!BitList.empty())
261 return Error(L: Loc, Msg: "Cannot use append/prepend with bit range");
262
263 const Init *CurrentValue = RV->getValue();
264 const RecTy *FieldType = RV->getType();
265
266 // If the current value is unset, just assign the new value directly.
267 if (!isa<UnsetInit>(Val: CurrentValue)) {
268 const bool IsAppendMode = Mode == LetMode::Append;
269
270 const Init *LHS = IsAppendMode ? CurrentValue : V;
271 const Init *RHS = IsAppendMode ? V : CurrentValue;
272
273 BinOpInit::BinaryOp ConcatOp;
274 if (isa<ListRecTy>(Val: FieldType))
275 ConcatOp = BinOpInit::LISTCONCAT;
276 else if (isa<StringRecTy>(Val: FieldType))
277 ConcatOp = BinOpInit::STRCONCAT;
278 else if (isa<DagRecTy>(Val: FieldType))
279 ConcatOp = BinOpInit::CONCAT;
280 else
281 return Error(L: Loc, Msg: Twine("Cannot ") +
282 (IsAppendMode ? "append to" : "prepend to") +
283 " field '" + ValName->getAsUnquotedString() +
284 "' of type '" + FieldType->getAsString() +
285 "' (expected list, string, code, or dag)");
286
287 V = BinOpInit::get(opc: ConcatOp, lhs: LHS, rhs: RHS, Type: FieldType)->Fold(CurRec);
288 }
289 }
290
291 // Do not allow assignments like 'X = X'. This will just cause infinite loops
292 // in the resolution machinery.
293 if (BitList.empty())
294 if (const auto *VI = dyn_cast<VarInit>(Val: V))
295 if (VI->getNameInit() == ValName && !AllowSelfAssignment)
296 return Error(L: Loc, Msg: "Recursion / self-assignment forbidden");
297
298 // If we are assigning to a subset of the bits in the value we must be
299 // assigning to a field of BitsRecTy, which must have a BitsInit initializer.
300 if (!BitList.empty()) {
301 const auto *CurVal = dyn_cast<BitsInit>(Val: RV->getValue());
302 if (!CurVal)
303 return Error(L: Loc, Msg: "Value '" + ValName->getAsUnquotedString() +
304 "' is not a bits type");
305
306 // Convert the incoming value to a bits type of the appropriate size...
307 const Init *BI = V->getCastTo(Ty: BitsRecTy::get(RK&: Records, Sz: BitList.size()));
308 if (!BI)
309 return Error(L: Loc, Msg: "Initializer is not compatible with bit range");
310
311 SmallVector<const Init *, 16> NewBits(CurVal->getNumBits());
312
313 // Loop over bits, assigning values as appropriate.
314 for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
315 unsigned Bit = BitList[i];
316 if (NewBits[Bit])
317 return Error(L: Loc, Msg: "Cannot set bit #" + Twine(Bit) + " of value '" +
318 ValName->getAsUnquotedString() +
319 "' more than once");
320 NewBits[Bit] = BI->getBit(Bit: i);
321 }
322
323 for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
324 if (!NewBits[i])
325 NewBits[i] = CurVal->getBit(Bit: i);
326
327 V = BitsInit::get(RK&: Records, Range: NewBits);
328 }
329
330 if (OverrideDefLoc ? RV->setValue(V, NewLoc: Loc) : RV->setValue(V)) {
331 std::string InitType;
332 if (const auto *BI = dyn_cast<BitsInit>(Val: V))
333 InitType = (Twine("' of type bit initializer with length ") +
334 Twine(BI->getNumBits()))
335 .str();
336 else if (const auto *TI = dyn_cast<TypedInit>(Val: V))
337 InitType =
338 (Twine("' of type '") + TI->getType()->getAsString() + "'").str();
339
340 return Error(L: Loc, Msg: "Field '" + ValName->getAsUnquotedString() +
341 "' of type '" + RV->getType()->getAsString() +
342 "' is incompatible with value '" + V->getAsString() +
343 InitType);
344 }
345 return false;
346}
347
348/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template
349/// args as SubClass's template arguments.
350bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
351 const Record *SC = SubClass.Rec;
352 MapResolver R(CurRec);
353
354 // Loop over all the subclass record's fields. Add regular fields to the new
355 // record.
356 for (const RecordVal &Field : SC->getValues())
357 if (!Field.isTemplateArg())
358 if (AddValue(CurRec, Loc: SubClass.RefRange.Start, RV: Field))
359 return true;
360
361 if (resolveArgumentsOfClass(R, Rec: SC, ArgValues: SubClass.TemplateArgs,
362 Loc: SubClass.RefRange.Start))
363 return true;
364
365 // Copy the subclass record's assertions to the new record.
366 CurRec->appendAssertions(Rec: SC);
367
368 // Copy the subclass record's dumps to the new record.
369 CurRec->appendDumps(Rec: SC);
370
371 const Init *Name;
372 if (CurRec->isClass())
373 Name = VarInit::get(VN: QualifiedNameOfImplicitName(Rec: *CurRec),
374 T: StringRecTy::get(RK&: Records));
375 else
376 Name = CurRec->getNameInit();
377 R.set(Key: QualifiedNameOfImplicitName(Rec: *SC), Value: Name);
378
379 CurRec->resolveReferences(R);
380
381 // Since everything went well, we can now set the "superclass" list for the
382 // current record.
383 if (CurRec->isSubClassOf(R: SC))
384 return Error(L: SubClass.RefRange.Start,
385 Msg: "Already subclass of '" + SC->getName() + "'!\n");
386 CurRec->addDirectSuperClass(R: SC, Range: SubClass.RefRange);
387 return false;
388}
389
390bool TGParser::AddSubClass(RecordsEntry &Entry, SubClassReference &SubClass) {
391 if (Entry.Rec)
392 return AddSubClass(CurRec: Entry.Rec.get(), SubClass);
393
394 if (Entry.Assertion)
395 return false;
396
397 for (auto &E : Entry.Loop->Entries) {
398 if (AddSubClass(Entry&: E, SubClass))
399 return true;
400 }
401
402 return false;
403}
404
405/// AddSubMultiClass - Add SubMultiClass as a subclass to
406/// CurMC, resolving its template args as SubMultiClass's
407/// template arguments.
408bool TGParser::AddSubMultiClass(MultiClass *CurMC,
409 SubMultiClassReference &SubMultiClass) {
410 MultiClass *SMC = SubMultiClass.MC;
411
412 SubstStack Substs;
413 if (resolveArgumentsOfMultiClass(
414 Substs, MC: SMC, ArgValues: SubMultiClass.TemplateArgs,
415 DefmName: VarInit::get(VN: QualifiedNameOfImplicitName(MC: CurMC),
416 T: StringRecTy::get(RK&: Records)),
417 Loc: SubMultiClass.RefRange.Start))
418 return true;
419
420 // Add all of the defs in the subclass into the current multiclass.
421 return resolve(Source: SMC->Entries, Substs, Final: false, Dest: &CurMC->Entries);
422}
423
424/// Add a record, foreach loop, or assertion to the current context.
425bool TGParser::addEntry(RecordsEntry E) {
426 assert((!!E.Rec + !!E.Loop + !!E.Assertion + !!E.Dump) == 1 &&
427 "RecordsEntry has invalid number of items");
428
429 // If we are parsing a loop, add it to the loop's entries.
430 if (!Loops.empty()) {
431 Loops.back()->Entries.push_back(x: std::move(E));
432 return false;
433 }
434
435 // If it is a loop, then resolve and perform the loop.
436 if (E.Loop) {
437 SubstStack Stack;
438 return resolve(Loop: *E.Loop, Stack, Final: CurMultiClass == nullptr,
439 Dest: CurMultiClass ? &CurMultiClass->Entries : nullptr);
440 }
441
442 // If we are parsing a multiclass, add it to the multiclass's entries.
443 if (CurMultiClass) {
444 CurMultiClass->Entries.push_back(x: std::move(E));
445 return false;
446 }
447
448 // If it is an assertion, then it's a top-level one, so check it.
449 if (E.Assertion) {
450 CheckAssert(Loc: E.Assertion->Loc, Condition: E.Assertion->Condition, Message: E.Assertion->Message);
451 return false;
452 }
453
454 if (E.Dump) {
455 dumpMessage(Loc: E.Dump->Loc, Message: E.Dump->Message);
456 return false;
457 }
458
459 // It must be a record, so finish it off.
460 return addDefOne(Rec: std::move(E.Rec));
461}
462
463/// Resolve the entries in \p Loop, going over inner loops recursively
464/// and making the given subsitutions of (name, value) pairs.
465///
466/// The resulting records are stored in \p Dest if non-null. Otherwise, they
467/// are added to the global record keeper.
468bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs, bool Final,
469 std::vector<RecordsEntry> *Dest, SMLoc *Loc) {
470
471 MapResolver R;
472 for (const auto &S : Substs)
473 R.set(Key: S.first, Value: S.second);
474 const Init *List = Loop.ListValue->resolveReferences(R);
475
476 // For if-then-else blocks, we lower to a foreach loop whose list is a
477 // ternary selection between lists of different length. Since we don't
478 // have a means to track variable length record lists, we *must* resolve
479 // the condition here. We want to defer final resolution of the arms
480 // until the resulting records are finalized.
481 // e.g. !if(!exists<SchedWrite>("__does_not_exist__"), [1], [])
482 if (const auto *TI = dyn_cast<TernOpInit>(Val: List);
483 TI && TI->getOpcode() == TernOpInit::IF && Final) {
484 const Init *OldLHS = TI->getLHS();
485 R.setFinal(true);
486 const Init *LHS = OldLHS->resolveReferences(R);
487 if (LHS == OldLHS) {
488 PrintError(ErrorLoc: Loop.Loc, Msg: Twine("unable to resolve if condition '") +
489 LHS->getAsString() +
490 "' at end of containing scope");
491 return true;
492 }
493 const Init *MHS = TI->getMHS();
494 const Init *RHS = TI->getRHS();
495 List = TernOpInit::get(opc: TernOpInit::IF, lhs: LHS, mhs: MHS, rhs: RHS, Type: TI->getType())
496 ->Fold(CurRec: nullptr);
497 }
498
499 const auto *LI = dyn_cast<ListInit>(Val: List);
500 if (!LI) {
501 if (!Final) {
502 Dest->emplace_back(
503 args: std::make_unique<ForeachLoop>(args: Loop.Loc, args: Loop.IterVar, args&: List));
504 return resolve(Source: Loop.Entries, Substs, Final, Dest: &Dest->back().Loop->Entries,
505 Loc);
506 }
507
508 PrintError(ErrorLoc: Loop.Loc, Msg: Twine("attempting to loop over '") +
509 List->getAsString() + "', expected a list");
510 return true;
511 }
512
513 bool Error = false;
514 for (auto *Elt : *LI) {
515 if (Loop.IterVar)
516 Substs.emplace_back(Args: Loop.IterVar->getNameInit(), Args&: Elt);
517 Error = resolve(Source: Loop.Entries, Substs, Final, Dest);
518 if (Loop.IterVar)
519 Substs.pop_back();
520 if (Error)
521 break;
522 }
523 return Error;
524}
525
526/// Resolve the entries in \p Source, going over loops recursively and
527/// making the given substitutions of (name, value) pairs.
528///
529/// The resulting records are stored in \p Dest if non-null. Otherwise, they
530/// are added to the global record keeper.
531bool TGParser::resolve(const std::vector<RecordsEntry> &Source,
532 SubstStack &Substs, bool Final,
533 std::vector<RecordsEntry> *Dest, SMLoc *Loc) {
534 bool Error = false;
535 for (auto &E : Source) {
536 if (E.Loop) {
537 Error = resolve(Loop: *E.Loop, Substs, Final, Dest);
538
539 } else if (E.Assertion) {
540 MapResolver R;
541 for (const auto &S : Substs)
542 R.set(Key: S.first, Value: S.second);
543 const Init *Condition = E.Assertion->Condition->resolveReferences(R);
544 const Init *Message = E.Assertion->Message->resolveReferences(R);
545
546 if (Dest)
547 Dest->push_back(x: std::make_unique<Record::AssertionInfo>(
548 args&: E.Assertion->Loc, args&: Condition, args&: Message));
549 else
550 CheckAssert(Loc: E.Assertion->Loc, Condition, Message);
551
552 } else if (E.Dump) {
553 MapResolver R;
554 for (const auto &S : Substs)
555 R.set(Key: S.first, Value: S.second);
556 const Init *Message = E.Dump->Message->resolveReferences(R);
557
558 if (Dest)
559 Dest->push_back(
560 x: std::make_unique<Record::DumpInfo>(args&: E.Dump->Loc, args&: Message));
561 else
562 dumpMessage(Loc: E.Dump->Loc, Message);
563
564 } else {
565 auto Rec = std::make_unique<Record>(args&: *E.Rec);
566 if (Loc)
567 Rec->appendLoc(Loc: *Loc);
568
569 MapResolver R(Rec.get());
570 for (const auto &S : Substs)
571 R.set(Key: S.first, Value: S.second);
572 Rec->resolveReferences(R);
573
574 if (Dest)
575 Dest->push_back(x: std::move(Rec));
576 else
577 Error = addDefOne(Rec: std::move(Rec));
578 }
579 if (Error)
580 break;
581 }
582 return Error;
583}
584
585/// Resolve the record fully and add it to the record keeper.
586bool TGParser::addDefOne(std::unique_ptr<Record> Rec) {
587 const Init *NewName = nullptr;
588 if (const Record *Prev = Records.getDef(Name: Rec->getNameInitAsString())) {
589 if (!Rec->isAnonymous()) {
590 PrintError(ErrorLoc: Rec->getLoc(),
591 Msg: "def already exists: " + Rec->getNameInitAsString());
592 PrintNote(NoteLoc: Prev->getLoc(), Msg: "location of previous definition");
593 return true;
594 }
595 NewName = Records.getNewAnonymousName();
596 }
597
598 Rec->resolveReferences(NewName);
599 checkConcrete(R&: *Rec);
600
601 if (!isa<StringInit>(Val: Rec->getNameInit())) {
602 PrintError(ErrorLoc: Rec->getLoc(), Msg: Twine("record name '") +
603 Rec->getNameInit()->getAsString() +
604 "' could not be fully resolved");
605 return true;
606 }
607
608 // Check the assertions.
609 Rec->checkRecordAssertions();
610
611 // Run the dumps.
612 Rec->emitRecordDumps();
613
614 // If ObjectBody has template arguments, it's an error.
615 assert(Rec->getTemplateArgs().empty() && "How'd this get template args?");
616
617 for (DefsetRecord *Defset : Defsets) {
618 DefInit *I = Rec->getDefInit();
619 if (!I->getType()->typeIsA(RHS: Defset->EltTy)) {
620 PrintError(ErrorLoc: Rec->getLoc(), Msg: Twine("adding record of incompatible type '") +
621 I->getType()->getAsString() +
622 "' to defset");
623 PrintNote(NoteLoc: Defset->Loc, Msg: "location of defset declaration");
624 return true;
625 }
626 Defset->Elements.push_back(Elt: I);
627 }
628
629 Records.addDef(R: std::move(Rec));
630 return false;
631}
632
633bool TGParser::resolveArguments(const Record *Rec,
634 ArrayRef<const ArgumentInit *> ArgValues,
635 SMLoc Loc, ArgValueHandler ArgValueHandler) {
636 ArrayRef<const Init *> ArgNames = Rec->getTemplateArgs();
637 assert(ArgValues.size() <= ArgNames.size() &&
638 "Too many template arguments allowed");
639
640 // Loop over the template arguments and handle the (name, value) pair.
641 SmallVector<const Init *, 2> UnsolvedArgNames(ArgNames);
642 for (auto *Arg : ArgValues) {
643 const Init *ArgName = nullptr;
644 const Init *ArgValue = Arg->getValue();
645 if (Arg->isPositional())
646 ArgName = ArgNames[Arg->getIndex()];
647 if (Arg->isNamed())
648 ArgName = Arg->getName();
649
650 // We can only specify the template argument once.
651 if (!is_contained(Range&: UnsolvedArgNames, Element: ArgName))
652 return Error(L: Loc, Msg: "We can only specify the template argument '" +
653 ArgName->getAsUnquotedString() + "' once");
654
655 ArgValueHandler(ArgName, ArgValue);
656 llvm::erase(C&: UnsolvedArgNames, V: ArgName);
657 }
658
659 // For unsolved arguments, if there is no default value, complain.
660 for (auto *UnsolvedArgName : UnsolvedArgNames) {
661 const Init *Default = Rec->getValue(Name: UnsolvedArgName)->getValue();
662 if (!Default->isComplete()) {
663 std::string Name = UnsolvedArgName->getAsUnquotedString();
664 Error(L: Loc, Msg: "value not specified for template argument '" + Name + "'");
665 PrintNote(NoteLoc: Rec->getFieldLoc(FieldName: Name),
666 Msg: "declared in '" + Rec->getNameInitAsString() + "'");
667 return true;
668 }
669 ArgValueHandler(UnsolvedArgName, Default);
670 }
671
672 return false;
673}
674
675/// Resolve the arguments of class and set them to MapResolver.
676/// Returns true if failed.
677bool TGParser::resolveArgumentsOfClass(MapResolver &R, const Record *Rec,
678 ArrayRef<const ArgumentInit *> ArgValues,
679 SMLoc Loc) {
680 return resolveArguments(
681 Rec, ArgValues, Loc,
682 ArgValueHandler: [&](const Init *Name, const Init *Value) { R.set(Key: Name, Value); });
683}
684
685/// Resolve the arguments of multiclass and store them into SubstStack.
686/// Returns true if failed.
687bool TGParser::resolveArgumentsOfMultiClass(
688 SubstStack &Substs, MultiClass *MC,
689 ArrayRef<const ArgumentInit *> ArgValues, const Init *DefmName, SMLoc Loc) {
690 // Add an implicit argument NAME.
691 Substs.emplace_back(Args: QualifiedNameOfImplicitName(MC), Args&: DefmName);
692 return resolveArguments(Rec: &MC->Rec, ArgValues, Loc,
693 ArgValueHandler: [&](const Init *Name, const Init *Value) {
694 Substs.emplace_back(Args&: Name, Args&: Value);
695 });
696}
697
698//===----------------------------------------------------------------------===//
699// Parser Code
700//===----------------------------------------------------------------------===//
701
702bool TGParser::consume(tgtok::TokKind K) {
703 if (Lex.getCode() == K) {
704 Lex.Lex();
705 return true;
706 }
707 return false;
708}
709
710/// ParseObjectName - If a valid object name is specified, return it. If no
711/// name is specified, return the unset initializer. Return nullptr on parse
712/// error.
713/// ObjectName ::= Value [ '#' Value ]*
714/// ObjectName ::= /*empty*/
715///
716const Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
717 switch (Lex.getCode()) {
718 case tgtok::colon:
719 case tgtok::semi:
720 case tgtok::l_brace:
721 // These are all of the tokens that can begin an object body.
722 // Some of these can also begin values but we disallow those cases
723 // because they are unlikely to be useful.
724 return UnsetInit::get(RK&: Records);
725 default:
726 break;
727 }
728
729 Record *CurRec = nullptr;
730 if (CurMultiClass)
731 CurRec = &CurMultiClass->Rec;
732
733 const Init *Name =
734 ParseValue(CurRec, ItemType: StringRecTy::get(RK&: Records), Mode: ParseNameMode);
735 if (!Name)
736 return nullptr;
737
738 if (CurMultiClass) {
739 const Init *NameStr = QualifiedNameOfImplicitName(MC: CurMultiClass);
740 HasReferenceResolver R(NameStr);
741 Name->resolveReferences(R);
742 if (!R.found())
743 Name = BinOpInit::getStrConcat(
744 lhs: VarInit::get(VN: NameStr, T: StringRecTy::get(RK&: Records)), rhs: Name);
745 }
746
747 return Name;
748}
749
750/// ParseClassID - Parse and resolve a reference to a class name. This returns
751/// null on error.
752///
753/// ClassID ::= ID
754///
755const Record *TGParser::ParseClassID() {
756 if (Lex.getCode() != tgtok::Id) {
757 TokError(Msg: "expected name for ClassID");
758 return nullptr;
759 }
760
761 const Record *Result = Records.getClass(Name: Lex.getCurStrVal());
762 if (!Result) {
763 std::string Msg("Couldn't find class '" + Lex.getCurStrVal() + "'");
764 if (MultiClasses[Lex.getCurStrVal()].get())
765 TokError(Msg: Msg + ". Use 'defm' if you meant to use multiclass '" +
766 Lex.getCurStrVal() + "'");
767 else
768 TokError(Msg);
769 } else if (TrackReferenceLocs) {
770 Result->appendReferenceLoc(Loc: Lex.getLocRange());
771 }
772
773 Lex.Lex();
774 return Result;
775}
776
777/// ParseMultiClassID - Parse and resolve a reference to a multiclass name.
778/// This returns null on error.
779///
780/// MultiClassID ::= ID
781///
782MultiClass *TGParser::ParseMultiClassID() {
783 if (Lex.getCode() != tgtok::Id) {
784 TokError(Msg: "expected name for MultiClassID");
785 return nullptr;
786 }
787
788 MultiClass *Result = MultiClasses[Lex.getCurStrVal()].get();
789 if (!Result)
790 TokError(Msg: "Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
791
792 Lex.Lex();
793 return Result;
794}
795
796/// ParseSubClassReference - Parse a reference to a subclass or a
797/// multiclass. This returns a SubClassRefTy with a null Record* on error.
798///
799/// SubClassRef ::= ClassID
800/// SubClassRef ::= ClassID '<' ArgValueList '>'
801///
802SubClassReference TGParser::ParseSubClassReference(Record *CurRec,
803 bool isDefm) {
804 SubClassReference Result;
805 Result.RefRange.Start = Lex.getLoc();
806
807 if (isDefm) {
808 if (MultiClass *MC = ParseMultiClassID())
809 Result.Rec = &MC->Rec;
810 } else {
811 Result.Rec = ParseClassID();
812 }
813 if (!Result.Rec)
814 return Result;
815
816 // If there is no template arg list, we're done.
817 if (!consume(K: tgtok::less)) {
818 Result.RefRange.End = Lex.getLoc();
819 return Result;
820 }
821
822 SmallVector<SMLoc> ArgLocs;
823 if (ParseTemplateArgValueList(Result&: Result.TemplateArgs, ArgLocs, CurRec,
824 ArgsRec: Result.Rec)) {
825 Result.Rec = nullptr; // Error parsing value list.
826 return Result;
827 }
828
829 if (CheckTemplateArgValues(Values&: Result.TemplateArgs, ValuesLocs: ArgLocs, ArgsRec: Result.Rec)) {
830 Result.Rec = nullptr; // Error checking value list.
831 return Result;
832 }
833
834 Result.RefRange.End = Lex.getLoc();
835 return Result;
836}
837
838/// ParseSubMultiClassReference - Parse a reference to a subclass or to a
839/// templated submulticlass. This returns a SubMultiClassRefTy with a null
840/// Record* on error.
841///
842/// SubMultiClassRef ::= MultiClassID
843/// SubMultiClassRef ::= MultiClassID '<' ArgValueList '>'
844///
845SubMultiClassReference
846TGParser::ParseSubMultiClassReference(MultiClass *CurMC) {
847 SubMultiClassReference Result;
848 Result.RefRange.Start = Lex.getLoc();
849
850 Result.MC = ParseMultiClassID();
851 if (!Result.MC)
852 return Result;
853
854 // If there is no template arg list, we're done.
855 if (!consume(K: tgtok::less)) {
856 Result.RefRange.End = Lex.getLoc();
857 return Result;
858 }
859
860 SmallVector<SMLoc> ArgLocs;
861 if (ParseTemplateArgValueList(Result&: Result.TemplateArgs, ArgLocs, CurRec: &CurMC->Rec,
862 ArgsRec: &Result.MC->Rec)) {
863 Result.MC = nullptr; // Error parsing value list.
864 return Result;
865 }
866
867 if (CheckTemplateArgValues(Values&: Result.TemplateArgs, ValuesLocs: ArgLocs, ArgsRec: &Result.MC->Rec)) {
868 Result.MC = nullptr; // Error checking value list.
869 return Result;
870 }
871
872 Result.RefRange.End = Lex.getLoc();
873
874 return Result;
875}
876
877/// ParseSliceElement - Parse subscript or range
878///
879/// SliceElement ::= Value<list<int>>
880/// SliceElement ::= Value<int>
881/// SliceElement ::= Value<int> '...' Value<int>
882/// SliceElement ::= Value<int> '-' Value<int> (deprecated)
883/// SliceElement ::= Value<int> INTVAL(Negative; deprecated)
884///
885/// SliceElement is either IntRecTy, ListRecTy, or nullptr
886///
887const TypedInit *TGParser::ParseSliceElement(Record *CurRec) {
888 auto LHSLoc = Lex.getLoc();
889 auto *CurVal = ParseValue(CurRec);
890 if (!CurVal)
891 return nullptr;
892 const auto *LHS = cast<TypedInit>(Val: CurVal);
893
894 const TypedInit *RHS = nullptr;
895 switch (Lex.getCode()) {
896 case tgtok::dotdotdot:
897 case tgtok::minus: { // Deprecated
898 Lex.Lex(); // eat
899 auto RHSLoc = Lex.getLoc();
900 CurVal = ParseValue(CurRec);
901 if (!CurVal)
902 return nullptr;
903 RHS = cast<TypedInit>(Val: CurVal);
904 if (!isa<IntRecTy>(Val: RHS->getType())) {
905 Error(L: RHSLoc,
906 Msg: "expected int...int, got " + Twine(RHS->getType()->getAsString()));
907 return nullptr;
908 }
909 break;
910 }
911 case tgtok::IntVal: { // Deprecated "-num"
912 auto i = -Lex.getCurIntVal();
913 if (i < 0) {
914 TokError(Msg: "invalid range, cannot be negative");
915 return nullptr;
916 }
917 RHS = IntInit::get(RK&: Records, V: i);
918 Lex.Lex(); // eat IntVal
919 break;
920 }
921 default: // Single value (IntRecTy or ListRecTy)
922 return LHS;
923 }
924
925 assert(RHS);
926 assert(isa<IntRecTy>(RHS->getType()));
927
928 // Closed-interval range <LHS:IntRecTy>...<RHS:IntRecTy>
929 if (!isa<IntRecTy>(Val: LHS->getType())) {
930 Error(L: LHSLoc,
931 Msg: "expected int...int, got " + Twine(LHS->getType()->getAsString()));
932 return nullptr;
933 }
934
935 return cast<TypedInit>(Val: BinOpInit::get(opc: BinOpInit::RANGEC, lhs: LHS, rhs: RHS,
936 Type: IntRecTy::get(RK&: Records)->getListTy())
937 ->Fold(CurRec));
938}
939
940/// ParseSliceElements - Parse subscripts in square brackets.
941///
942/// SliceElements ::= ( SliceElement ',' )* SliceElement ','?
943///
944/// SliceElement is either IntRecTy, ListRecTy, or nullptr
945///
946/// Returns ListRecTy by defaut.
947/// Returns IntRecTy if;
948/// - Single=true
949/// - SliceElements is Value<int> w/o trailing comma
950///
951const TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
952 const TypedInit *CurVal;
953 SmallVector<const Init *, 2> Elems; // int
954 SmallVector<const TypedInit *, 2> Slices; // list<int>
955
956 auto FlushElems = [&] {
957 if (!Elems.empty()) {
958 Slices.push_back(Elt: ListInit::get(Range: Elems, EltTy: IntRecTy::get(RK&: Records)));
959 Elems.clear();
960 }
961 };
962
963 do {
964 auto LHSLoc = Lex.getLoc();
965 CurVal = ParseSliceElement(CurRec);
966 if (!CurVal)
967 return nullptr;
968 auto *CurValTy = CurVal->getType();
969
970 if (const auto *ListValTy = dyn_cast<ListRecTy>(Val: CurValTy)) {
971 if (!isa<IntRecTy>(Val: ListValTy->getElementType())) {
972 Error(L: LHSLoc,
973 Msg: "expected list<int>, got " + Twine(ListValTy->getAsString()));
974 return nullptr;
975 }
976
977 FlushElems();
978 Slices.push_back(Elt: CurVal);
979 Single = false;
980 CurVal = nullptr;
981 } else if (!isa<IntRecTy>(Val: CurValTy)) {
982 Error(L: LHSLoc,
983 Msg: "unhandled type " + Twine(CurValTy->getAsString()) + " in range");
984 return nullptr;
985 }
986
987 if (Lex.getCode() != tgtok::comma)
988 break;
989
990 Lex.Lex(); // eat comma
991
992 // `[i,]` is not LISTELEM but LISTSLICE
993 Single = false;
994 if (CurVal)
995 Elems.push_back(Elt: CurVal);
996 CurVal = nullptr;
997 } while (Lex.getCode() != tgtok::r_square);
998
999 if (CurVal) {
1000 // LISTELEM
1001 if (Single)
1002 return CurVal;
1003
1004 Elems.push_back(Elt: CurVal);
1005 }
1006
1007 FlushElems();
1008
1009 // Concatenate lists in Slices
1010 const TypedInit *Result = nullptr;
1011 for (auto *Slice : Slices) {
1012 Result = (Result ? cast<TypedInit>(Val: BinOpInit::getListConcat(lhs: Result, rhs: Slice))
1013 : Slice);
1014 }
1015
1016 return Result;
1017}
1018
1019/// ParseRangePiece - Parse a bit/value range.
1020/// RangePiece ::= INTVAL
1021/// RangePiece ::= INTVAL '...' INTVAL
1022/// RangePiece ::= INTVAL '-' INTVAL
1023/// RangePiece ::= INTVAL INTVAL
1024// The last two forms are deprecated.
1025bool TGParser::ParseRangePiece(SmallVectorImpl<unsigned> &Ranges,
1026 const TypedInit *FirstItem) {
1027 const Init *CurVal = FirstItem;
1028 if (!CurVal)
1029 CurVal = ParseValue(CurRec: nullptr);
1030
1031 const auto *II = dyn_cast_or_null<IntInit>(Val: CurVal);
1032 if (!II)
1033 return TokError(Msg: "expected integer or bitrange");
1034
1035 int64_t Start = II->getValue();
1036 int64_t End;
1037
1038 if (Start < 0)
1039 return TokError(Msg: "invalid range, cannot be negative");
1040
1041 switch (Lex.getCode()) {
1042 default:
1043 Ranges.push_back(Elt: Start);
1044 return false;
1045
1046 case tgtok::dotdotdot:
1047 case tgtok::minus: {
1048 Lex.Lex(); // eat
1049
1050 const Init *I_End = ParseValue(CurRec: nullptr);
1051 const auto *II_End = dyn_cast_or_null<IntInit>(Val: I_End);
1052 if (!II_End) {
1053 TokError(Msg: "expected integer value as end of range");
1054 return true;
1055 }
1056
1057 End = II_End->getValue();
1058 break;
1059 }
1060 case tgtok::IntVal: {
1061 End = -Lex.getCurIntVal();
1062 Lex.Lex();
1063 break;
1064 }
1065 }
1066 if (End < 0)
1067 return TokError(Msg: "invalid range, cannot be negative");
1068
1069 // Add to the range.
1070 if (Start < End)
1071 for (; Start <= End; ++Start)
1072 Ranges.push_back(Elt: Start);
1073 else
1074 for (; Start >= End; --Start)
1075 Ranges.push_back(Elt: Start);
1076 return false;
1077}
1078
1079/// ParseRangeList - Parse a list of scalars and ranges into scalar values.
1080///
1081/// RangeList ::= RangePiece (',' RangePiece)*
1082///
1083void TGParser::ParseRangeList(SmallVectorImpl<unsigned> &Result) {
1084 // Parse the first piece.
1085 if (ParseRangePiece(Ranges&: Result)) {
1086 Result.clear();
1087 return;
1088 }
1089 while (consume(K: tgtok::comma))
1090 // Parse the next range piece.
1091 if (ParseRangePiece(Ranges&: Result)) {
1092 Result.clear();
1093 return;
1094 }
1095}
1096
1097/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing.
1098/// OptionalRangeList ::= '{' RangeList '}'
1099/// OptionalRangeList ::= /*empty*/
1100bool TGParser::ParseOptionalRangeList(SmallVectorImpl<unsigned> &Ranges) {
1101 SMLoc StartLoc = Lex.getLoc();
1102 if (!consume(K: tgtok::l_brace))
1103 return false;
1104
1105 // Parse the range list.
1106 ParseRangeList(Result&: Ranges);
1107 if (Ranges.empty())
1108 return true;
1109
1110 if (!consume(K: tgtok::r_brace)) {
1111 TokError(Msg: "expected '}' at end of bit list");
1112 return Error(L: StartLoc, Msg: "to match this '{'");
1113 }
1114 return false;
1115}
1116
1117/// ParseType - Parse and return a tblgen type. This returns null on error.
1118///
1119/// Type ::= STRING // string type
1120/// Type ::= CODE // code type
1121/// Type ::= BIT // bit type
1122/// Type ::= BITS '<' INTVAL '>' // bits<x> type
1123/// Type ::= INT // int type
1124/// Type ::= LIST '<' Type '>' // list<x> type
1125/// Type ::= DAG // dag type
1126/// Type ::= ClassID // Record Type
1127///
1128const RecTy *TGParser::ParseType() {
1129 switch (Lex.getCode()) {
1130 default:
1131 TokError(Msg: "Unknown token when expecting a type");
1132 return nullptr;
1133 case tgtok::String:
1134 case tgtok::Code:
1135 Lex.Lex();
1136 return StringRecTy::get(RK&: Records);
1137 case tgtok::Bit:
1138 Lex.Lex();
1139 return BitRecTy::get(RK&: Records);
1140 case tgtok::Int:
1141 Lex.Lex();
1142 return IntRecTy::get(RK&: Records);
1143 case tgtok::Dag:
1144 Lex.Lex();
1145 return DagRecTy::get(RK&: Records);
1146 case tgtok::Id: {
1147 auto I = TypeAliases.find(x: Lex.getCurStrVal());
1148 if (I != TypeAliases.end()) {
1149 Lex.Lex();
1150 return I->second;
1151 }
1152 if (const Record *R = ParseClassID())
1153 return RecordRecTy::get(Class: R);
1154 TokError(Msg: "unknown class name");
1155 return nullptr;
1156 }
1157 case tgtok::Bits: {
1158 if (Lex.Lex() != tgtok::less) { // Eat 'bits'
1159 TokError(Msg: "expected '<' after bits type");
1160 return nullptr;
1161 }
1162 if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
1163 TokError(Msg: "expected integer in bits<n> type");
1164 return nullptr;
1165 }
1166 uint64_t Val = Lex.getCurIntVal();
1167 if (Lex.Lex() != tgtok::greater) { // Eat count.
1168 TokError(Msg: "expected '>' at end of bits<n> type");
1169 return nullptr;
1170 }
1171 Lex.Lex(); // Eat '>'
1172 return BitsRecTy::get(RK&: Records, Sz: Val);
1173 }
1174 case tgtok::List: {
1175 if (Lex.Lex() != tgtok::less) { // Eat 'bits'
1176 TokError(Msg: "expected '<' after list type");
1177 return nullptr;
1178 }
1179 Lex.Lex(); // Eat '<'
1180 const RecTy *SubType = ParseType();
1181 if (!SubType)
1182 return nullptr;
1183
1184 if (!consume(K: tgtok::greater)) {
1185 TokError(Msg: "expected '>' at end of list<ty> type");
1186 return nullptr;
1187 }
1188 return ListRecTy::get(T: SubType);
1189 }
1190 }
1191}
1192
1193/// ParseIDValue
1194const Init *TGParser::ParseIDValue(Record *CurRec, const StringInit *Name,
1195 SMRange NameLoc, IDParseMode Mode) {
1196 if (const Init *I = CurScope->getVar(Records, ParsingMultiClass: CurMultiClass, Name, NameLoc,
1197 TrackReferenceLocs))
1198 return I;
1199
1200 if (Mode == ParseNameMode)
1201 return Name;
1202
1203 if (const Init *I = Records.getGlobal(Name: Name->getValue())) {
1204 // Add a reference to the global if it's a record.
1205 if (TrackReferenceLocs) {
1206 if (const auto *Def = dyn_cast<DefInit>(Val: I))
1207 Def->getDef()->appendReferenceLoc(Loc: NameLoc);
1208 }
1209 return I;
1210 }
1211
1212 // Allow self-references of concrete defs, but delay the lookup so that we
1213 // get the correct type.
1214 if (CurRec && !CurRec->isClass() && !CurMultiClass &&
1215 CurRec->getNameInit() == Name)
1216 return UnOpInit::get(opc: UnOpInit::CAST, lhs: Name, Type: CurRec->getType());
1217
1218 Error(L: NameLoc.Start, Msg: "Variable not defined: '" + Name->getValue() + "'");
1219 return nullptr;
1220}
1221
1222/// ParseOperation - Parse an operator. This returns null on error.
1223///
1224/// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
1225///
1226const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
1227 switch (Lex.getCode()) {
1228 default:
1229 TokError(Msg: "unknown bang operator");
1230 return nullptr;
1231 case tgtok::XNOT:
1232 case tgtok::XToLower:
1233 case tgtok::XToUpper:
1234 case tgtok::XListFlatten:
1235 case tgtok::XLOG2:
1236 case tgtok::XHead:
1237 case tgtok::XTail:
1238 case tgtok::XSize:
1239 case tgtok::XEmpty:
1240 case tgtok::XCast:
1241 case tgtok::XRepr:
1242 case tgtok::XGetDagOp:
1243 case tgtok::XGetDagOpName:
1244 case tgtok::XInitialized: { // Value ::= !unop '(' Value ')'
1245 UnOpInit::UnaryOp Code;
1246 const RecTy *Type = nullptr;
1247
1248 switch (Lex.getCode()) {
1249 default:
1250 llvm_unreachable("Unhandled code!");
1251 case tgtok::XCast:
1252 Lex.Lex(); // eat the operation
1253 Code = UnOpInit::CAST;
1254
1255 Type = ParseOperatorType();
1256
1257 if (!Type) {
1258 TokError(Msg: "did not get type for unary operator");
1259 return nullptr;
1260 }
1261
1262 break;
1263 case tgtok::XRepr:
1264 Lex.Lex(); // eat the operation
1265 Code = UnOpInit::REPR;
1266 Type = StringRecTy::get(RK&: Records);
1267 break;
1268 case tgtok::XToLower:
1269 Lex.Lex(); // eat the operation
1270 Code = UnOpInit::TOLOWER;
1271 Type = StringRecTy::get(RK&: Records);
1272 break;
1273 case tgtok::XToUpper:
1274 Lex.Lex(); // eat the operation
1275 Code = UnOpInit::TOUPPER;
1276 Type = StringRecTy::get(RK&: Records);
1277 break;
1278 case tgtok::XNOT:
1279 Lex.Lex(); // eat the operation
1280 Code = UnOpInit::NOT;
1281 Type = IntRecTy::get(RK&: Records);
1282 break;
1283 case tgtok::XListFlatten:
1284 Lex.Lex(); // eat the operation.
1285 Code = UnOpInit::LISTFLATTEN;
1286 Type = IntRecTy::get(RK&: Records); // Bogus type used here.
1287 break;
1288 case tgtok::XLOG2:
1289 Lex.Lex(); // eat the operation
1290 Code = UnOpInit::LOG2;
1291 Type = IntRecTy::get(RK&: Records);
1292 break;
1293 case tgtok::XHead:
1294 Lex.Lex(); // eat the operation
1295 Code = UnOpInit::HEAD;
1296 break;
1297 case tgtok::XTail:
1298 Lex.Lex(); // eat the operation
1299 Code = UnOpInit::TAIL;
1300 break;
1301 case tgtok::XSize:
1302 Lex.Lex();
1303 Code = UnOpInit::SIZE;
1304 Type = IntRecTy::get(RK&: Records);
1305 break;
1306 case tgtok::XEmpty:
1307 Lex.Lex(); // eat the operation
1308 Code = UnOpInit::EMPTY;
1309 Type = IntRecTy::get(RK&: Records);
1310 break;
1311 case tgtok::XGetDagOp:
1312 Lex.Lex(); // eat the operation
1313 if (Lex.getCode() == tgtok::less) {
1314 // Parse an optional type suffix, so that you can say
1315 // !getdagop<BaseClass>(someDag) as a shorthand for
1316 // !cast<BaseClass>(!getdagop(someDag)).
1317 Type = ParseOperatorType();
1318
1319 if (!Type) {
1320 TokError(Msg: "did not get type for unary operator");
1321 return nullptr;
1322 }
1323
1324 if (!isa<RecordRecTy>(Val: Type)) {
1325 TokError(Msg: "type for !getdagop must be a record type");
1326 // but keep parsing, to consume the operand
1327 }
1328 } else {
1329 Type = RecordRecTy::get(RK&: Records, Classes: {});
1330 }
1331 Code = UnOpInit::GETDAGOP;
1332 break;
1333 case tgtok::XGetDagOpName:
1334 Lex.Lex(); // eat the operation
1335 Type = StringRecTy::get(RK&: Records);
1336 Code = UnOpInit::GETDAGOPNAME;
1337 break;
1338 case tgtok::XInitialized:
1339 Lex.Lex(); // eat the operation
1340 Code = UnOpInit::INITIALIZED;
1341 Type = IntRecTy::get(RK&: Records);
1342 break;
1343 }
1344 if (!consume(K: tgtok::l_paren)) {
1345 TokError(Msg: "expected '(' after unary operator");
1346 return nullptr;
1347 }
1348
1349 const Init *LHS = ParseValue(CurRec);
1350 if (!LHS)
1351 return nullptr;
1352
1353 if (Code == UnOpInit::EMPTY || Code == UnOpInit::SIZE) {
1354 const auto *LHSl = dyn_cast<ListInit>(Val: LHS);
1355 const auto *LHSs = dyn_cast<StringInit>(Val: LHS);
1356 const auto *LHSd = dyn_cast<DagInit>(Val: LHS);
1357 const auto *LHSt = dyn_cast<TypedInit>(Val: LHS);
1358 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1359 TokError(
1360 Msg: "expected string, list, or dag type argument in unary operator");
1361 return nullptr;
1362 }
1363 if (LHSt) {
1364 if (!isa<ListRecTy, StringRecTy, DagRecTy>(Val: LHSt->getType())) {
1365 TokError(
1366 Msg: "expected string, list, or dag type argument in unary operator");
1367 return nullptr;
1368 }
1369 }
1370 }
1371
1372 if (Code == UnOpInit::HEAD || Code == UnOpInit::TAIL ||
1373 Code == UnOpInit::LISTFLATTEN) {
1374 const auto *LHSl = dyn_cast<ListInit>(Val: LHS);
1375 const auto *LHSt = dyn_cast<TypedInit>(Val: LHS);
1376 if (!LHSl && !LHSt) {
1377 TokError(Msg: "expected list type argument in unary operator");
1378 return nullptr;
1379 }
1380 if (LHSt) {
1381 if (!isa<ListRecTy>(Val: LHSt->getType())) {
1382 TokError(Msg: "expected list type argument in unary operator");
1383 return nullptr;
1384 }
1385 }
1386
1387 if (LHSl && LHSl->empty()) {
1388 TokError(Msg: "empty list argument in unary operator");
1389 return nullptr;
1390 }
1391 bool UseElementType =
1392 Code == UnOpInit::HEAD || Code == UnOpInit::LISTFLATTEN;
1393 if (LHSl) {
1394 const Init *Item = LHSl->getElement(Idx: 0);
1395 const auto *Itemt = dyn_cast<TypedInit>(Val: Item);
1396 if (!Itemt) {
1397 TokError(Msg: "untyped list element in unary operator");
1398 return nullptr;
1399 }
1400 Type = UseElementType ? Itemt->getType()
1401 : ListRecTy::get(T: Itemt->getType());
1402 } else {
1403 assert(LHSt && "expected list type argument in unary operator");
1404 const auto *LType = dyn_cast<ListRecTy>(Val: LHSt->getType());
1405 Type = UseElementType ? LType->getElementType() : LType;
1406 }
1407
1408 // for !listflatten, we expect a list of lists, but also support a list of
1409 // non-lists, where !listflatten will be a NOP.
1410 if (Code == UnOpInit::LISTFLATTEN) {
1411 const auto *InnerListTy = dyn_cast<ListRecTy>(Val: Type);
1412 if (InnerListTy) {
1413 // listflatten will convert list<list<X>> to list<X>.
1414 Type = ListRecTy::get(T: InnerListTy->getElementType());
1415 } else {
1416 // If its a list of non-lists, !listflatten will be a NOP.
1417 Type = ListRecTy::get(T: Type);
1418 }
1419 }
1420 }
1421
1422 if (!consume(K: tgtok::r_paren)) {
1423 TokError(Msg: "expected ')' in unary operator");
1424 return nullptr;
1425 }
1426 return (UnOpInit::get(opc: Code, lhs: LHS, Type))->Fold(CurRec);
1427 }
1428
1429 case tgtok::XIsA: {
1430 // Value ::= !isa '<' Type '>' '(' Value ')'
1431 Lex.Lex(); // eat the operation
1432
1433 const RecTy *Type = ParseOperatorType();
1434 if (!Type)
1435 return nullptr;
1436
1437 if (!consume(K: tgtok::l_paren)) {
1438 TokError(Msg: "expected '(' after type of !isa");
1439 return nullptr;
1440 }
1441
1442 const Init *LHS = ParseValue(CurRec);
1443 if (!LHS)
1444 return nullptr;
1445
1446 if (!consume(K: tgtok::r_paren)) {
1447 TokError(Msg: "expected ')' in !isa");
1448 return nullptr;
1449 }
1450
1451 return IsAOpInit::get(CheckType: Type, Expr: LHS)->Fold();
1452 }
1453
1454 case tgtok::XExists: {
1455 // Value ::= !exists '<' Type '>' '(' Value ')'
1456 Lex.Lex(); // eat the operation.
1457
1458 const RecTy *Type = ParseOperatorType();
1459 if (!Type)
1460 return nullptr;
1461
1462 if (!consume(K: tgtok::l_paren)) {
1463 TokError(Msg: "expected '(' after type of !exists");
1464 return nullptr;
1465 }
1466
1467 SMLoc ExprLoc = Lex.getLoc();
1468 const Init *Expr = ParseValue(CurRec);
1469 if (!Expr)
1470 return nullptr;
1471
1472 const auto *ExprType = dyn_cast<TypedInit>(Val: Expr);
1473 if (!ExprType) {
1474 Error(L: ExprLoc, Msg: "expected string type argument in !exists operator");
1475 return nullptr;
1476 }
1477
1478 const auto *RecType = dyn_cast<RecordRecTy>(Val: ExprType->getType());
1479 if (RecType) {
1480 Error(L: ExprLoc,
1481 Msg: "expected string type argument in !exists operator, please "
1482 "use !isa instead");
1483 return nullptr;
1484 }
1485
1486 const auto *SType = dyn_cast<StringRecTy>(Val: ExprType->getType());
1487 if (!SType) {
1488 Error(L: ExprLoc, Msg: "expected string type argument in !exists operator");
1489 return nullptr;
1490 }
1491
1492 if (!consume(K: tgtok::r_paren)) {
1493 TokError(Msg: "expected ')' in !exists");
1494 return nullptr;
1495 }
1496
1497 return (ExistsOpInit::get(CheckType: Type, Expr))->Fold(CurRec);
1498 }
1499
1500 case tgtok::XInstances: {
1501 // Value ::= !instances '<' Type '>' '(' Regex? ')'
1502 Lex.Lex(); // eat the operation.
1503
1504 const RecTy *Type = ParseOperatorType();
1505 if (!Type)
1506 return nullptr;
1507
1508 if (!consume(K: tgtok::l_paren)) {
1509 TokError(Msg: "expected '(' after type of !instances");
1510 return nullptr;
1511 }
1512
1513 // The Regex can be optional.
1514 const Init *Regex;
1515 if (Lex.getCode() != tgtok::r_paren) {
1516 SMLoc RegexLoc = Lex.getLoc();
1517 Regex = ParseValue(CurRec);
1518
1519 const auto *RegexType = dyn_cast<TypedInit>(Val: Regex);
1520 if (!RegexType) {
1521 Error(L: RegexLoc, Msg: "expected string type argument in !instances operator");
1522 return nullptr;
1523 }
1524
1525 const auto *SType = dyn_cast<StringRecTy>(Val: RegexType->getType());
1526 if (!SType) {
1527 Error(L: RegexLoc, Msg: "expected string type argument in !instances operator");
1528 return nullptr;
1529 }
1530 } else {
1531 // Use wildcard when Regex is not specified.
1532 Regex = StringInit::get(RK&: Records, ".*");
1533 }
1534
1535 if (!consume(K: tgtok::r_paren)) {
1536 TokError(Msg: "expected ')' in !instances");
1537 return nullptr;
1538 }
1539
1540 return InstancesOpInit::get(Type, Regex)->Fold(CurRec);
1541 }
1542
1543 case tgtok::XConcat:
1544 case tgtok::XMatch:
1545 case tgtok::XADD:
1546 case tgtok::XSUB:
1547 case tgtok::XMUL:
1548 case tgtok::XDIV:
1549 case tgtok::XAND:
1550 case tgtok::XOR:
1551 case tgtok::XXOR:
1552 case tgtok::XSRA:
1553 case tgtok::XSRL:
1554 case tgtok::XSHL:
1555 case tgtok::XEq:
1556 case tgtok::XNe:
1557 case tgtok::XLe:
1558 case tgtok::XLt:
1559 case tgtok::XGe:
1560 case tgtok::XGt:
1561 case tgtok::XListConcat:
1562 case tgtok::XListSplat:
1563 case tgtok::XListRemove:
1564 case tgtok::XStrConcat:
1565 case tgtok::XInterleave:
1566 case tgtok::XGetDagArg:
1567 case tgtok::XGetDagName:
1568 case tgtok::XSetDagOp:
1569 case tgtok::XSetDagOpName: { // Value ::= !binop '(' Value ',' Value ')'
1570 tgtok::TokKind OpTok = Lex.getCode();
1571 SMLoc OpLoc = Lex.getLoc();
1572 Lex.Lex(); // eat the operation
1573
1574 BinOpInit::BinaryOp Code;
1575 switch (OpTok) {
1576 default:
1577 llvm_unreachable("Unhandled code!");
1578 case tgtok::XConcat:
1579 Code = BinOpInit::CONCAT;
1580 break;
1581 case tgtok::XMatch:
1582 Code = BinOpInit::MATCH;
1583 break;
1584 case tgtok::XADD:
1585 Code = BinOpInit::ADD;
1586 break;
1587 case tgtok::XSUB:
1588 Code = BinOpInit::SUB;
1589 break;
1590 case tgtok::XMUL:
1591 Code = BinOpInit::MUL;
1592 break;
1593 case tgtok::XDIV:
1594 Code = BinOpInit::DIV;
1595 break;
1596 case tgtok::XAND:
1597 Code = BinOpInit::AND;
1598 break;
1599 case tgtok::XOR:
1600 Code = BinOpInit::OR;
1601 break;
1602 case tgtok::XXOR:
1603 Code = BinOpInit::XOR;
1604 break;
1605 case tgtok::XSRA:
1606 Code = BinOpInit::SRA;
1607 break;
1608 case tgtok::XSRL:
1609 Code = BinOpInit::SRL;
1610 break;
1611 case tgtok::XSHL:
1612 Code = BinOpInit::SHL;
1613 break;
1614 case tgtok::XEq:
1615 Code = BinOpInit::EQ;
1616 break;
1617 case tgtok::XNe:
1618 Code = BinOpInit::NE;
1619 break;
1620 case tgtok::XLe:
1621 Code = BinOpInit::LE;
1622 break;
1623 case tgtok::XLt:
1624 Code = BinOpInit::LT;
1625 break;
1626 case tgtok::XGe:
1627 Code = BinOpInit::GE;
1628 break;
1629 case tgtok::XGt:
1630 Code = BinOpInit::GT;
1631 break;
1632 case tgtok::XListConcat:
1633 Code = BinOpInit::LISTCONCAT;
1634 break;
1635 case tgtok::XListSplat:
1636 Code = BinOpInit::LISTSPLAT;
1637 break;
1638 case tgtok::XListRemove:
1639 Code = BinOpInit::LISTREMOVE;
1640 break;
1641 case tgtok::XStrConcat:
1642 Code = BinOpInit::STRCONCAT;
1643 break;
1644 case tgtok::XInterleave:
1645 Code = BinOpInit::INTERLEAVE;
1646 break;
1647 case tgtok::XSetDagOp:
1648 Code = BinOpInit::SETDAGOP;
1649 break;
1650 case tgtok::XSetDagOpName:
1651 Code = BinOpInit::SETDAGOPNAME;
1652 break;
1653 case tgtok::XGetDagArg:
1654 Code = BinOpInit::GETDAGARG;
1655 break;
1656 case tgtok::XGetDagName:
1657 Code = BinOpInit::GETDAGNAME;
1658 break;
1659 }
1660
1661 const RecTy *Type = nullptr;
1662 const RecTy *ArgType = nullptr;
1663 switch (OpTok) {
1664 default:
1665 llvm_unreachable("Unhandled code!");
1666 case tgtok::XMatch:
1667 Type = BitRecTy::get(RK&: Records);
1668 ArgType = StringRecTy::get(RK&: Records);
1669 break;
1670 case tgtok::XConcat:
1671 case tgtok::XSetDagOp:
1672 Type = DagRecTy::get(RK&: Records);
1673 ArgType = DagRecTy::get(RK&: Records);
1674 break;
1675 case tgtok::XGetDagArg:
1676 Type = ParseOperatorType();
1677 if (!Type) {
1678 TokError(Msg: "did not get type for !getdagarg operator");
1679 return nullptr;
1680 }
1681 ArgType = DagRecTy::get(RK&: Records);
1682 break;
1683 case tgtok::XSetDagOpName:
1684 Type = DagRecTy::get(RK&: Records);
1685 ArgType = DagRecTy::get(RK&: Records);
1686 break;
1687 case tgtok::XGetDagName:
1688 Type = StringRecTy::get(RK&: Records);
1689 ArgType = DagRecTy::get(RK&: Records);
1690 break;
1691 case tgtok::XAND:
1692 case tgtok::XOR:
1693 case tgtok::XXOR:
1694 case tgtok::XSRA:
1695 case tgtok::XSRL:
1696 case tgtok::XSHL:
1697 case tgtok::XADD:
1698 case tgtok::XSUB:
1699 case tgtok::XMUL:
1700 case tgtok::XDIV:
1701 Type = IntRecTy::get(RK&: Records);
1702 ArgType = IntRecTy::get(RK&: Records);
1703 break;
1704 case tgtok::XEq:
1705 case tgtok::XNe:
1706 case tgtok::XLe:
1707 case tgtok::XLt:
1708 case tgtok::XGe:
1709 case tgtok::XGt:
1710 Type = BitRecTy::get(RK&: Records);
1711 // ArgType for the comparison operators is not yet known.
1712 break;
1713 case tgtok::XListConcat:
1714 // We don't know the list type until we parse the first argument.
1715 ArgType = ItemType;
1716 break;
1717 case tgtok::XListSplat:
1718 // Can't do any typechecking until we parse the first argument.
1719 break;
1720 case tgtok::XListRemove:
1721 // We don't know the list type until we parse the first argument.
1722 ArgType = ItemType;
1723 break;
1724 case tgtok::XStrConcat:
1725 Type = StringRecTy::get(RK&: Records);
1726 ArgType = StringRecTy::get(RK&: Records);
1727 break;
1728 case tgtok::XInterleave:
1729 Type = StringRecTy::get(RK&: Records);
1730 // The first argument type is not yet known.
1731 }
1732
1733 if (Type && ItemType && !Type->typeIsConvertibleTo(RHS: ItemType)) {
1734 Error(L: OpLoc, Msg: Twine("expected value of type '") + ItemType->getAsString() +
1735 "', got '" + Type->getAsString() + "'");
1736 return nullptr;
1737 }
1738
1739 if (!consume(K: tgtok::l_paren)) {
1740 TokError(Msg: "expected '(' after binary operator");
1741 return nullptr;
1742 }
1743
1744 SmallVector<const Init *, 2> InitList;
1745
1746 // Note that this loop consumes an arbitrary number of arguments.
1747 // The actual count is checked later.
1748 for (;;) {
1749 SMLoc InitLoc = Lex.getLoc();
1750 InitList.push_back(Elt: ParseValue(CurRec, ItemType: ArgType));
1751 if (!InitList.back())
1752 return nullptr;
1753
1754 const auto *InitListBack = dyn_cast<TypedInit>(Val: InitList.back());
1755 if (!InitListBack) {
1756 Error(L: OpLoc, Msg: Twine("expected value to be a typed value, got '" +
1757 InitList.back()->getAsString() + "'"));
1758 return nullptr;
1759 }
1760 const RecTy *ListType = InitListBack->getType();
1761
1762 if (!ArgType) {
1763 // Argument type must be determined from the argument itself.
1764 ArgType = ListType;
1765
1766 switch (Code) {
1767 case BinOpInit::LISTCONCAT:
1768 if (!isa<ListRecTy>(Val: ArgType)) {
1769 Error(L: InitLoc, Msg: Twine("expected a list, got value of type '") +
1770 ArgType->getAsString() + "'");
1771 return nullptr;
1772 }
1773 break;
1774 case BinOpInit::LISTSPLAT:
1775 if (ItemType && InitList.size() == 1) {
1776 if (!isa<ListRecTy>(Val: ItemType)) {
1777 Error(L: OpLoc,
1778 Msg: Twine("expected output type to be a list, got type '") +
1779 ItemType->getAsString() + "'");
1780 return nullptr;
1781 }
1782 if (!ArgType->getListTy()->typeIsConvertibleTo(RHS: ItemType)) {
1783 Error(L: OpLoc, Msg: Twine("expected first arg type to be '") +
1784 ArgType->getAsString() +
1785 "', got value of type '" +
1786 cast<ListRecTy>(Val: ItemType)
1787 ->getElementType()
1788 ->getAsString() +
1789 "'");
1790 return nullptr;
1791 }
1792 }
1793 if (InitList.size() == 2 && !isa<IntRecTy>(Val: ArgType)) {
1794 Error(L: InitLoc, Msg: Twine("expected second parameter to be an int, got "
1795 "value of type '") +
1796 ArgType->getAsString() + "'");
1797 return nullptr;
1798 }
1799 ArgType = nullptr; // Broken invariant: types not identical.
1800 break;
1801 case BinOpInit::LISTREMOVE:
1802 if (!isa<ListRecTy>(Val: ArgType)) {
1803 Error(L: InitLoc, Msg: Twine("expected a list, got value of type '") +
1804 ArgType->getAsString() + "'");
1805 return nullptr;
1806 }
1807 break;
1808 case BinOpInit::EQ:
1809 case BinOpInit::NE:
1810 if (!ArgType->typeIsConvertibleTo(RHS: IntRecTy::get(RK&: Records)) &&
1811 !ArgType->typeIsConvertibleTo(RHS: StringRecTy::get(RK&: Records)) &&
1812 !ArgType->typeIsConvertibleTo(RHS: RecordRecTy::get(RK&: Records, Classes: {}))) {
1813 Error(L: InitLoc, Msg: Twine("expected bit, bits, int, string, or record; "
1814 "got value of type '") +
1815 ArgType->getAsString() + "'");
1816 return nullptr;
1817 }
1818 break;
1819 case BinOpInit::GETDAGARG: // The 2nd argument of !getdagarg could be
1820 // index or name.
1821 case BinOpInit::LE:
1822 case BinOpInit::LT:
1823 case BinOpInit::GE:
1824 case BinOpInit::GT:
1825 if (!ArgType->typeIsConvertibleTo(RHS: IntRecTy::get(RK&: Records)) &&
1826 !ArgType->typeIsConvertibleTo(RHS: StringRecTy::get(RK&: Records))) {
1827 Error(L: InitLoc, Msg: Twine("expected bit, bits, int, or string; "
1828 "got value of type '") +
1829 ArgType->getAsString() + "'");
1830 return nullptr;
1831 }
1832 break;
1833 case BinOpInit::INTERLEAVE:
1834 switch (InitList.size()) {
1835 case 1: // First argument must be a list of strings or integers.
1836 if (ArgType != StringRecTy::get(RK&: Records)->getListTy() &&
1837 !ArgType->typeIsConvertibleTo(
1838 RHS: IntRecTy::get(RK&: Records)->getListTy())) {
1839 Error(L: InitLoc,
1840 Msg: Twine("expected list of string, int, bits, or bit; "
1841 "got value of type '") +
1842 ArgType->getAsString() + "'");
1843 return nullptr;
1844 }
1845 break;
1846 case 2: // Second argument must be a string.
1847 if (!isa<StringRecTy>(Val: ArgType)) {
1848 Error(L: InitLoc, Msg: Twine("expected second argument to be a string, "
1849 "got value of type '") +
1850 ArgType->getAsString() + "'");
1851 return nullptr;
1852 }
1853 break;
1854 default:;
1855 }
1856 ArgType = nullptr; // Broken invariant: types not identical.
1857 break;
1858 default:
1859 llvm_unreachable("other ops have fixed argument types");
1860 }
1861
1862 } else {
1863 // Desired argument type is a known and in ArgType.
1864 const RecTy *Resolved = resolveTypes(T1: ArgType, T2: ListType);
1865 if (!Resolved) {
1866 Error(L: InitLoc, Msg: Twine("expected value of type '") +
1867 ArgType->getAsString() + "', got '" +
1868 ListType->getAsString() + "'");
1869 return nullptr;
1870 }
1871 if (Code != BinOpInit::ADD && Code != BinOpInit::SUB &&
1872 Code != BinOpInit::AND && Code != BinOpInit::OR &&
1873 Code != BinOpInit::XOR && Code != BinOpInit::SRA &&
1874 Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
1875 Code != BinOpInit::MUL && Code != BinOpInit::DIV)
1876 ArgType = Resolved;
1877 }
1878
1879 // Deal with BinOps whose arguments have different types, by
1880 // rewriting ArgType in between them.
1881 switch (Code) {
1882 case BinOpInit::SETDAGOPNAME:
1883 // After parsing the first dag argument, expect a string.
1884 ArgType = StringRecTy::get(RK&: Records);
1885 break;
1886 case BinOpInit::SETDAGOP:
1887 // After parsing the first dag argument, switch to expecting
1888 // a record, with no restriction on its superclasses.
1889 ArgType = RecordRecTy::get(RK&: Records, Classes: {});
1890 break;
1891 case BinOpInit::GETDAGARG:
1892 // After parsing the first dag argument, expect an index integer or a
1893 // name string.
1894 ArgType = nullptr;
1895 break;
1896 case BinOpInit::GETDAGNAME:
1897 // After parsing the first dag argument, expect an index integer.
1898 ArgType = IntRecTy::get(RK&: Records);
1899 break;
1900 default:
1901 break;
1902 }
1903
1904 if (!consume(K: tgtok::comma))
1905 break;
1906 }
1907
1908 if (!consume(K: tgtok::r_paren)) {
1909 TokError(Msg: "expected ')' in operator");
1910 return nullptr;
1911 }
1912
1913 // listconcat returns a list with type of the argument.
1914 if (Code == BinOpInit::LISTCONCAT)
1915 Type = ArgType;
1916 // listsplat returns a list of type of the *first* argument.
1917 if (Code == BinOpInit::LISTSPLAT)
1918 Type = cast<TypedInit>(Val: InitList.front())->getType()->getListTy();
1919 // listremove returns a list with type of the argument.
1920 if (Code == BinOpInit::LISTREMOVE)
1921 Type = ArgType;
1922
1923 // We allow multiple operands to associative operators like !strconcat as
1924 // shorthand for nesting them.
1925 if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT ||
1926 Code == BinOpInit::CONCAT || Code == BinOpInit::ADD ||
1927 Code == BinOpInit::AND || Code == BinOpInit::OR ||
1928 Code == BinOpInit::XOR || Code == BinOpInit::MUL) {
1929 while (InitList.size() > 2) {
1930 const Init *RHS = InitList.pop_back_val();
1931 RHS = (BinOpInit::get(opc: Code, lhs: InitList.back(), rhs: RHS, Type))->Fold(CurRec);
1932 InitList.back() = RHS;
1933 }
1934 }
1935
1936 if (InitList.size() == 2)
1937 return (BinOpInit::get(opc: Code, lhs: InitList[0], rhs: InitList[1], Type))
1938 ->Fold(CurRec);
1939
1940 Error(L: OpLoc, Msg: "expected two operands to operator");
1941 return nullptr;
1942 }
1943
1944 case tgtok::XForEach:
1945 case tgtok::XFilter:
1946 case tgtok::XSort: {
1947 return ParseOperationListComprehension(CurRec, ItemType);
1948 }
1949
1950 case tgtok::XRange: {
1951 SMLoc OpLoc = Lex.getLoc();
1952 Lex.Lex(); // eat the operation
1953
1954 if (!consume(K: tgtok::l_paren)) {
1955 TokError(Msg: "expected '(' after !range operator");
1956 return nullptr;
1957 }
1958
1959 SmallVector<const Init *, 2> Args;
1960 bool FirstArgIsList = false;
1961 for (;;) {
1962 if (Args.size() >= 3) {
1963 TokError(Msg: "expected at most three values of integer");
1964 return nullptr;
1965 }
1966
1967 SMLoc InitLoc = Lex.getLoc();
1968 Args.push_back(Elt: ParseValue(CurRec));
1969 if (!Args.back())
1970 return nullptr;
1971
1972 const auto *ArgBack = dyn_cast<TypedInit>(Val: Args.back());
1973 if (!ArgBack) {
1974 Error(L: OpLoc, Msg: Twine("expected value to be a typed value, got '" +
1975 Args.back()->getAsString() + "'"));
1976 return nullptr;
1977 }
1978
1979 const RecTy *ArgBackType = ArgBack->getType();
1980 if (!FirstArgIsList || Args.size() == 1) {
1981 if (Args.size() == 1 && isa<ListRecTy>(Val: ArgBackType)) {
1982 FirstArgIsList = true; // Detect error if 2nd arg were present.
1983 } else if (isa<IntRecTy>(Val: ArgBackType)) {
1984 // Assume 2nd arg should be IntRecTy
1985 } else {
1986 if (Args.size() != 1)
1987 Error(L: InitLoc, Msg: Twine("expected value of type 'int', got '" +
1988 ArgBackType->getAsString() + "'"));
1989 else
1990 Error(L: InitLoc, Msg: Twine("expected list or int, got value of type '") +
1991 ArgBackType->getAsString() + "'");
1992 return nullptr;
1993 }
1994 } else {
1995 // Don't come here unless 1st arg is ListRecTy.
1996 assert(isa<ListRecTy>(cast<TypedInit>(Args[0])->getType()));
1997 Error(L: InitLoc, Msg: Twine("expected one list, got extra value of type '") +
1998 ArgBackType->getAsString() + "'");
1999 return nullptr;
2000 }
2001 if (!consume(K: tgtok::comma))
2002 break;
2003 }
2004
2005 if (!consume(K: tgtok::r_paren)) {
2006 TokError(Msg: "expected ')' in operator");
2007 return nullptr;
2008 }
2009
2010 const Init *LHS, *MHS, *RHS;
2011 auto ArgCount = Args.size();
2012 assert(ArgCount >= 1);
2013 const auto *Arg0 = cast<TypedInit>(Val: Args[0]);
2014 const auto *Arg0Ty = Arg0->getType();
2015 if (ArgCount == 1) {
2016 if (isa<ListRecTy>(Val: Arg0Ty)) {
2017 // (0, !size(arg), 1)
2018 LHS = IntInit::get(RK&: Records, V: 0);
2019 MHS = UnOpInit::get(opc: UnOpInit::SIZE, lhs: Arg0, Type: IntRecTy::get(RK&: Records))
2020 ->Fold(CurRec);
2021 RHS = IntInit::get(RK&: Records, V: 1);
2022 } else {
2023 assert(isa<IntRecTy>(Arg0Ty));
2024 // (0, arg, 1)
2025 LHS = IntInit::get(RK&: Records, V: 0);
2026 MHS = Arg0;
2027 RHS = IntInit::get(RK&: Records, V: 1);
2028 }
2029 } else {
2030 assert(isa<IntRecTy>(Arg0Ty));
2031 const auto *Arg1 = cast<TypedInit>(Val: Args[1]);
2032 assert(isa<IntRecTy>(Arg1->getType()));
2033 LHS = Arg0;
2034 MHS = Arg1;
2035 if (ArgCount == 3) {
2036 // (start, end, step)
2037 const auto *Arg2 = cast<TypedInit>(Val: Args[2]);
2038 assert(isa<IntRecTy>(Arg2->getType()));
2039 RHS = Arg2;
2040 } else {
2041 // (start, end, 1)
2042 RHS = IntInit::get(RK&: Records, V: 1);
2043 }
2044 }
2045 return TernOpInit::get(opc: TernOpInit::RANGE, lhs: LHS, mhs: MHS, rhs: RHS,
2046 Type: IntRecTy::get(RK&: Records)->getListTy())
2047 ->Fold(CurRec);
2048 }
2049
2050 case tgtok::XSetDagArg:
2051 case tgtok::XSetDagName:
2052 case tgtok::XDag:
2053 case tgtok::XIf:
2054 case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
2055 TernOpInit::TernaryOp Code;
2056 const RecTy *Type = nullptr;
2057
2058 tgtok::TokKind LexCode = Lex.getCode();
2059 Lex.Lex(); // Eat the operation.
2060 switch (LexCode) {
2061 default:
2062 llvm_unreachable("Unhandled code!");
2063 case tgtok::XDag:
2064 Code = TernOpInit::DAG;
2065 Type = DagRecTy::get(RK&: Records);
2066 ItemType = nullptr;
2067 break;
2068 case tgtok::XIf:
2069 Code = TernOpInit::IF;
2070 break;
2071 case tgtok::XSubst:
2072 Code = TernOpInit::SUBST;
2073 break;
2074 case tgtok::XSetDagArg:
2075 Code = TernOpInit::SETDAGARG;
2076 Type = DagRecTy::get(RK&: Records);
2077 ItemType = nullptr;
2078 break;
2079 case tgtok::XSetDagName:
2080 Code = TernOpInit::SETDAGNAME;
2081 Type = DagRecTy::get(RK&: Records);
2082 ItemType = nullptr;
2083 break;
2084 }
2085 if (!consume(K: tgtok::l_paren)) {
2086 TokError(Msg: "expected '(' after ternary operator");
2087 return nullptr;
2088 }
2089
2090 const Init *LHS = ParseValue(CurRec);
2091 if (!LHS)
2092 return nullptr;
2093
2094 if (!consume(K: tgtok::comma)) {
2095 TokError(Msg: "expected ',' in ternary operator");
2096 return nullptr;
2097 }
2098
2099 SMLoc MHSLoc = Lex.getLoc();
2100 const Init *MHS = ParseValue(CurRec, ItemType);
2101 if (!MHS)
2102 return nullptr;
2103
2104 if (!consume(K: tgtok::comma)) {
2105 TokError(Msg: "expected ',' in ternary operator");
2106 return nullptr;
2107 }
2108
2109 SMLoc RHSLoc = Lex.getLoc();
2110 const Init *RHS = ParseValue(CurRec, ItemType);
2111 if (!RHS)
2112 return nullptr;
2113
2114 if (!consume(K: tgtok::r_paren)) {
2115 TokError(Msg: "expected ')' in binary operator");
2116 return nullptr;
2117 }
2118
2119 switch (LexCode) {
2120 default:
2121 llvm_unreachable("Unhandled code!");
2122 case tgtok::XDag: {
2123 const auto *MHSt = dyn_cast<TypedInit>(Val: MHS);
2124 if (!MHSt && !isa<UnsetInit>(Val: MHS)) {
2125 Error(L: MHSLoc, Msg: "could not determine type of the child list in !dag");
2126 return nullptr;
2127 }
2128 if (MHSt && !isa<ListRecTy>(Val: MHSt->getType())) {
2129 Error(L: MHSLoc, Msg: Twine("expected list of children, got type '") +
2130 MHSt->getType()->getAsString() + "'");
2131 return nullptr;
2132 }
2133
2134 const auto *RHSt = dyn_cast<TypedInit>(Val: RHS);
2135 if (!RHSt && !isa<UnsetInit>(Val: RHS)) {
2136 Error(L: RHSLoc, Msg: "could not determine type of the name list in !dag");
2137 return nullptr;
2138 }
2139 if (RHSt && StringRecTy::get(RK&: Records)->getListTy() != RHSt->getType()) {
2140 Error(L: RHSLoc, Msg: Twine("expected list<string>, got type '") +
2141 RHSt->getType()->getAsString() + "'");
2142 return nullptr;
2143 }
2144
2145 if (!MHSt && !RHSt) {
2146 Error(L: MHSLoc,
2147 Msg: "cannot have both unset children and unset names in !dag");
2148 return nullptr;
2149 }
2150 break;
2151 }
2152 case tgtok::XIf: {
2153 const RecTy *MHSTy = nullptr;
2154 const RecTy *RHSTy = nullptr;
2155
2156 if (const auto *MHSt = dyn_cast<TypedInit>(Val: MHS))
2157 MHSTy = MHSt->getType();
2158 if (const auto *MHSbits = dyn_cast<BitsInit>(Val: MHS))
2159 MHSTy = BitsRecTy::get(RK&: Records, Sz: MHSbits->getNumBits());
2160 if (isa<BitInit>(Val: MHS))
2161 MHSTy = BitRecTy::get(RK&: Records);
2162
2163 if (const auto *RHSt = dyn_cast<TypedInit>(Val: RHS))
2164 RHSTy = RHSt->getType();
2165 if (const auto *RHSbits = dyn_cast<BitsInit>(Val: RHS))
2166 RHSTy = BitsRecTy::get(RK&: Records, Sz: RHSbits->getNumBits());
2167 if (isa<BitInit>(Val: RHS))
2168 RHSTy = BitRecTy::get(RK&: Records);
2169
2170 // For UnsetInit, it's typed from the other hand.
2171 if (isa<UnsetInit>(Val: MHS))
2172 MHSTy = RHSTy;
2173 if (isa<UnsetInit>(Val: RHS))
2174 RHSTy = MHSTy;
2175
2176 if (!MHSTy || !RHSTy) {
2177 TokError(Msg: "could not get type for !if");
2178 return nullptr;
2179 }
2180
2181 Type = resolveTypes(T1: MHSTy, T2: RHSTy);
2182 if (!Type) {
2183 TokError(Msg: Twine("inconsistent types '") + MHSTy->getAsString() +
2184 "' and '" + RHSTy->getAsString() + "' for !if");
2185 return nullptr;
2186 }
2187 break;
2188 }
2189 case tgtok::XSubst: {
2190 const auto *RHSt = dyn_cast<TypedInit>(Val: RHS);
2191 if (!RHSt) {
2192 TokError(Msg: "could not get type for !subst");
2193 return nullptr;
2194 }
2195 Type = RHSt->getType();
2196 break;
2197 }
2198 case tgtok::XSetDagArg: {
2199 const auto *MHSt = dyn_cast<TypedInit>(Val: MHS);
2200 if (!MHSt || !isa<IntRecTy, StringRecTy>(Val: MHSt->getType())) {
2201 Error(L: MHSLoc, Msg: Twine("expected integer index or string name, got ") +
2202 (MHSt ? ("type '" + MHSt->getType()->getAsString())
2203 : ("'" + MHS->getAsString())) +
2204 "'");
2205 return nullptr;
2206 }
2207 break;
2208 }
2209 case tgtok::XSetDagName: {
2210 const auto *MHSt = dyn_cast<TypedInit>(Val: MHS);
2211 if (!MHSt || !isa<IntRecTy, StringRecTy>(Val: MHSt->getType())) {
2212 Error(L: MHSLoc, Msg: Twine("expected integer index or string name, got ") +
2213 (MHSt ? ("type '" + MHSt->getType()->getAsString())
2214 : ("'" + MHS->getAsString())) +
2215 "'");
2216 return nullptr;
2217 }
2218 const auto *RHSt = dyn_cast<TypedInit>(Val: RHS);
2219 // The name could be a string or unset.
2220 if (RHSt && !isa<StringRecTy>(Val: RHSt->getType())) {
2221 Error(L: RHSLoc, Msg: Twine("expected string or unset name, got type '") +
2222 RHSt->getType()->getAsString() + "'");
2223 return nullptr;
2224 }
2225 break;
2226 }
2227 }
2228 return (TernOpInit::get(opc: Code, lhs: LHS, mhs: MHS, rhs: RHS, Type))->Fold(CurRec);
2229 }
2230
2231 case tgtok::XSubstr:
2232 return ParseOperationSubstr(CurRec, ItemType);
2233
2234 case tgtok::XFind:
2235 return ParseOperationFind(CurRec, ItemType);
2236
2237 case tgtok::XCond:
2238 return ParseOperationCond(CurRec, ItemType);
2239
2240 case tgtok::XSwitch:
2241 return ParseOperationSwitch(CurRec, ItemType);
2242
2243 case tgtok::XFoldl: {
2244 // Value ::= !foldl '(' Value ',' Value ',' Id ',' Id ',' Expr ')'
2245 Lex.Lex(); // eat the operation
2246 if (!consume(K: tgtok::l_paren)) {
2247 TokError(Msg: "expected '(' after !foldl");
2248 return nullptr;
2249 }
2250
2251 const Init *StartUntyped = ParseValue(CurRec);
2252 if (!StartUntyped)
2253 return nullptr;
2254
2255 const auto *Start = dyn_cast<TypedInit>(Val: StartUntyped);
2256 if (!Start) {
2257 TokError(Msg: Twine("could not get type of !foldl start: '") +
2258 StartUntyped->getAsString() + "'");
2259 return nullptr;
2260 }
2261
2262 if (!consume(K: tgtok::comma)) {
2263 TokError(Msg: "expected ',' in !foldl");
2264 return nullptr;
2265 }
2266
2267 const Init *ListUntyped = ParseValue(CurRec);
2268 if (!ListUntyped)
2269 return nullptr;
2270
2271 const auto *List = dyn_cast<TypedInit>(Val: ListUntyped);
2272 if (!List) {
2273 TokError(Msg: Twine("could not get type of !foldl list: '") +
2274 ListUntyped->getAsString() + "'");
2275 return nullptr;
2276 }
2277
2278 const auto *ListType = dyn_cast<ListRecTy>(Val: List->getType());
2279 if (!ListType) {
2280 TokError(Msg: Twine("!foldl list must be a list, but is of type '") +
2281 List->getType()->getAsString());
2282 return nullptr;
2283 }
2284
2285 if (Lex.getCode() != tgtok::comma) {
2286 TokError(Msg: "expected ',' in !foldl");
2287 return nullptr;
2288 }
2289
2290 if (Lex.Lex() != tgtok::Id) { // eat the ','
2291 TokError(Msg: "third argument of !foldl must be an identifier");
2292 return nullptr;
2293 }
2294
2295 const Init *A = StringInit::get(RK&: Records, Lex.getCurStrVal());
2296 if (CurRec && CurRec->getValue(Name: A)) {
2297 TokError(Msg: Twine("left !foldl variable '") + A->getAsString() +
2298 "' already defined");
2299 return nullptr;
2300 }
2301
2302 if (Lex.Lex() != tgtok::comma) { // eat the id
2303 TokError(Msg: "expected ',' in !foldl");
2304 return nullptr;
2305 }
2306
2307 if (Lex.Lex() != tgtok::Id) { // eat the ','
2308 TokError(Msg: "fourth argument of !foldl must be an identifier");
2309 return nullptr;
2310 }
2311
2312 const Init *B = StringInit::get(RK&: Records, Lex.getCurStrVal());
2313 if (CurRec && CurRec->getValue(Name: B)) {
2314 TokError(Msg: Twine("right !foldl variable '") + B->getAsString() +
2315 "' already defined");
2316 return nullptr;
2317 }
2318
2319 if (Lex.Lex() != tgtok::comma) { // eat the id
2320 TokError(Msg: "expected ',' in !foldl");
2321 return nullptr;
2322 }
2323 Lex.Lex(); // eat the ','
2324
2325 // We need to create a temporary record to provide a scope for the
2326 // two variables.
2327 std::unique_ptr<Record> ParseRecTmp;
2328 Record *ParseRec = CurRec;
2329 if (!ParseRec) {
2330 ParseRecTmp =
2331 std::make_unique<Record>(args: ".parse", args: ArrayRef<SMLoc>{}, args&: Records);
2332 ParseRec = ParseRecTmp.get();
2333 }
2334
2335 TGVarScope *FoldScope = PushScope(Rec: ParseRec);
2336 ParseRec->addValue(RV: RecordVal(A, Start->getType(), RecordVal::FK_Normal));
2337 ParseRec->addValue(
2338 RV: RecordVal(B, ListType->getElementType(), RecordVal::FK_Normal));
2339 const Init *ExprUntyped = ParseValue(CurRec: ParseRec);
2340 ParseRec->removeValue(Name: A);
2341 ParseRec->removeValue(Name: B);
2342 PopScope(ExpectedStackTop: FoldScope);
2343 if (!ExprUntyped)
2344 return nullptr;
2345
2346 const auto *Expr = dyn_cast<TypedInit>(Val: ExprUntyped);
2347 if (!Expr) {
2348 TokError(Msg: "could not get type of !foldl expression");
2349 return nullptr;
2350 }
2351
2352 if (Expr->getType() != Start->getType()) {
2353 TokError(Msg: Twine("!foldl expression must be of same type as start (") +
2354 Start->getType()->getAsString() + "), but is of type " +
2355 Expr->getType()->getAsString());
2356 return nullptr;
2357 }
2358
2359 if (!consume(K: tgtok::r_paren)) {
2360 TokError(Msg: "expected ')' in fold operator");
2361 return nullptr;
2362 }
2363
2364 return FoldOpInit::get(Start, List, A, B, Expr, Type: Start->getType())
2365 ->Fold(CurRec);
2366 }
2367 }
2368}
2369
2370/// ParseOperatorType - Parse a type for an operator. This returns
2371/// null on error.
2372///
2373/// OperatorType ::= '<' Type '>'
2374///
2375const RecTy *TGParser::ParseOperatorType() {
2376 const RecTy *Type = nullptr;
2377
2378 if (!consume(K: tgtok::less)) {
2379 TokError(Msg: "expected type name for operator");
2380 return nullptr;
2381 }
2382
2383 if (Lex.getCode() == tgtok::Code)
2384 TokError(Msg: "the 'code' type is not allowed in bang operators; use 'string'");
2385
2386 Type = ParseType();
2387
2388 if (!Type) {
2389 TokError(Msg: "expected type name for operator");
2390 return nullptr;
2391 }
2392
2393 if (!consume(K: tgtok::greater)) {
2394 TokError(Msg: "expected type name for operator");
2395 return nullptr;
2396 }
2397
2398 return Type;
2399}
2400
2401/// Parse the !substr operation. Return null on error.
2402///
2403/// Substr ::= !substr(string, start-int [, length-int]) => string
2404const Init *TGParser::ParseOperationSubstr(Record *CurRec,
2405 const RecTy *ItemType) {
2406 TernOpInit::TernaryOp Code = TernOpInit::SUBSTR;
2407 const RecTy *Type = StringRecTy::get(RK&: Records);
2408
2409 Lex.Lex(); // eat the operation
2410
2411 if (!consume(K: tgtok::l_paren)) {
2412 TokError(Msg: "expected '(' after !substr operator");
2413 return nullptr;
2414 }
2415
2416 const Init *LHS = ParseValue(CurRec);
2417 if (!LHS)
2418 return nullptr;
2419
2420 if (!consume(K: tgtok::comma)) {
2421 TokError(Msg: "expected ',' in !substr operator");
2422 return nullptr;
2423 }
2424
2425 SMLoc MHSLoc = Lex.getLoc();
2426 const Init *MHS = ParseValue(CurRec);
2427 if (!MHS)
2428 return nullptr;
2429
2430 SMLoc RHSLoc = Lex.getLoc();
2431 const Init *RHS;
2432 if (consume(K: tgtok::comma)) {
2433 RHSLoc = Lex.getLoc();
2434 RHS = ParseValue(CurRec);
2435 if (!RHS)
2436 return nullptr;
2437 } else {
2438 RHS = IntInit::get(RK&: Records, V: std::numeric_limits<int64_t>::max());
2439 }
2440
2441 if (!consume(K: tgtok::r_paren)) {
2442 TokError(Msg: "expected ')' in !substr operator");
2443 return nullptr;
2444 }
2445
2446 if (ItemType && !Type->typeIsConvertibleTo(RHS: ItemType)) {
2447 Error(L: RHSLoc, Msg: Twine("expected value of type '") + ItemType->getAsString() +
2448 "', got '" + Type->getAsString() + "'");
2449 }
2450
2451 const auto *LHSt = dyn_cast<TypedInit>(Val: LHS);
2452 if (!LHSt && !isa<UnsetInit>(Val: LHS)) {
2453 TokError(Msg: "could not determine type of the string in !substr");
2454 return nullptr;
2455 }
2456 if (LHSt && !isa<StringRecTy>(Val: LHSt->getType())) {
2457 TokError(Msg: Twine("expected string, got type '") +
2458 LHSt->getType()->getAsString() + "'");
2459 return nullptr;
2460 }
2461
2462 const auto *MHSt = dyn_cast<TypedInit>(Val: MHS);
2463 if (!MHSt && !isa<UnsetInit>(Val: MHS)) {
2464 TokError(Msg: "could not determine type of the start position in !substr");
2465 return nullptr;
2466 }
2467 if (MHSt && !isa<IntRecTy>(Val: MHSt->getType())) {
2468 Error(L: MHSLoc, Msg: Twine("expected int, got type '") +
2469 MHSt->getType()->getAsString() + "'");
2470 return nullptr;
2471 }
2472
2473 if (RHS) {
2474 const auto *RHSt = dyn_cast<TypedInit>(Val: RHS);
2475 if (!RHSt && !isa<UnsetInit>(Val: RHS)) {
2476 TokError(Msg: "could not determine type of the length in !substr");
2477 return nullptr;
2478 }
2479 if (RHSt && !isa<IntRecTy>(Val: RHSt->getType())) {
2480 TokError(Msg: Twine("expected int, got type '") +
2481 RHSt->getType()->getAsString() + "'");
2482 return nullptr;
2483 }
2484 }
2485
2486 return (TernOpInit::get(opc: Code, lhs: LHS, mhs: MHS, rhs: RHS, Type))->Fold(CurRec);
2487}
2488
2489/// Parse the !find operation. Return null on error.
2490///
2491/// Find ::= !find(string, string [, start-int]) => int
2492const Init *TGParser::ParseOperationFind(Record *CurRec,
2493 const RecTy *ItemType) {
2494 TernOpInit::TernaryOp Code = TernOpInit::FIND;
2495 const RecTy *Type = IntRecTy::get(RK&: Records);
2496
2497 Lex.Lex(); // eat the operation
2498
2499 if (!consume(K: tgtok::l_paren)) {
2500 TokError(Msg: "expected '(' after !find operator");
2501 return nullptr;
2502 }
2503
2504 const Init *LHS = ParseValue(CurRec);
2505 if (!LHS)
2506 return nullptr;
2507
2508 if (!consume(K: tgtok::comma)) {
2509 TokError(Msg: "expected ',' in !find operator");
2510 return nullptr;
2511 }
2512
2513 SMLoc MHSLoc = Lex.getLoc();
2514 const Init *MHS = ParseValue(CurRec);
2515 if (!MHS)
2516 return nullptr;
2517
2518 SMLoc RHSLoc = Lex.getLoc();
2519 const Init *RHS;
2520 if (consume(K: tgtok::comma)) {
2521 RHSLoc = Lex.getLoc();
2522 RHS = ParseValue(CurRec);
2523 if (!RHS)
2524 return nullptr;
2525 } else {
2526 RHS = IntInit::get(RK&: Records, V: 0);
2527 }
2528
2529 if (!consume(K: tgtok::r_paren)) {
2530 TokError(Msg: "expected ')' in !find operator");
2531 return nullptr;
2532 }
2533
2534 if (ItemType && !Type->typeIsConvertibleTo(RHS: ItemType)) {
2535 Error(L: RHSLoc, Msg: Twine("expected value of type '") + ItemType->getAsString() +
2536 "', got '" + Type->getAsString() + "'");
2537 }
2538
2539 const auto *LHSt = dyn_cast<TypedInit>(Val: LHS);
2540 if (!LHSt && !isa<UnsetInit>(Val: LHS)) {
2541 TokError(Msg: "could not determine type of the source string in !find");
2542 return nullptr;
2543 }
2544 if (LHSt && !isa<StringRecTy>(Val: LHSt->getType())) {
2545 TokError(Msg: Twine("expected string, got type '") +
2546 LHSt->getType()->getAsString() + "'");
2547 return nullptr;
2548 }
2549
2550 const auto *MHSt = dyn_cast<TypedInit>(Val: MHS);
2551 if (!MHSt && !isa<UnsetInit>(Val: MHS)) {
2552 TokError(Msg: "could not determine type of the target string in !find");
2553 return nullptr;
2554 }
2555 if (MHSt && !isa<StringRecTy>(Val: MHSt->getType())) {
2556 Error(L: MHSLoc, Msg: Twine("expected string, got type '") +
2557 MHSt->getType()->getAsString() + "'");
2558 return nullptr;
2559 }
2560
2561 if (RHS) {
2562 const auto *RHSt = dyn_cast<TypedInit>(Val: RHS);
2563 if (!RHSt && !isa<UnsetInit>(Val: RHS)) {
2564 TokError(Msg: "could not determine type of the start position in !find");
2565 return nullptr;
2566 }
2567 if (RHSt && !isa<IntRecTy>(Val: RHSt->getType())) {
2568 TokError(Msg: Twine("expected int, got type '") +
2569 RHSt->getType()->getAsString() + "'");
2570 return nullptr;
2571 }
2572 }
2573
2574 return (TernOpInit::get(opc: Code, lhs: LHS, mhs: MHS, rhs: RHS, Type))->Fold(CurRec);
2575}
2576
2577/// Parse the !foreach, !filter, and !sort operations. Return null on error.
2578///
2579/// ForEach ::= !foreach(ID, list-or-dag, expr) => list<expr type>
2580/// Filter ::= !filter(ID, list, predicate) ==> list<list type>
2581/// Sort ::= !sort(ID, list, key-expr) ==> list<list type>
2582const Init *TGParser::ParseOperationListComprehension(Record *CurRec,
2583 const RecTy *ItemType) {
2584 SMLoc OpLoc = Lex.getLoc();
2585 tgtok::TokKind Operation = Lex.getCode();
2586 Lex.Lex(); // eat the operation
2587 if (Lex.getCode() != tgtok::l_paren) {
2588 TokError(Msg: "expected '(' after !foreach/!filter");
2589 return nullptr;
2590 }
2591
2592 if (Lex.Lex() != tgtok::Id) { // eat the '('
2593 TokError(Msg: "first argument of !foreach/!filter must be an identifier");
2594 return nullptr;
2595 }
2596
2597 const Init *LHS = StringInit::get(RK&: Records, Lex.getCurStrVal());
2598 Lex.Lex(); // eat the ID.
2599
2600 if (CurRec && CurRec->getValue(Name: LHS)) {
2601 TokError(Msg: Twine("iteration variable '") + LHS->getAsString() +
2602 "' is already defined");
2603 return nullptr;
2604 }
2605
2606 if (!consume(K: tgtok::comma)) {
2607 TokError(Msg: "expected ',' in !foreach/!filter");
2608 return nullptr;
2609 }
2610
2611 const Init *MHS = ParseValue(CurRec);
2612 if (!MHS)
2613 return nullptr;
2614
2615 if (!consume(K: tgtok::comma)) {
2616 TokError(Msg: "expected ',' in !foreach/!filter");
2617 return nullptr;
2618 }
2619
2620 const auto *MHSt = dyn_cast<TypedInit>(Val: MHS);
2621 if (!MHSt) {
2622 TokError(Msg: "could not get type of !foreach/!filter list or dag");
2623 return nullptr;
2624 }
2625
2626 const RecTy *InEltType = nullptr;
2627 const RecTy *ExprEltType = nullptr;
2628 bool IsDAG = false;
2629
2630 if (const auto *InListTy = dyn_cast<ListRecTy>(Val: MHSt->getType())) {
2631 InEltType = InListTy->getElementType();
2632 if (ItemType) {
2633 if (const auto *OutListTy = dyn_cast<ListRecTy>(Val: ItemType)) {
2634 switch (Operation) {
2635 case tgtok::XForEach:
2636 ExprEltType = OutListTy->getElementType();
2637 break;
2638 case tgtok::XFilter:
2639 ExprEltType = IntRecTy::get(RK&: Records);
2640 break;
2641 case tgtok::XSort:
2642 ExprEltType = nullptr;
2643 break;
2644 default:
2645 llvm_unreachable("unexpected token");
2646 }
2647 } else {
2648 Error(L: OpLoc, Msg: "expected value of type '" +
2649 Twine(ItemType->getAsString()) +
2650 "', but got list type");
2651 return nullptr;
2652 }
2653 }
2654 } else if (const auto *InDagTy = dyn_cast<DagRecTy>(Val: MHSt->getType())) {
2655 switch (Operation) {
2656 case tgtok::XFilter:
2657 TokError(Msg: "!filter must have a list argument");
2658 return nullptr;
2659 case tgtok::XSort:
2660 TokError(Msg: "!sort must have a list argument");
2661 return nullptr;
2662 case tgtok::XForEach:
2663 break;
2664 default:
2665 llvm_unreachable("unexpected token");
2666 }
2667 InEltType = InDagTy;
2668 if (ItemType && !isa<DagRecTy>(Val: ItemType)) {
2669 Error(L: OpLoc, Msg: "expected value of type '" + Twine(ItemType->getAsString()) +
2670 "', but got dag type");
2671 return nullptr;
2672 }
2673 IsDAG = true;
2674 } else {
2675 switch (Operation) {
2676 case tgtok::XForEach:
2677 TokError(Msg: "!foreach must have a list or dag argument");
2678 return nullptr;
2679 case tgtok::XFilter:
2680 TokError(Msg: "!filter must have a list argument");
2681 return nullptr;
2682 case tgtok::XSort:
2683 TokError(Msg: "!sort must have a list argument");
2684 return nullptr;
2685 default:
2686 llvm_unreachable("unexpected token");
2687 }
2688 }
2689
2690 // We need to create a temporary record to provide a scope for the
2691 // iteration variable.
2692 std::unique_ptr<Record> ParseRecTmp;
2693 Record *ParseRec = CurRec;
2694 if (!ParseRec) {
2695 ParseRecTmp =
2696 std::make_unique<Record>(args: ".parse", args: ArrayRef<SMLoc>{}, args&: Records);
2697 ParseRec = ParseRecTmp.get();
2698 }
2699 TGVarScope *TempScope = PushScope(Rec: ParseRec);
2700 ParseRec->addValue(RV: RecordVal(LHS, InEltType, RecordVal::FK_Normal));
2701 const Init *RHS = ParseValue(CurRec: ParseRec, ItemType: ExprEltType);
2702 ParseRec->removeValue(Name: LHS);
2703 PopScope(ExpectedStackTop: TempScope);
2704 if (!RHS)
2705 return nullptr;
2706
2707 if (!consume(K: tgtok::r_paren)) {
2708 TokError(Msg: "expected ')' in !foreach/!filter");
2709 return nullptr;
2710 }
2711
2712 const RecTy *OutType;
2713 TernOpInit::TernaryOp Opc;
2714 switch (Operation) {
2715 case tgtok::XForEach:
2716 Opc = TernOpInit::FOREACH;
2717 if (IsDAG) {
2718 OutType = InEltType;
2719 } else {
2720 const auto *RHSt = dyn_cast<TypedInit>(Val: RHS);
2721 if (!RHSt) {
2722 TokError(Msg: "could not get type of !foreach result expression");
2723 return nullptr;
2724 }
2725 OutType = RHSt->getType()->getListTy();
2726 }
2727 break;
2728 case tgtok::XFilter:
2729 Opc = TernOpInit::FILTER;
2730 OutType = InEltType->getListTy();
2731 break;
2732 case tgtok::XSort:
2733 Opc = TernOpInit::SORT;
2734 OutType = InEltType->getListTy();
2735 break;
2736 default:
2737 llvm_unreachable("unexpected token");
2738 }
2739 return (TernOpInit::get(opc: Opc, lhs: LHS, mhs: MHS, rhs: RHS, Type: OutType))->Fold(CurRec);
2740}
2741
2742/// Unify the types of \p Inits, treating UnsetInits as wildcards. Returns
2743/// std::nullopt on type conflict (a TokError has been emitted). Returns
2744/// optional containing nullptr if every Init is unset (no error emitted —
2745/// caller decides whether that is acceptable).
2746std::optional<const RecTy *>
2747TGParser::resolveInitTypes(ArrayRef<const Init *> Inits, const Twine &ErrCtx) {
2748 const RecTy *Type = nullptr;
2749 for (const Init *V : Inits) {
2750 if (isa<UnsetInit>(Val: V))
2751 continue;
2752
2753 const RecTy *VTy = nullptr;
2754 if (const auto *Vt = dyn_cast<TypedInit>(Val: V))
2755 VTy = Vt->getType();
2756
2757 if (!Type) {
2758 Type = VTy;
2759 continue;
2760 }
2761 const RecTy *RType = resolveTypes(T1: Type, T2: VTy);
2762 if (!RType) {
2763 TokError(Msg: Twine("inconsistent types '") + Type->getAsString() + "' and '" +
2764 VTy->getAsString() + "' " + ErrCtx);
2765 return std::nullopt;
2766 }
2767 Type = RType;
2768 }
2769 return Type;
2770}
2771
2772/// Parse the !cond operation. Return null on error.
2773///
2774/// Cond ::= !cond([cond: val,]+) => val type
2775const Init *TGParser::ParseOperationCond(Record *CurRec,
2776 const RecTy *ItemType) {
2777 Lex.Lex(); // eat the operation 'cond'
2778
2779 if (!consume(K: tgtok::l_paren)) {
2780 TokError(Msg: "expected '(' after !cond operator");
2781 return nullptr;
2782 }
2783
2784 // Parse through '[Case: Val,]+'
2785 SmallVector<const Init *, 4> Cases;
2786 SmallVector<const Init *, 4> Vals;
2787 while (true) {
2788 if (consume(K: tgtok::r_paren))
2789 break;
2790
2791 const Init *V = ParseValue(CurRec);
2792 if (!V)
2793 return nullptr;
2794 Cases.push_back(Elt: V);
2795
2796 if (!consume(K: tgtok::colon)) {
2797 TokError(Msg: "expected ':' following a condition in !cond operator");
2798 return nullptr;
2799 }
2800
2801 V = ParseValue(CurRec, ItemType);
2802 if (!V)
2803 return nullptr;
2804 Vals.push_back(Elt: V);
2805
2806 if (consume(K: tgtok::r_paren))
2807 break;
2808
2809 if (!consume(K: tgtok::comma)) {
2810 TokError(Msg: "expected ',' or ')' following a value in !cond operator");
2811 return nullptr;
2812 }
2813 }
2814
2815 if (Cases.size() < 1) {
2816 TokError(
2817 Msg: "there should be at least 1 'condition : value' in the !cond operator");
2818 return nullptr;
2819 }
2820
2821 // resolve type
2822 std::optional<const RecTy *> TypeOpt = resolveInitTypes(Inits: Vals, ErrCtx: "for !cond");
2823 if (!TypeOpt)
2824 return nullptr;
2825 const RecTy *Type = *TypeOpt;
2826 if (!Type) {
2827 TokError(Msg: "could not determine type for !cond from its arguments");
2828 return nullptr;
2829 }
2830 return CondOpInit::get(Conds: Cases, Values: Vals, Type)->Fold(CurRec);
2831}
2832
2833/// Switch ::= !switch(key, [case : val,]+ default-val) => val type
2834const Init *TGParser::ParseOperationSwitch(Record *CurRec,
2835 const RecTy *ItemType) {
2836 Lex.Lex(); // eat the operation 'switch'
2837
2838 if (!consume(K: tgtok::l_paren)) {
2839 TokError(Msg: "expected '(' after !switch operator");
2840 return nullptr;
2841 }
2842
2843 SmallVector<const Init *, 4> KeyAndCases;
2844 const Init *Key = ParseValue(CurRec);
2845 if (!Key)
2846 return nullptr;
2847 // Push the key as the first element of the vector for type-checking.
2848 KeyAndCases.push_back(Elt: Key);
2849
2850 if (!consume(K: tgtok::comma)) {
2851 TokError(Msg: "expected ',' after key in !switch operator");
2852 return nullptr;
2853 }
2854
2855 // After parsing each Value, the next token disambiguates: ')' means it was
2856 // the default; ':' means it was a case key whose value follows.
2857 SmallVector<const Init *, 4> Vals;
2858 while (true) {
2859 const Init *V = ParseValue(CurRec);
2860 if (!V)
2861 return nullptr;
2862
2863 // Parse the mandatory default value.
2864 if (consume(K: tgtok::r_paren)) {
2865 if (ItemType) {
2866 // The default value was parsed without the ItemType hint. Coerce it now
2867 // to match case-value parses.
2868 if (const Init *Coerced = V->convertInitializerTo(Ty: ItemType))
2869 V = Coerced;
2870 }
2871 // Push the default value as the last element of the vector for
2872 // type-checking.
2873 Vals.push_back(Elt: V);
2874 break;
2875 }
2876
2877 if (!consume(K: tgtok::colon)) {
2878 TokError(Msg: "expected ':' after case key, or ')' to close !switch operator");
2879 return nullptr;
2880 }
2881 KeyAndCases.push_back(Elt: V);
2882
2883 V = ParseValue(CurRec, ItemType);
2884 if (!V)
2885 return nullptr;
2886 Vals.push_back(Elt: V);
2887
2888 if (!consume(K: tgtok::comma)) {
2889 TokError(Msg: "expected ',' after case value in !switch operator");
2890 return nullptr;
2891 }
2892 }
2893 assert(KeyAndCases.size() == Vals.size() &&
2894 "inconsistent keys and values for !switch");
2895
2896 if (KeyAndCases.size() < 2) {
2897 TokError(
2898 Msg: "there should be at least 1 'case: value' in the !switch operator");
2899 return nullptr;
2900 }
2901
2902 // Check value type consistency.
2903 std::optional<const RecTy *> ValTypeOpt =
2904 resolveInitTypes(Inits: Vals, ErrCtx: "for !switch values");
2905 if (!ValTypeOpt)
2906 return nullptr;
2907 const RecTy *ValType = *ValTypeOpt;
2908 if (!ValType) {
2909 TokError(Msg: "could not determine type for !switch from its arguments");
2910 return nullptr;
2911 }
2912
2913 // Check key/case-key type consistency. We only care about conflicts here.
2914 // The all-unset case should be fine because no downstream code uses the key
2915 // type.
2916 if (!resolveInitTypes(Inits: KeyAndCases, ErrCtx: "between !switch key and case keys"))
2917 return nullptr;
2918
2919 // Reduce !switch to !cond: each case becomes !eq(Key, c_i) -> v_i, with a
2920 // trailing 'true' arm carrying the default value.
2921 SmallVector<const Init *, 4> Conds;
2922 size_t ValsSize = Vals.size();
2923 Conds.reserve(N: ValsSize);
2924 const RecTy *BitTy = BitRecTy::get(RK&: Records);
2925 for (const Init *CaseKey : llvm::drop_begin(RangeOrContainer&: KeyAndCases))
2926 Conds.push_back(
2927 Elt: BinOpInit::get(opc: BinOpInit::EQ, lhs: Key, rhs: CaseKey, Type: BitTy)->Fold(CurRec));
2928 Conds.push_back(Elt: IntInit::get(RK&: Records, V: 1));
2929 assert(Conds.size() == ValsSize && "inconsistent !switch to !cond reduction");
2930 return CondOpInit::get(Conds, Values: Vals, Type: ValType)->Fold(CurRec);
2931}
2932
2933/// ParseSimpleValue - Parse a tblgen value. This returns null on error.
2934///
2935/// SimpleValue ::= IDValue
2936/// SimpleValue ::= INTVAL
2937/// SimpleValue ::= STRVAL+
2938/// SimpleValue ::= CODEFRAGMENT
2939/// SimpleValue ::= '?'
2940/// SimpleValue ::= '{' ValueList '}'
2941/// SimpleValue ::= ID '<' ValueListNE '>'
2942/// SimpleValue ::= '[' ValueList ']'
2943/// SimpleValue ::= '(' IDValue DagArgList ')'
2944/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')'
2945/// SimpleValue ::= ADDTOK '(' Value ',' Value ')'
2946/// SimpleValue ::= DIVTOK '(' Value ',' Value ')'
2947/// SimpleValue ::= SUBTOK '(' Value ',' Value ')'
2948/// SimpleValue ::= SHLTOK '(' Value ',' Value ')'
2949/// SimpleValue ::= SRATOK '(' Value ',' Value ')'
2950/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
2951/// SimpleValue ::= LISTCONCATTOK '(' Value ',' Value ')'
2952/// SimpleValue ::= LISTSPLATTOK '(' Value ',' Value ')'
2953/// SimpleValue ::= LISTREMOVETOK '(' Value ',' Value ')'
2954/// SimpleValue ::= RANGE '(' Value ')'
2955/// SimpleValue ::= RANGE '(' Value ',' Value ')'
2956/// SimpleValue ::= RANGE '(' Value ',' Value ',' Value ')'
2957/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
2958/// SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
2959///
2960const Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
2961 IDParseMode Mode) {
2962 const Init *R = nullptr;
2963 tgtok::TokKind Code = Lex.getCode();
2964
2965 // Parse bang operators.
2966 if (tgtok::isBangOperator(Kind: Code))
2967 return ParseOperation(CurRec, ItemType);
2968
2969 switch (Code) {
2970 default:
2971 TokError(Msg: "Unknown or reserved token when parsing a value");
2972 break;
2973
2974 case tgtok::TrueVal:
2975 R = IntInit::get(RK&: Records, V: 1);
2976 Lex.Lex();
2977 break;
2978 case tgtok::FalseVal:
2979 R = IntInit::get(RK&: Records, V: 0);
2980 Lex.Lex();
2981 break;
2982 case tgtok::IntVal:
2983 R = IntInit::get(RK&: Records, V: Lex.getCurIntVal());
2984 Lex.Lex();
2985 break;
2986 case tgtok::BinaryIntVal: {
2987 auto BinaryVal = Lex.getCurBinaryIntVal();
2988 SmallVector<Init *, 16> Bits(BinaryVal.second);
2989 for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2990 Bits[i] = BitInit::get(RK&: Records, V: BinaryVal.first & (1LL << i));
2991 R = BitsInit::get(RK&: Records, Range: Bits);
2992 Lex.Lex();
2993 break;
2994 }
2995 case tgtok::StrVal: {
2996 std::string Val = Lex.getCurStrVal();
2997 Lex.Lex();
2998
2999 // Handle multiple consecutive concatenated strings.
3000 while (Lex.getCode() == tgtok::StrVal) {
3001 Val += Lex.getCurStrVal();
3002 Lex.Lex();
3003 }
3004
3005 R = StringInit::get(RK&: Records, Val);
3006 break;
3007 }
3008 case tgtok::CodeFragment:
3009 R = StringInit::get(RK&: Records, Lex.getCurStrVal(), Fmt: StringInit::SF_Code);
3010 Lex.Lex();
3011 break;
3012 case tgtok::question:
3013 R = UnsetInit::get(RK&: Records);
3014 Lex.Lex();
3015 break;
3016 case tgtok::Id: {
3017 SMRange NameLoc = Lex.getLocRange();
3018 const StringInit *Name = StringInit::get(RK&: Records, Lex.getCurStrVal());
3019 tgtok::TokKind Next = Lex.Lex();
3020 if (Next == tgtok::equal) // Named argument.
3021 return Name;
3022 if (Next != tgtok::less) // consume the Id.
3023 return ParseIDValue(CurRec, Name, NameLoc, Mode); // Value ::= IDValue
3024
3025 // Value ::= CLASSID '<' ArgValueList '>' (CLASSID has been consumed)
3026 // This is supposed to synthesize a new anonymous definition, deriving
3027 // from the class with the template arguments, but no body.
3028 const Record *Class = Records.getClass(Name: Name->getValue());
3029 if (!Class) {
3030 Error(L: NameLoc.Start,
3031 Msg: "Expected a class name, got '" + Name->getValue() + "'");
3032 return nullptr;
3033 }
3034
3035 SmallVector<const ArgumentInit *, 8> Args;
3036 SmallVector<SMLoc> ArgLocs;
3037 Lex.Lex(); // consume the <
3038 if (ParseTemplateArgValueList(Result&: Args, ArgLocs, CurRec, ArgsRec: Class))
3039 return nullptr; // Error parsing value list.
3040
3041 if (CheckTemplateArgValues(Values&: Args, ValuesLocs: ArgLocs, ArgsRec: Class))
3042 return nullptr; // Error checking template argument values.
3043
3044 if (resolveArguments(Rec: Class, ArgValues: Args, Loc: NameLoc.Start))
3045 return nullptr;
3046
3047 if (TrackReferenceLocs)
3048 Class->appendReferenceLoc(Loc: NameLoc);
3049 return VarDefInit::get(Loc: NameLoc.Start, Class, Args)->Fold();
3050 }
3051 case tgtok::l_brace: { // Value ::= '{' ValueList '}'
3052 SMLoc BraceLoc = Lex.getLoc();
3053 Lex.Lex(); // eat the '{'
3054 SmallVector<const Init *, 16> Vals;
3055
3056 if (Lex.getCode() != tgtok::r_brace) {
3057 ParseValueList(Result&: Vals, CurRec);
3058 if (Vals.empty())
3059 return nullptr;
3060 }
3061 if (!consume(K: tgtok::r_brace)) {
3062 TokError(Msg: "expected '}' at end of bit list value");
3063 return nullptr;
3064 }
3065
3066 SmallVector<const Init *, 16> NewBits;
3067
3068 // As we parse { a, b, ... }, 'a' is the highest bit, but we parse it
3069 // first. We'll first read everything in to a vector, then we can reverse
3070 // it to get the bits in the correct order for the BitsInit value.
3071 for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
3072 // FIXME: The following two loops would not be duplicated
3073 // if the API was a little more orthogonal.
3074
3075 // bits<n> values are allowed to initialize n bits.
3076 if (const auto *BI = dyn_cast<BitsInit>(Val: Vals[i])) {
3077 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
3078 NewBits.push_back(Elt: BI->getBit(Bit: (e - i) - 1));
3079 continue;
3080 }
3081 // bits<n> can also come from variable initializers.
3082 if (const auto *VI = dyn_cast<VarInit>(Val: Vals[i])) {
3083 if (const auto *BitsRec = dyn_cast<BitsRecTy>(Val: VI->getType())) {
3084 for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
3085 NewBits.push_back(Elt: VI->getBit(Bit: (e - i) - 1));
3086 continue;
3087 }
3088 // Fallthrough to try convert this to a bit.
3089 }
3090 // All other values must be convertible to just a single bit.
3091 const Init *Bit = Vals[i]->getCastTo(Ty: BitRecTy::get(RK&: Records));
3092 if (!Bit) {
3093 Error(L: BraceLoc, Msg: "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
3094 ") is not convertable to a bit");
3095 return nullptr;
3096 }
3097 NewBits.push_back(Elt: Bit);
3098 }
3099 std::reverse(first: NewBits.begin(), last: NewBits.end());
3100 return BitsInit::get(RK&: Records, Range: NewBits);
3101 }
3102 case tgtok::l_square: { // Value ::= '[' ValueList ']'
3103 Lex.Lex(); // eat the '['
3104 SmallVector<const Init *, 16> Vals;
3105
3106 const RecTy *DeducedEltTy = nullptr;
3107 const ListRecTy *GivenListTy = nullptr;
3108
3109 if (ItemType) {
3110 const auto *ListType = dyn_cast<ListRecTy>(Val: ItemType);
3111 if (!ListType) {
3112 TokError(Msg: Twine("Encountered a list when expecting a ") +
3113 ItemType->getAsString());
3114 return nullptr;
3115 }
3116 GivenListTy = ListType;
3117 }
3118
3119 if (Lex.getCode() != tgtok::r_square) {
3120 ParseValueList(Result&: Vals, CurRec,
3121 ItemType: GivenListTy ? GivenListTy->getElementType() : nullptr);
3122 if (Vals.empty())
3123 return nullptr;
3124 }
3125 if (!consume(K: tgtok::r_square)) {
3126 TokError(Msg: "expected ']' at end of list value");
3127 return nullptr;
3128 }
3129
3130 const RecTy *GivenEltTy = nullptr;
3131 if (consume(K: tgtok::less)) {
3132 // Optional list element type
3133 GivenEltTy = ParseType();
3134 if (!GivenEltTy) {
3135 // Couldn't parse element type
3136 return nullptr;
3137 }
3138
3139 if (!consume(K: tgtok::greater)) {
3140 TokError(Msg: "expected '>' at end of list element type");
3141 return nullptr;
3142 }
3143 }
3144
3145 // Check elements
3146 const RecTy *EltTy = nullptr;
3147 for (const Init *V : Vals) {
3148 const auto *TArg = dyn_cast<TypedInit>(Val: V);
3149 if (TArg) {
3150 if (EltTy) {
3151 EltTy = resolveTypes(T1: EltTy, T2: TArg->getType());
3152 if (!EltTy) {
3153 TokError(Msg: "Incompatible types in list elements");
3154 return nullptr;
3155 }
3156 } else {
3157 EltTy = TArg->getType();
3158 }
3159 }
3160 }
3161
3162 if (GivenEltTy) {
3163 if (EltTy) {
3164 // Verify consistency
3165 if (!EltTy->typeIsConvertibleTo(RHS: GivenEltTy)) {
3166 TokError(Msg: "Incompatible types in list elements");
3167 return nullptr;
3168 }
3169 }
3170 EltTy = GivenEltTy;
3171 }
3172
3173 if (!EltTy) {
3174 if (!ItemType) {
3175 TokError(Msg: "No type for list");
3176 return nullptr;
3177 }
3178 DeducedEltTy = GivenListTy->getElementType();
3179 } else {
3180 // Make sure the deduced type is compatible with the given type
3181 if (GivenListTy) {
3182 if (!EltTy->typeIsConvertibleTo(RHS: GivenListTy->getElementType())) {
3183 TokError(Msg: Twine("Element type mismatch for list: element type '") +
3184 EltTy->getAsString() + "' not convertible to '" +
3185 GivenListTy->getElementType()->getAsString());
3186 return nullptr;
3187 }
3188 }
3189 DeducedEltTy = EltTy;
3190 }
3191
3192 return ListInit::get(Range: Vals, EltTy: DeducedEltTy);
3193 }
3194 case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
3195 // Value ::= '(' '[' ValueList ']' DagArgList ')'
3196 Lex.Lex(); // eat the '('
3197 if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&
3198 Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp &&
3199 Lex.getCode() != tgtok::l_square) {
3200 TokError(Msg: "expected identifier or list of value types in dag init");
3201 return nullptr;
3202 }
3203
3204 const Init *Operator = ParseValue(CurRec);
3205 if (!Operator)
3206 return nullptr;
3207
3208 // If the operator name is present, parse it.
3209 const StringInit *OperatorName = nullptr;
3210 if (consume(K: tgtok::colon)) {
3211 if (Lex.getCode() != tgtok::VarName) { // eat the ':'
3212 TokError(Msg: "expected variable name in dag operator");
3213 return nullptr;
3214 }
3215 OperatorName = StringInit::get(RK&: Records, Lex.getCurStrVal());
3216 Lex.Lex(); // eat the VarName.
3217 }
3218
3219 SmallVector<std::pair<const Init *, const StringInit *>, 8> DagArgs;
3220 if (Lex.getCode() != tgtok::r_paren) {
3221 ParseDagArgList(Result&: DagArgs, CurRec);
3222 if (DagArgs.empty())
3223 return nullptr;
3224 }
3225
3226 if (!consume(K: tgtok::r_paren)) {
3227 TokError(Msg: "expected ')' in dag init");
3228 return nullptr;
3229 }
3230
3231 return DagInit::get(V: Operator, VN: OperatorName, ArgAndNames: DagArgs);
3232 }
3233 }
3234
3235 return R;
3236}
3237
3238/// ParseValue - Parse a TableGen value. This returns null on error.
3239///
3240/// Value ::= SimpleValue ValueSuffix*
3241/// ValueSuffix ::= '{' BitList '}'
3242/// ValueSuffix ::= '[' SliceElements ']'
3243/// ValueSuffix ::= '.' ID
3244///
3245const Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
3246 IDParseMode Mode) {
3247 SMLoc LHSLoc = Lex.getLoc();
3248 const Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
3249 if (!Result)
3250 return nullptr;
3251
3252 // Parse the suffixes now if present.
3253 while (true) {
3254 switch (Lex.getCode()) {
3255 default:
3256 return Result;
3257 case tgtok::l_brace: {
3258 if (Mode == ParseNameMode)
3259 // This is the beginning of the object body.
3260 return Result;
3261
3262 SMLoc CurlyLoc = Lex.getLoc();
3263 Lex.Lex(); // eat the '{'
3264 SmallVector<unsigned, 16> Ranges;
3265 ParseRangeList(Result&: Ranges);
3266 if (Ranges.empty())
3267 return nullptr;
3268
3269 // Reverse the bitlist.
3270 std::reverse(first: Ranges.begin(), last: Ranges.end());
3271 Result = Result->convertInitializerBitRange(Bits: Ranges);
3272 if (!Result) {
3273 Error(L: CurlyLoc, Msg: "Invalid bit range for value");
3274 return nullptr;
3275 }
3276
3277 // Eat the '}'.
3278 if (!consume(K: tgtok::r_brace)) {
3279 TokError(Msg: "expected '}' at end of bit range list");
3280 return nullptr;
3281 }
3282 break;
3283 }
3284 case tgtok::l_square: {
3285 const auto *LHS = dyn_cast<TypedInit>(Val: Result);
3286 if (!LHS) {
3287 Error(L: LHSLoc, Msg: "Invalid value, list expected");
3288 return nullptr;
3289 }
3290
3291 const auto *LHSTy = dyn_cast<ListRecTy>(Val: LHS->getType());
3292 if (!LHSTy) {
3293 Error(L: LHSLoc, Msg: "Type '" + Twine(LHS->getType()->getAsString()) +
3294 "' is invalid, list expected");
3295 return nullptr;
3296 }
3297
3298 Lex.Lex(); // eat the '['
3299 const TypedInit *RHS = ParseSliceElements(CurRec, /*Single=*/true);
3300 if (!RHS)
3301 return nullptr;
3302
3303 if (isa<ListRecTy>(Val: RHS->getType())) {
3304 Result =
3305 BinOpInit::get(opc: BinOpInit::LISTSLICE, lhs: LHS, rhs: RHS, Type: LHSTy)->Fold(CurRec);
3306 } else {
3307 Result = BinOpInit::get(opc: BinOpInit::LISTELEM, lhs: LHS, rhs: RHS,
3308 Type: LHSTy->getElementType())
3309 ->Fold(CurRec);
3310 }
3311
3312 assert(Result);
3313
3314 // Eat the ']'.
3315 if (!consume(K: tgtok::r_square)) {
3316 TokError(Msg: "expected ']' at end of list slice");
3317 return nullptr;
3318 }
3319 break;
3320 }
3321 case tgtok::dot: {
3322 if (Lex.Lex() != tgtok::Id) { // eat the .
3323 TokError(Msg: "expected field identifier after '.'");
3324 return nullptr;
3325 }
3326 SMRange FieldNameLoc = Lex.getLocRange();
3327 const StringInit *FieldName =
3328 StringInit::get(RK&: Records, Lex.getCurStrVal());
3329 if (!Result->getFieldType(FieldName)) {
3330 TokError(Msg: "Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
3331 Result->getAsString() + "'");
3332 return nullptr;
3333 }
3334
3335 // Add a reference to this field if we know the record class.
3336 if (TrackReferenceLocs) {
3337 if (const auto *DI = dyn_cast<DefInit>(Val: Result)) {
3338 const RecordVal *V = DI->getDef()->getValue(Name: FieldName);
3339 const_cast<RecordVal *>(V)->addReferenceLoc(Loc: FieldNameLoc);
3340 } else if (const auto *TI = dyn_cast<TypedInit>(Val: Result)) {
3341 if (const auto *RecTy = dyn_cast<RecordRecTy>(Val: TI->getType())) {
3342 for (const Record *R : RecTy->getClasses())
3343 if (const auto *RV = R->getValue(Name: FieldName))
3344 const_cast<RecordVal *>(RV)->addReferenceLoc(Loc: FieldNameLoc);
3345 }
3346 }
3347 }
3348
3349 Result = FieldInit::get(R: Result, FN: 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>(Val: Result);
3357 if (!LHS) {
3358 Error(L: PasteLoc, Msg: "LHS of paste is not typed!");
3359 return nullptr;
3360 }
3361
3362 // Check if it's a 'listA # listB'
3363 if (isa<ListRecTy>(Val: 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, Mode: ParseValueMode);
3376 if (!RHSResult)
3377 return nullptr;
3378 Result = BinOpInit::getListConcat(lhs: LHS, rhs: 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(RK&: Records)) {
3387 auto CastLHS = dyn_cast<TypedInit>(
3388 Val: UnOpInit::get(opc: UnOpInit::CAST, lhs: LHS, Type: StringRecTy::get(RK&: Records))
3389 ->Fold(CurRec));
3390 if (!CastLHS) {
3391 Error(L: PasteLoc,
3392 Msg: 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(RK&: Records, "");
3411 break;
3412
3413 default:
3414 const Init *RHSResult = ParseValue(CurRec, ItemType: nullptr, Mode: ParseNameMode);
3415 if (!RHSResult)
3416 return nullptr;
3417 RHS = dyn_cast<TypedInit>(Val: RHSResult);
3418 if (!RHS) {
3419 Error(L: PasteLoc, Msg: "RHS of paste is not typed!");
3420 return nullptr;
3421 }
3422
3423 if (RHS->getType() != StringRecTy::get(RK&: Records)) {
3424 auto CastRHS = dyn_cast<TypedInit>(
3425 Val: UnOpInit::get(opc: UnOpInit::CAST, lhs: RHS, Type: StringRecTy::get(RK&: Records))
3426 ->Fold(CurRec));
3427 if (!CastRHS) {
3428 Error(L: PasteLoc,
3429 Msg: Twine("can't cast '") + RHS->getAsString() + "' to string");
3430 return nullptr;
3431 }
3432 RHS = CastRHS;
3433 }
3434
3435 break;
3436 }
3437
3438 Result = BinOpInit::getStrConcat(lhs: LHS, rhs: RHS);
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(RK&: Records, Lex.getCurStrVal());
3459 Result.emplace_back(Args: UnsetInit::get(RK&: Records), Args&: 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(Msg: "expected variable name in dag literal");
3474 Result.clear();
3475 return;
3476 }
3477 VarName = StringInit::get(RK&: Records, Lex.getCurStrVal());
3478 Lex.Lex(); // eat the VarName.
3479 }
3480
3481 Result.emplace_back(Args&: Val, Args&: VarName);
3482 }
3483 if (!consume(K: 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(Elt: ParseValue(CurRec, ItemType));
3497 if (!Result.back()) {
3498 Result.clear();
3499 return;
3500 }
3501
3502 while (consume(K: tgtok::comma)) {
3503 // ignore trailing comma for lists
3504 if (Lex.getCode() == tgtok::r_square)
3505 return;
3506 Result.push_back(Elt: 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(
3523 SmallVectorImpl<const ArgumentInit *> &Result,
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(K: 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(Msg: "Too many template arguments: " + utostr(X: ArgIndex + 1));
3536 return true;
3537 }
3538
3539 SMLoc ValueLoc = ArgLocs.emplace_back(Args: 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 ItemType: HasNamedArg ? nullptr : ArgsRec->getValue(Name: 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>(Val: Value))
3551 return Error(L: ValueLoc,
3552 Msg: "The name of named argument should be a valid identifier");
3553
3554 auto *Name = cast<StringInit>(Val: Value);
3555 const Init *QualifiedName = QualifyName(CurRec: *ArgsRec, Name);
3556 auto *NamedArg = ArgsRec->getValue(Name: QualifiedName);
3557 if (!NamedArg)
3558 return Error(L: ValueLoc,
3559 Msg: "Argument " + Name->getAsString() + " doesn't exist");
3560
3561 Lex.Lex(); // eat the '='.
3562 ValueLoc = Lex.getLoc();
3563 Value = ParseValue(CurRec, ItemType: NamedArg->getType());
3564 // Named value can't be uninitialized.
3565 if (isa<UnsetInit>(Val: Value))
3566 return Error(L: ValueLoc,
3567 Msg: "The value of named argument should be initialized, "
3568 "but we got '" +
3569 Value->getAsString() + "'");
3570
3571 Result.push_back(Elt: ArgumentInit::get(Value, Aux: QualifiedName));
3572 HasNamedArg = true;
3573 } else {
3574 // Positional arguments should be put before named arguments.
3575 if (HasNamedArg)
3576 return Error(L: ValueLoc,
3577 Msg: "Positional argument should be put before named argument");
3578
3579 Result.push_back(Elt: ArgumentInit::get(Value, Aux: ArgIndex));
3580 }
3581
3582 if (consume(K: tgtok::greater)) // end of argument list?
3583 return false;
3584 if (!consume(K: tgtok::comma))
3585 return TokError(Msg: "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(K: tgtok::Field);
3604
3605 const RecTy *Type = ParseType();
3606 if (!Type)
3607 return nullptr;
3608
3609 if (Lex.getCode() != tgtok::Id) {
3610 TokError(Msg: "Expected identifier in declaration");
3611 return nullptr;
3612 }
3613
3614 std::string Str = Lex.getCurStrVal();
3615 if (Str == "NAME") {
3616 TokError(Msg: "'" + Str + "' is a reserved variable name");
3617 return nullptr;
3618 }
3619
3620 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Name: Str)) {
3621 TokError(Msg: "local variable of this name already exists");
3622 return nullptr;
3623 }
3624
3625 SMLoc IdLoc = Lex.getLoc();
3626 const Init *DeclName = StringInit::get(RK&: Records, Str);
3627 Lex.Lex();
3628
3629 bool BadField;
3630 if (!ParsingTemplateArgs) { // def, possibly in a multiclass
3631 BadField = AddValue(CurRec, Loc: IdLoc,
3632 RV: RecordVal(DeclName, IdLoc, Type,
3633 HasField ? RecordVal::FK_NonconcreteOK
3634 : RecordVal::FK_Normal));
3635 } else if (CurRec) { // class template argument
3636 DeclName = QualifyName(CurRec: *CurRec, Name: DeclName);
3637 BadField =
3638 AddValue(CurRec, Loc: IdLoc,
3639 RV: RecordVal(DeclName, IdLoc, Type, RecordVal::FK_TemplateArg));
3640 } else { // multiclass template argument
3641 assert(CurMultiClass && "invalid context for template argument");
3642 DeclName = QualifyName(MC: CurMultiClass, Name: DeclName);
3643 BadField =
3644 AddValue(CurRec, Loc: IdLoc,
3645 RV: 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(K: tgtok::equal)) {
3652 SMLoc ValLoc = Lex.getLoc();
3653 const Init *Val = ParseValue(CurRec, ItemType: Type);
3654 if (!Val ||
3655 SetValue(CurRec, Loc: ValLoc, ValName: DeclName, BitList: {}, V: 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(Msg: "Expected identifier in foreach declaration");
3679 return nullptr;
3680 }
3681
3682 const Init *DeclName = StringInit::get(RK&: Records, Lex.getCurStrVal());
3683 Lex.Lex();
3684
3685 // If a value is present, parse it.
3686 if (!consume(K: tgtok::equal)) {
3687 TokError(Msg: "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(Result&: Ranges);
3698 if (!consume(K: tgtok::r_brace)) {
3699 TokError(Msg: "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(CurRec: nullptr);
3708 if (!I)
3709 return nullptr;
3710
3711 const auto *TI = dyn_cast<TypedInit>(Val: I);
3712 if (TI && isa<ListRecTy>(Val: TI->getType())) {
3713 ForeachListValue = I;
3714 IterType = cast<ListRecTy>(Val: TI->getType())->getElementType();
3715 break;
3716 }
3717
3718 if (TI) {
3719 if (ParseRangePiece(Ranges, FirstItem: TI))
3720 return nullptr;
3721 break;
3722 }
3723
3724 Error(L: ValueLoc, Msg: "expected a list, got '" + I->getAsString() + "'");
3725 if (CurMultiClass) {
3726 PrintNote(NoteLoc: {}, Msg: "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(RK&: Records);
3736 std::vector<Init *> Values;
3737 for (unsigned R : Ranges)
3738 Values.push_back(x: IntInit::get(RK&: Records, V: R));
3739 ForeachListValue = ListInit::get(Range: Values, EltTy: IterType);
3740 }
3741
3742 if (!IterType)
3743 return nullptr;
3744
3745 return VarInit::get(VN: DeclName, T: 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, ParsingTemplateArgs: true /*templateargs*/);
3763 if (!TemplArg)
3764 return true;
3765
3766 TheRecToAddTo->addTemplateArg(Name: TemplArg);
3767
3768 while (consume(K: tgtok::comma)) {
3769 // Read the following declarations.
3770 SMLoc Loc = Lex.getLoc();
3771 TemplArg = ParseDeclaration(CurRec, ParsingTemplateArgs: true /*templateargs*/);
3772 if (!TemplArg)
3773 return true;
3774
3775 if (TheRecToAddTo->isTemplateArg(Name: TemplArg))
3776 return Error(L: Loc, Msg: "template argument with the same name has already been "
3777 "defined");
3778
3779 TheRecToAddTo->addTemplateArg(Name: TemplArg);
3780 }
3781
3782 if (!consume(K: tgtok::greater))
3783 return TokError(Msg: "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(S: "append", Value: LetMode::Append)
3806 .Case(S: "prepend", Value: LetMode::Prepend)
3807 .Default(Value: 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: Mode, .Loc: Lex.getLoc(), .Name: 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 {.Mode: LetMode::Replace, .Loc: Loc, .Name: 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(CurMultiClass: nullptr, CurRec);
3835
3836 if (Lex.getCode() == tgtok::Defvar)
3837 return ParseDefvar(CurRec);
3838
3839 if (Lex.getCode() == tgtok::Dump)
3840 return ParseDump(CurMultiClass: nullptr, CurRec);
3841
3842 if (Lex.getCode() != tgtok::Let) {
3843 if (!ParseDeclaration(CurRec, ParsingTemplateArgs: false))
3844 return true;
3845
3846 if (!consume(K: tgtok::semi))
3847 return TokError(Msg: "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(Msg: "expected field identifier after let");
3856
3857 auto [Mode, IdLoc, FieldNameStr] = ParseLetModeAndName();
3858 const StringInit *FieldName = StringInit::get(RK&: Records, FieldNameStr);
3859
3860 SmallVector<unsigned, 16> BitList;
3861 if (ParseOptionalRangeList(Ranges&: BitList))
3862 return true;
3863 std::reverse(first: BitList.begin(), last: BitList.end());
3864
3865 if (!consume(K: tgtok::equal))
3866 return TokError(Msg: "expected '=' in let expression");
3867
3868 RecordVal *Field = CurRec->getValue(Name: FieldName);
3869 if (!Field)
3870 return Error(L: IdLoc, Msg: "Value '" + FieldName->getValue() + "' unknown!");
3871
3872 const RecTy *Type = Field->getType();
3873 if (!BitList.empty() && isa<BitsRecTy>(Val: 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(RK&: Records, Sz: BitList.size());
3877 }
3878
3879 const Init *Val = ParseValue(CurRec, ItemType: Type);
3880 if (!Val)
3881 return true;
3882
3883 if (!consume(K: tgtok::semi))
3884 return TokError(Msg: "expected ';' after let expression");
3885
3886 return SetValue(CurRec, Loc: IdLoc, ValName: FieldName, BitList, V: 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(K: tgtok::semi))
3900 return false;
3901
3902 if (!consume(K: tgtok::l_brace))
3903 return TokError(Msg: "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(K: tgtok::semi)) {
3915 PrintError(ErrorLoc: SemiLoc, Msg: "A class or def body should not end with a semicolon");
3916 PrintNote(Msg: "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, Loc: LR.Loc, ValName: LR.Name, BitList: LR.Bits, V: LR.Value,
3928 /*AllowSelfAssignment=*/false, /*OverrideDefLoc=*/true,
3929 Mode: 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(CurRec: 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(Entry&: 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(Rec: CurRec);
3967 // If there is a baseclass list, read it.
3968 if (consume(K: tgtok::colon)) {
3969
3970 // Read all of the subclasses.
3971 SubClassReference SubClass = ParseSubClassReference(CurRec, isDefm: 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(K: tgtok::comma))
3982 break;
3983 SubClass = ParseSubClassReference(CurRec, isDefm: false);
3984 }
3985 }
3986
3987 if (ApplyLetStack(CurRec))
3988 return true;
3989
3990 bool Result = ParseBody(CurRec);
3991 PopScope(ExpectedStackTop: 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>(Val: Name)) {
4017 CurRec = std::make_unique<Record>(args: Records.getNewAnonymousName(), args&: DefLoc,
4018 args&: Records, args: Record::RK_AnonymousDef);
4019 } else {
4020 CurRec = std::make_unique<Record>(args&: Name, args&: NameLoc, args&: Records);
4021 }
4022
4023 if (ParseObjectBody(CurRec: CurRec.get()))
4024 return true;
4025
4026 return addEntry(E: 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>(Val: Type))
4043 return Error(L: Defset.Loc, Msg: "expected list type");
4044 Defset.EltTy = cast<ListRecTy>(Val: Type)->getElementType();
4045
4046 if (Lex.getCode() != tgtok::Id)
4047 return TokError(Msg: "expected identifier");
4048 const StringInit *DeclName = StringInit::get(RK&: Records, Lex.getCurStrVal());
4049 if (Records.getGlobal(Name: DeclName->getValue()))
4050 return TokError(Msg: "def or global variable of this name already exists");
4051
4052 if (Lex.Lex() != tgtok::equal) // Eat the identifier
4053 return TokError(Msg: "expected '='");
4054 if (Lex.Lex() != tgtok::l_brace) // Eat the '='
4055 return TokError(Msg: "expected '{'");
4056 SMLoc BraceLoc = Lex.getLoc();
4057 Lex.Lex(); // Eat the '{'
4058
4059 Defsets.push_back(Elt: &Defset);
4060 bool Err = ParseObjectList(MC: nullptr);
4061 Defsets.pop_back();
4062 if (Err)
4063 return true;
4064
4065 if (!consume(K: tgtok::r_brace)) {
4066 TokError(Msg: "expected '}' at end of defset");
4067 return Error(L: BraceLoc, Msg: "to match this '{'");
4068 }
4069
4070 Records.addExtraGlobal(Name: DeclName->getValue(),
4071 I: ListInit::get(Range: Defset.Elements, EltTy: 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(Msg: "expected identifier");
4085
4086 const std::string TypeName = Lex.getCurStrVal();
4087 if (TypeAliases.count(x: TypeName) || Records.getClass(Name: TypeName))
4088 return TokError(Msg: "type of this name '" + TypeName + "' already exists");
4089
4090 Lex.Lex();
4091 if (!consume(K: tgtok::equal))
4092 return TokError(Msg: "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(L: Loc, Msg: "cannot define type alias for class type '" +
4101 Type->getAsString() + "'");
4102
4103 TypeAliases[TypeName] = Type;
4104
4105 if (!consume(K: tgtok::semi))
4106 return TokError(Msg: "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(Msg: "expected identifier");
4121 const StringInit *DeclName = StringInit::get(RK&: Records, Lex.getCurStrVal());
4122 if (CurScope->varAlreadyDefined(Name: DeclName->getValue()))
4123 return TokError(Msg: "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(Name: DeclName->getValue());
4128 if (V && !V->isTemplateArg())
4129 return TokError(Msg: "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(Name: DeclName->getValue()))
4135 return TokError(Msg: "def or global variable of this name already exists");
4136
4137 Lex.Lex();
4138 if (!consume(K: tgtok::equal))
4139 return TokError(Msg: "expected '='");
4140
4141 const Init *Value = ParseValue(CurRec);
4142 if (!Value)
4143 return true;
4144
4145 if (!consume(K: tgtok::semi))
4146 return TokError(Msg: "expected ';'");
4147
4148 if (!CurScope->isOutermost())
4149 CurScope->addVar(Name: DeclName->getValue(), I: Value);
4150 else
4151 Records.addExtraGlobal(Name: DeclName->getValue(), I: 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(ForeachListValue&: ListValue);
4171 if (!IterName)
4172 return TokError(Msg: "expected declaration in for");
4173
4174 if (!consume(K: tgtok::In))
4175 return TokError(Msg: "Unknown tok");
4176
4177 // Create a loop object and remember it.
4178 auto TheLoop = std::make_unique<ForeachLoop>(args&: Loc, args&: IterName, args&: ListValue);
4179 // A foreach loop introduces a new scope for local variables.
4180 TGVarScope *ForeachScope = PushScope(Loop: TheLoop.get());
4181 Loops.push_back(x: std::move(TheLoop));
4182
4183 if (Lex.getCode() != tgtok::l_brace) {
4184 // FOREACH Declaration IN Object
4185 if (ParseObject(MC: 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(MC: CurMultiClass))
4194 return true;
4195
4196 if (!consume(K: tgtok::r_brace)) {
4197 TokError(Msg: "expected '}' at end of foreach command");
4198 return Error(L: BraceLoc, Msg: "to match this '{'");
4199 }
4200 }
4201
4202 PopScope(ExpectedStackTop: 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(E: 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(CurRec: nullptr);
4224 if (!Condition)
4225 return true;
4226
4227 if (!consume(K: tgtok::Then))
4228 return TokError(Msg: "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(Range: {}, EltTy: BitRecTy::get(RK&: Records));
4237 const ListInit *SingletonList =
4238 ListInit::get(Range: {BitInit::get(RK&: Records, V: true)}, EltTy: BitRecTy::get(RK&: Records));
4239 const RecTy *BitListTy = ListRecTy::get(T: BitRecTy::get(RK&: Records));
4240
4241 // The foreach containing the then-clause selects SingletonList if
4242 // the condition is true.
4243 const Init *ThenClauseList =
4244 TernOpInit::get(opc: TernOpInit::IF, lhs: Condition, mhs: SingletonList, rhs: EmptyList,
4245 Type: BitListTy)
4246 ->Fold(CurRec: nullptr);
4247 Loops.push_back(x: std::make_unique<ForeachLoop>(args&: Loc, args: nullptr, args&: ThenClauseList));
4248
4249 if (ParseIfBody(CurMultiClass, Kind: "then"))
4250 return true;
4251
4252 std::unique_ptr<ForeachLoop> Loop = std::move(Loops.back());
4253 Loops.pop_back();
4254
4255 if (addEntry(E: 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(K: 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(opc: TernOpInit::IF, lhs: Condition, mhs: EmptyList, rhs: SingletonList,
4267 Type: BitListTy)
4268 ->Fold(CurRec: nullptr);
4269 Loops.push_back(
4270 x: std::make_unique<ForeachLoop>(args&: Loc, args: nullptr, args&: ElseClauseList));
4271
4272 if (ParseIfBody(CurMultiClass, Kind: "else"))
4273 return true;
4274
4275 Loop = std::move(Loops.back());
4276 Loops.pop_back();
4277
4278 if (addEntry(E: 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(MC: 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(MC: CurMultiClass))
4305 return true;
4306
4307 if (!consume(K: tgtok::r_brace)) {
4308 TokError(Msg: "expected '}' at end of '" + Kind + "' clause");
4309 return Error(L: BraceLoc, Msg: "to match this '{'");
4310 }
4311 }
4312
4313 PopScope(ExpectedStackTop: 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(K: tgtok::comma)) {
4330 TokError(Msg: "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(K: tgtok::semi))
4339 return TokError(Msg: "expected ';'");
4340
4341 if (CurRec)
4342 CurRec->addAssertion(Loc: ConditionLoc, Condition, Message);
4343 else
4344 addEntry(E: std::make_unique<Record::AssertionInfo>(args&: ConditionLoc, args&: Condition,
4345 args&: 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(Msg: "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(Msg: "Class '" + CurRec->getNameInitAsString() +
4368 "' already defined");
4369
4370 CurRec->updateClassLoc(Loc: 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>(args: Lex.getCurStrVal(), args: Lex.getLoc(),
4374 args&: Records, args: Record::RK_Class);
4375 CurRec = NewRec.get();
4376 Records.addClass(R: std::move(NewRec));
4377 }
4378
4379 if (TypeAliases.count(x: Name))
4380 return TokError(Msg: "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(Rec: 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(ExpectedStackTop: 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(Msg: "expected identifier in let definition");
4411 Result.clear();
4412 return;
4413 }
4414
4415 auto [Mode, NameLoc, NameStr] = ParseLetModeAndName();
4416 const StringInit *Name = StringInit::get(RK&: Records, NameStr);
4417
4418 // Check for an optional RangeList.
4419 SmallVector<unsigned, 16> Bits;
4420 if (ParseOptionalRangeList(Ranges&: Bits)) {
4421 Result.clear();
4422 return;
4423 }
4424 std::reverse(first: Bits.begin(), last: Bits.end());
4425
4426 if (!consume(K: tgtok::equal)) {
4427 TokError(Msg: "expected '=' in let expression");
4428 Result.clear();
4429 return;
4430 }
4431
4432 const Init *Val = ParseValue(CurRec: nullptr);
4433 if (!Val) {
4434 Result.clear();
4435 return;
4436 }
4437
4438 // Now that we have everything, add the record.
4439 Result.emplace_back(Args&: Name, Args&: Bits, Args&: Val, Args&: NameLoc, Args&: Mode);
4440 } while (consume(K: 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.
4454 SmallVector<LetRecord, 8> LetInfo;
4455 ParseLetList(Result&: LetInfo);
4456 if (LetInfo.empty())
4457 return true;
4458 LetStack.push_back(x: std::move(LetInfo));
4459
4460 if (!consume(K: tgtok::In))
4461 return TokError(Msg: "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(MC: 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(MC: CurMultiClass))
4478 return true;
4479
4480 if (!consume(K: tgtok::r_brace)) {
4481 TokError(Msg: "expected '}' at end of top level let command");
4482 return Error(L: BraceLoc, Msg: "to match this '{'");
4483 }
4484
4485 PopScope(ExpectedStackTop: 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(Msg: "expected identifier after multiclass for name");
4512 std::string Name = Lex.getCurStrVal();
4513
4514 auto Result = MultiClasses.try_emplace(
4515 k: Name, args: std::make_unique<MultiClass>(args&: Name, args: Lex.getLoc(), args&: Records));
4516
4517 if (!Result.second)
4518 return TokError(Msg: "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(Multiclass: CurMultiClass);
4525
4526 // If there are template args, parse them.
4527 if (Lex.getCode() == tgtok::less)
4528 if (ParseTemplateArgList(CurRec: nullptr))
4529 return true;
4530
4531 bool inherits = false;
4532
4533 // If there are submulticlasses, parse them.
4534 if (consume(K: tgtok::colon)) {
4535 inherits = true;
4536
4537 // Read all of the submulticlasses.
4538 SubMultiClassReference SubMultiClass =
4539 ParseSubMultiClassReference(CurMC: CurMultiClass);
4540 while (true) {
4541 // Check for error.
4542 if (!SubMultiClass.MC)
4543 return true;
4544
4545 // Add it.
4546 if (AddSubMultiClass(CurMC: CurMultiClass, SubMultiClass))
4547 return true;
4548
4549 if (!consume(K: tgtok::comma))
4550 break;
4551 SubMultiClass = ParseSubMultiClassReference(CurMC: CurMultiClass);
4552 }
4553 }
4554
4555 if (Lex.getCode() != tgtok::l_brace) {
4556 if (!inherits)
4557 return TokError(Msg: "expected '{' in multiclass definition");
4558 if (!consume(K: tgtok::semi))
4559 return TokError(Msg: "expected ';' in multiclass definition");
4560 } else {
4561 if (Lex.Lex() == tgtok::r_brace) // eat the '{'.
4562 return TokError(Msg: "multiclass must contain at least one def");
4563
4564 while (Lex.getCode() != tgtok::r_brace) {
4565 switch (Lex.getCode()) {
4566 default:
4567 return TokError(Msg: "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(MC: 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(K: tgtok::semi)) {
4588 PrintError(ErrorLoc: SemiLoc, Msg: "A multiclass body should not end with a semicolon");
4589 PrintNote(Msg: "Semicolon ignored; remove to eliminate this error");
4590 }
4591 }
4592
4593 if (!NoWarnOnUnusedTemplateArgs)
4594 CurMultiClass->Rec.checkUnusedTemplateArgs();
4595
4596 PopScope(ExpectedStackTop: 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>(Val: DefmName)) {
4613 DefmName = Records.getNewAnonymousName();
4614 if (CurMultiClass)
4615 DefmName = BinOpInit::getStrConcat(
4616 lhs: VarInit::get(VN: QualifiedNameOfImplicitName(MC: CurMultiClass),
4617 T: StringRecTy::get(RK&: Records)),
4618 rhs: DefmName);
4619 }
4620
4621 if (Lex.getCode() != tgtok::colon)
4622 return TokError(Msg: "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(CurRec: nullptr, isDefm: 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, ArgValues: Ref.TemplateArgs, DefmName,
4649 Loc: SubClassLoc))
4650 return true;
4651
4652 if (resolve(Source: MC->Entries, Substs, Final: !CurMultiClass && Loops.empty(),
4653 Dest: &NewEntries, Loc: &SubClassLoc))
4654 return true;
4655
4656 if (!consume(K: tgtok::comma))
4657 break;
4658
4659 if (Lex.getCode() != tgtok::Id)
4660 return TokError(Msg: "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(Name: Lex.getCurStrVal()) != nullptr);
4667
4668 if (InheritFromClass)
4669 break;
4670
4671 Ref = ParseSubClassReference(CurRec: nullptr, isDefm: 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(CurRec: nullptr, isDefm: 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(Entry&: E, SubClass))
4688 return true;
4689 }
4690
4691 if (!consume(K: tgtok::comma))
4692 break;
4693 SubClass = ParseSubClassReference(CurRec: nullptr, isDefm: false);
4694 }
4695 }
4696
4697 for (auto &E : NewEntries) {
4698 if (ApplyLetStack(Entry&: E))
4699 return true;
4700
4701 addEntry(E: std::move(E));
4702 }
4703
4704 if (!consume(K: tgtok::semi))
4705 return TokError(Msg: "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 Msg: "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4727 case tgtok::Assert:
4728 return ParseAssert(CurMultiClass: MC);
4729 case tgtok::Def:
4730 return ParseDef(CurMultiClass: MC);
4731 case tgtok::Defm:
4732 return ParseDefm(CurMultiClass: MC);
4733 case tgtok::Deftype:
4734 return ParseDeftype();
4735 case tgtok::Defvar:
4736 return ParseDefvar();
4737 case tgtok::Dump:
4738 return ParseDump(CurMultiClass: MC);
4739 case tgtok::Foreach:
4740 return ParseForeach(CurMultiClass: MC);
4741 case tgtok::If:
4742 return ParseIf(CurMultiClass: MC);
4743 case tgtok::Let:
4744 return ParseTopLevelLet(CurMultiClass: MC);
4745 case tgtok::Defset:
4746 if (MC)
4747 return TokError(Msg: "defset is not allowed inside multiclass");
4748 return ParseDefset();
4749 case tgtok::Class:
4750 if (MC)
4751 return TokError(Msg: "class is not allowed inside multiclass");
4752 if (!Loops.empty())
4753 return TokError(Msg: "class is not allowed inside foreach loop");
4754 return ParseClass();
4755 case tgtok::MultiClass:
4756 if (!Loops.empty())
4757 return TokError(Msg: "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(Kind: Lex.getCode())) {
4766 if (ParseObject(MC))
4767 return true;
4768 }
4769 return false;
4770}
4771
4772bool TGParser::ParseFile() {
4773 Lex.Lex(); // Prime the lexer.
4774 TGVarScope *GlobalScope = PushScope();
4775 if (ParseObjectList())
4776 return true;
4777 PopScope(ExpectedStackTop: GlobalScope);
4778
4779 // If we have unread input at the end of the file, report it.
4780 if (Lex.getCode() == tgtok::Eof)
4781 return false;
4782
4783 return TokError(Msg: "Unexpected token at top level");
4784}
4785
4786// Check the types of the template argument values for a class
4787// inheritance, multiclass invocation, or anonymous class invocation.
4788// If necessary, replace an argument with a cast to the required type.
4789// The argument count has already been checked.
4790bool TGParser::CheckTemplateArgValues(
4791 SmallVectorImpl<const ArgumentInit *> &Values, ArrayRef<SMLoc> ValuesLocs,
4792 const Record *ArgsRec) {
4793 assert(Values.size() == ValuesLocs.size() &&
4794 "expected as many values as locations");
4795
4796 ArrayRef<const Init *> TArgs = ArgsRec->getTemplateArgs();
4797
4798 bool HasError = false;
4799 for (auto [Value, Loc] : llvm::zip_equal(t&: Values, u&: ValuesLocs)) {
4800 const Init *ArgName = nullptr;
4801 if (Value->isPositional())
4802 ArgName = TArgs[Value->getIndex()];
4803 if (Value->isNamed())
4804 ArgName = Value->getName();
4805
4806 const RecordVal *Arg = ArgsRec->getValue(Name: ArgName);
4807 const RecTy *ArgType = Arg->getType();
4808
4809 if (const auto *ArgValue = dyn_cast<TypedInit>(Val: Value->getValue())) {
4810 auto *CastValue = ArgValue->getCastTo(Ty: ArgType);
4811 if (CastValue) {
4812 assert((!isa<TypedInit>(CastValue) ||
4813 cast<TypedInit>(CastValue)->getType()->typeIsA(ArgType)) &&
4814 "result of template arg value cast has wrong type");
4815 Value = Value->cloneWithValue(Value: CastValue);
4816 } else {
4817 HasError |= Error(
4818 L: Loc, Msg: "Value specified for template argument '" +
4819 Arg->getNameInitAsString() + "' is of type " +
4820 ArgValue->getType()->getAsString() + "; expected type " +
4821 ArgType->getAsString() + ": " + ArgValue->getAsString());
4822 }
4823 }
4824 }
4825
4826 return HasError;
4827}
4828
4829#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4830LLVM_DUMP_METHOD void RecordsEntry::dump() const {
4831 if (Loop)
4832 Loop->dump();
4833 if (Rec)
4834 Rec->dump();
4835}
4836
4837LLVM_DUMP_METHOD void ForeachLoop::dump() const {
4838 errs() << "foreach " << IterVar->getAsString() << " = "
4839 << ListValue->getAsString() << " in {\n";
4840
4841 for (const auto &E : Entries)
4842 E.dump();
4843
4844 errs() << "}\n";
4845}
4846
4847LLVM_DUMP_METHOD void MultiClass::dump() const {
4848 errs() << "Record:\n";
4849 Rec.dump();
4850
4851 errs() << "Defs:\n";
4852 for (const auto &E : Entries)
4853 E.dump();
4854}
4855#endif
4856
4857bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {
4858 // Location of the `dump` statement.
4859 SMLoc Loc = Lex.getLoc();
4860 assert(Lex.getCode() == tgtok::Dump && "Unknown tok");
4861 Lex.Lex(); // eat the operation
4862
4863 const Init *Message = ParseValue(CurRec);
4864 if (!Message)
4865 return true;
4866
4867 // Allow to use dump directly on `defvar` and `def`, by wrapping
4868 // them with a `!repl`.
4869 if (isa<DefInit>(Val: Message))
4870 Message = UnOpInit::get(opc: UnOpInit::REPR, lhs: Message, Type: StringRecTy::get(RK&: Records))
4871 ->Fold(CurRec);
4872
4873 if (!consume(K: tgtok::semi))
4874 return TokError(Msg: "expected ';'");
4875
4876 if (CurRec)
4877 CurRec->addDump(Loc, Message);
4878 else {
4879 HasReferenceResolver resolver{nullptr};
4880 resolver.setFinal(true);
4881 // force a resolution with a dummy resolver
4882 const Init *ResolvedMessage = Message->resolveReferences(R&: resolver);
4883 addEntry(E: std::make_unique<Record::DumpInfo>(args&: Loc, args&: ResolvedMessage));
4884 }
4885
4886 return false;
4887}
4888