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