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