LLVM: lib/TableGen/TGParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
17#include "llvm/Config/llvm-config.h"
22#include
23#include
24#include
25#include
26
27using namespace llvm;
28
29
30
31
32
33namespace llvm {
34
39
41
43};
44
49
51
53 void dump() const;
54};
55
56#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
58 errs() << "Multiclass:\n";
59
61
62 errs() << "Template args:\n";
64 TA->dump();
65}
66#endif
67
68}
69
71 const auto *BV = cast(RV.getValue());
72 for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
73 const Init *Bit = BV->getBit(i);
74 bool IsReference = false;
75 if (const auto *VBI = dyn_cast(Bit)) {
76 if (const auto *VI = dyn_cast(VBI->getBitVar())) {
77 if (R.getValue(VI->getName()))
78 IsReference = true;
79 }
80 } else if (isa(Bit)) {
81 IsReference = true;
82 }
83 if (!(IsReference || Bit->isConcrete()))
84 return false;
85 }
86 return true;
87}
88
90 for (const RecordVal &RV : R.getValues()) {
91
92
93
94
95 if (RV.isNonconcreteOK())
96 continue;
97
98 if (const Init *V = RV.getValue()) {
99 bool Ok = isa(V) ? checkBitsConcrete(R, RV) : V->isConcrete();
100 if (!Ok) {
102 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
112
119
120 if (const auto *BinOp = dyn_cast(NewName))
121 NewName = BinOp->Fold(&CurRec);
122 return NewName;
123}
124
127}
128
129
132}
133
136}
137
141 bool TrackReferenceLocs) const {
142
143 auto It = Vars.find(Name->getValue());
144 if (It != Vars.end())
145 return It->second;
146
147 auto FindValueInArgs = [&](Record *Rec,
149 if (!Rec)
150 return nullptr;
154 assert(RV && "Template arg doesn't exist??");
156 if (TrackReferenceLocs)
159 }
160 return Name->getValue() == "NAME"
162 : nullptr;
163 };
164
165
166
167 switch (Kind) {
169 break;
171 if (CurRec) {
172
174 if (TrackReferenceLocs)
175 RV->addReferenceLoc(NameLoc);
177 }
178
179
181 if (auto *V = FindValueInArgs(CurRec, Name))
182 return V;
183 }
184 break;
185 }
187
189 const auto *IterVar = dyn_cast(CurLoop->IterVar);
190 if (IterVar && IterVar->getNameInit() == Name)
191 return IterVar;
192 }
193 break;
194 }
196
197 if (CurMultiClass)
198 if (auto *V = FindValueInArgs(&CurMultiClass->Rec, Name))
199 return V;
200 break;
201 }
202 }
203
204
205 if (Parent)
206 return Parent->getVar(Records, ParsingMultiClass, Name, NameLoc,
207 TrackReferenceLocs);
208
209 return nullptr;
210}
211
213 if (!CurRec)
214 CurRec = &CurMultiClass->Rec;
215
217
218 if (ERV->setValue(RV.getValue()))
219 return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
221 "previous definition of type '" +
222 ERV->getType()->getAsString() + "'");
223 } else {
225 }
226 return false;
227}
228
229
230
231bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const Init *ValName,
233 bool AllowSelfAssignment, bool OverrideDefLoc) {
234 if (!V) return false;
235
236 if (!CurRec) CurRec = &CurMultiClass->Rec;
237
239 if (!RV)
241 "' unknown!");
242
243
244
245 if (BitList.empty())
246 if (const auto *VI = dyn_cast(V))
247 if (VI->getNameInit() == ValName && !AllowSelfAssignment)
248 return Error(Loc, "Recursion / self-assignment forbidden");
249
250
251
252
253
254 if (!BitList.empty()) {
255 const auto *CurVal = dyn_cast(RV->getValue());
256 if (!CurVal)
258 "' is not a bits type");
259
260
262 if (!BI)
263 return Error(Loc, "Initializer is not compatible with bit range");
264
266
267
268 for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
269 unsigned Bit = BitList[i];
270 if (NewBits[Bit])
271 return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" +
274 }
275
276 for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
277 if (!NewBits[i])
278 NewBits[i] = CurVal->getBit(i);
279
281 }
282
283 if (OverrideDefLoc ? RV->setValue(V, Loc) : RV->setValue(V)) {
284 std::string InitType;
285 if (const auto *BI = dyn_cast(V))
286 InitType = (Twine("' of type bit initializer with length ") +
287 Twine(BI->getNumBits())).str();
288 else if (const auto *TI = dyn_cast(V))
289 InitType = (Twine("' of type '") + TI->getType()->getAsString()).str();
292 "' is incompatible with value '" +
293 V->getAsString() + InitType + "'");
294 }
295 return false;
296}
297
298
299
303
304
305
307 if (.isTemplateArg())
309 return true;
310
311 if (resolveArgumentsOfClass(R, SC, SubClass.TemplateArgs,
313 return true;
314
315
317
318
320
325 else
328
330
331
332
333 for (const auto &[SC, Loc] : SC->getSuperClasses()) {
336 "Already subclass of '" + SC->getName() + "'!\n");
338 }
339
342 "Already subclass of '" + SC->getName() + "'!\n");
344 return false;
345}
346
349 return AddSubClass(Entry.Rec.get(), SubClass);
350
351 if (Entry.Assertion)
352 return false;
353
354 for (auto &E : Entry.Loop->Entries) {
355 if (AddSubClass(E, SubClass))
356 return true;
357 }
358
359 return false;
360}
361
362
363
364
365bool TGParser::AddSubMultiClass(MultiClass *CurMC,
368
369 SubstStack Substs;
370 if (resolveArgumentsOfMultiClass(
375 return true;
376
377
378 return resolve(SMC->Entries, Substs, false, &CurMC->Entries);
379}
380
381
384 "RecordsEntry has invalid number of items");
385
386
387 if (!Loops.empty()) {
388 Loops.back()->Entries.push_back(std::move(E));
389 return false;
390 }
391
392
393 if (E.Loop) {
394 SubstStack Stack;
395 return resolve(*E.Loop, Stack, CurMultiClass == nullptr,
396 CurMultiClass ? &CurMultiClass->Entries : nullptr);
397 }
398
399
400 if (CurMultiClass) {
401 CurMultiClass->Entries.push_back(std::move(E));
402 return false;
403 }
404
405
408 return false;
409 }
410
411 if (E.Dump) {
413 return false;
414 }
415
416
417 return addDefOne(std::move(E.Rec));
418}
419
420
421
422
423
424
425bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs,
426 bool Final, std::vector *Dest,
428
430 for (const auto &S : Substs)
431 R.set(S.first, S.second);
432 const Init *List = Loop.ListValue->resolveReferences(R);
433
434
435
436
437
438
439
440 if (const auto *TI = dyn_cast(List);
442 const Init *OldLHS = TI->getLHS();
443 R.setFinal(true);
445 if (LHS == OldLHS) {
447 Twine("unable to resolve if condition '") +
448 LHS->getAsString() + "' at end of containing scope");
449 return true;
450 }
451 const Init *MHS = TI->getMHS();
452 const Init *RHS = TI->getRHS();
454 ->Fold(nullptr);
455 }
456
457 const auto *LI = dyn_cast(List);
458 if (!LI) {
459 if (!Final) {
460 Dest->emplace_back(std::make_unique(Loop.Loc, Loop.IterVar,
462 return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
463 Loc);
464 }
465
467 List->getAsString() + "', expected a list");
468 return true;
469 }
470
471 bool Error = false;
472 for (auto *Elt : *LI) {
473 if (Loop.IterVar)
474 Substs.emplace_back(Loop.IterVar->getNameInit(), Elt);
475 Error = resolve(Loop.Entries, Substs, Final, Dest);
476 if (Loop.IterVar)
477 Substs.pop_back();
479 break;
480 }
482}
483
484
485
486
487
488
489bool TGParser::resolve(const std::vector &Source,
490 SubstStack &Substs, bool Final,
491 std::vector *Dest, SMLoc *Loc) {
492 bool Error = false;
493 for (auto &E : Source) {
494 if (E.Loop) {
495 Error = resolve(*E.Loop, Substs, Final, Dest);
496
499 for (const auto &S : Substs)
500 R.set(S.first, S.second);
501 const Init *Condition = E.Assertion->Condition->resolveReferences(R);
502 const Init *Message = E.Assertion->Message->resolveReferences(R);
503
504 if (Dest)
505 Dest->push_back(std::make_uniqueRecord::AssertionInfo(
506 E.Assertion->Loc, Condition, Message));
507 else
509
510 } else if (E.Dump) {
512 for (const auto &S : Substs)
513 R.set(S.first, S.second);
514 const Init *Message = E.Dump->Message->resolveReferences(R);
515
516 if (Dest)
517 Dest->push_back(
518 std::make_uniqueRecord::DumpInfo(E.Dump->Loc, Message));
519 else
521
522 } else {
523 auto Rec = std::make_unique(*E.Rec);
524 if (Loc)
525 Rec->appendLoc(*Loc);
526
528 for (const auto &S : Substs)
529 R.set(S.first, S.second);
530 Rec->resolveReferences(R);
531
532 if (Dest)
533 Dest->push_back(std::move(Rec));
534 else
535 Error = addDefOne(std::move(Rec));
536 }
538 break;
539 }
541}
542
543
544bool TGParser::addDefOne(std::unique_ptr Rec) {
545 const Init *NewName = nullptr;
546 if (const Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
547 if (!Rec->isAnonymous()) {
549 "def already exists: " + Rec->getNameInitAsString());
550 PrintNote(Prev->getLoc(), "location of previous definition");
551 return true;
552 }
554 }
555
558
559 if (!isa(Rec->getNameInit())) {
561 Rec->getNameInit()->getAsString() +
562 "' could not be fully resolved");
563 return true;
564 }
565
566
567 Rec->checkRecordAssertions();
568
569
570 Rec->emitRecordDumps();
571
572
573 assert(Rec->getTemplateArgs().empty() && "How'd this get template args?");
574
576 DefInit *I = Rec->getDefInit();
577 if (->getType()->typeIsA(Defset->EltTy)) {
578 PrintError(Rec->getLoc(), Twine("adding record of incompatible type '") +
579 I->getType()->getAsString() +
580 "' to defset");
581 PrintNote(Defset->Loc, "location of defset declaration");
582 return true;
583 }
584 Defset->Elements.push_back(I);
585 }
586
587 Records.addDef(std::move(Rec));
588 return false;
589}
590
591bool TGParser::resolveArguments(const Record *Rec,
593 SMLoc Loc, ArgValueHandler ArgValueHandler) {
596 "Too many template arguments allowed");
597
598
600 for (auto *Arg : ArgValues) {
601 const Init *ArgName = nullptr;
602 const Init *ArgValue = Arg->getValue();
603 if (Arg->isPositional())
604 ArgName = ArgNames[Arg->getIndex()];
605 if (Arg->isNamed())
606 ArgName = Arg->getName();
607
608
609 if ((UnsolvedArgNames, ArgName))
610 return Error(Loc, "We can only specify the template argument '" +
612
613 ArgValueHandler(ArgName, ArgValue);
615 }
616
617
618 for (auto *UnsolvedArgName : UnsolvedArgNames) {
620 if (->isComplete()) {
621 std::string Name = UnsolvedArgName->getAsUnquotedString();
622 Error(Loc, "value not specified for template argument '" + Name + "'");
625 return true;
626 }
627 ArgValueHandler(UnsolvedArgName, Default);
628 }
629
630 return false;
631}
632
633
634
635bool TGParser::resolveArgumentsOfClass(MapResolver &R, const Record *Rec,
638 return resolveArguments(
639 Rec, ArgValues, Loc,
641}
642
643
644
645bool TGParser::resolveArgumentsOfMultiClass(
648
650 return resolveArguments(&MC->Rec, ArgValues, Loc,
652 Substs.emplace_back(Name, Value);
653 });
654}
655
656
657
658
659
661 if (Lex.getCode() == K) {
662 Lex.Lex();
663 return true;
664 }
665 return false;
666}
667
668
669
670
671
672
673
674const Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
679
680
681
683 default:
684 break;
685 }
686
687 Record *CurRec = nullptr;
688 if (CurMultiClass)
689 CurRec = &CurMultiClass->Rec;
690
692 ParseValue(CurRec, StringRecTy::get(Records), ParseNameMode);
694 return nullptr;
695
696 if (CurMultiClass) {
699 Name->resolveReferences(R);
700 if (.found())
703 }
704
706}
707
708
709
710
711
712
713const Record *TGParser::ParseClassID() {
715 TokError("expected name for ClassID");
716 return nullptr;
717 }
718
720 if (!Result) {
721 std::string Msg("Couldn't find class '" + Lex.getCurStrVal() + "'");
723 TokError(Msg + ". Use 'defm' if you meant to use multiclass '" +
725 else
727 } else if (TrackReferenceLocs) {
729 }
730
731 Lex.Lex();
733}
734
735
736
737
738
739
740MultiClass *TGParser::ParseMultiClassID() {
742 TokError("expected name for MultiClassID");
743 return nullptr;
744 }
745
747 if (!Result)
749
750 Lex.Lex();
752}
753
754
755
756
757
758
759
761ParseSubClassReference(Record *CurRec, bool isDefm) {
764
765 if (isDefm) {
766 if (MultiClass *MC = ParseMultiClassID())
768 } else {
769 Result.Rec = ParseClassID();
770 }
772
773
777 }
778
780 if (ParseTemplateArgValueList(Result.TemplateArgs, ArgLocs, CurRec,
782 Result.Rec = nullptr;
784 }
785
786 if (CheckTemplateArgValues(Result.TemplateArgs, ArgLocs, Result.Rec)) {
787 Result.Rec = nullptr;
789 }
790
793}
794
795
796
797
798
799
800
801
803ParseSubMultiClassReference(MultiClass *CurMC) {
806
807 Result.MC = ParseMultiClassID();
809
810
814 }
815
817 if (ParseTemplateArgValueList(Result.TemplateArgs, ArgLocs, &CurMC->Rec,
819 Result.MC = nullptr;
821 }
822
824
826}
827
828
829
830
831
832
833
834
835
836
837
838const TypedInit *TGParser::ParseSliceElement(Record *CurRec) {
839 auto LHSLoc = Lex.getLoc();
840 auto *CurVal = ParseValue(CurRec);
841 if (!CurVal)
842 return nullptr;
843 const auto *LHS = cast(CurVal);
844
849 Lex.Lex();
850 auto RHSLoc = Lex.getLoc();
851 CurVal = ParseValue(CurRec);
852 if (!CurVal)
853 return nullptr;
854 RHS = cast(CurVal);
855 if (!isa(RHS->getType())) {
857 "expected int...int, got " + Twine(RHS->getType()->getAsString()));
858 return nullptr;
859 }
860 break;
861 }
864 if (i < 0) {
865 TokError("invalid range, cannot be negative");
866 return nullptr;
867 }
869 Lex.Lex();
870 break;
871 }
872 default:
873 return LHS;
874 }
875
878
879
880 if (!isa(LHS->getType())) {
882 "expected int...int, got " + Twine(LHS->getType()->getAsString()));
883 return nullptr;
884 }
885
888 ->Fold(CurRec));
889}
890
891
892
893
894
895
896
897
898
899
900
901
902const TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
906
907 auto FlushElems = [&] {
908 if (!Elems.empty()) {
911 }
912 };
913
914 do {
915 auto LHSLoc = Lex.getLoc();
916 CurVal = ParseSliceElement(CurRec);
917 if (!CurVal)
918 return nullptr;
919 auto *CurValTy = CurVal->getType();
920
921 if (const auto *ListValTy = dyn_cast(CurValTy)) {
922 if (!isa(ListValTy->getElementType())) {
924 "expected list, got " + Twine(ListValTy->getAsString()));
925 return nullptr;
926 }
927
928 FlushElems();
931 CurVal = nullptr;
932 } else if (!isa(CurValTy)) {
934 "unhandled type " + Twine(CurValTy->getAsString()) + " in range");
935 return nullptr;
936 }
937
939 break;
940
941 Lex.Lex();
942
943
945 if (CurVal)
947 CurVal = nullptr;
949
950 if (CurVal) {
951
952 if (Single)
953 return CurVal;
954
956 }
957
958 FlushElems();
959
960
962 for (auto *Slice : Slices) {
964 : Slice);
965 }
966
968}
969
970
971
972
973
974
975
978 const Init *CurVal = FirstItem;
979 if (!CurVal)
980 CurVal = ParseValue(nullptr);
981
982 const auto *II = dyn_cast_or_null(CurVal);
983 if ()
984 return TokError("expected integer or bitrange");
985
986 int64_t Start = II->getValue();
987 int64_t End;
988
989 if (Start < 0)
990 return TokError("invalid range, cannot be negative");
991
993 default:
994 Ranges.push_back(Start);
995 return false;
996
999 Lex.Lex();
1000
1001 const Init *I_End = ParseValue(nullptr);
1002 const auto *II_End = dyn_cast_or_null(I_End);
1003 if (!II_End) {
1004 TokError("expected integer value as end of range");
1005 return true;
1006 }
1007
1008 End = II_End->getValue();
1009 break;
1010 }
1013 Lex.Lex();
1014 break;
1015 }
1016 }
1017 if (End < 0)
1018 return TokError("invalid range, cannot be negative");
1019
1020
1021 if (Start < End)
1022 for (; Start <= End; ++Start)
1023 Ranges.push_back(Start);
1024 else
1025 for (; Start >= End; --Start)
1026 Ranges.push_back(Start);
1027 return false;
1028}
1029
1030
1031
1032
1033
1035
1036 if (ParseRangePiece(Result)) {
1038 return;
1039 }
1041
1042 if (ParseRangePiece(Result)) {
1044 return;
1045 }
1046}
1047
1048
1049
1050
1054 return false;
1055
1056
1057 ParseRangeList(Ranges);
1058 if (Ranges.empty()) return true;
1059
1061 TokError("expected '>' at end of range list");
1062 return Error(StartLoc, "to match this '<'");
1063 }
1064 return false;
1065}
1066
1067
1068
1069
1073 return false;
1074
1075
1076 ParseRangeList(Ranges);
1077 if (Ranges.empty()) return true;
1078
1080 TokError("expected '}' at end of bit list");
1081 return Error(StartLoc, "to match this '{'");
1082 }
1083 return false;
1084}
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097const RecTy *TGParser::ParseType() {
1098 switch (Lex.getCode()) {
1099 default: TokError("Unknown token when expecting a type"); return nullptr;
1102 Lex.Lex();
1105 Lex.Lex();
1108 Lex.Lex();
1111 Lex.Lex();
1115 if (I != TypeAliases.end()) {
1116 Lex.Lex();
1117 return I->second;
1118 }
1119 if (const Record *R = ParseClassID())
1121 TokError("unknown class name");
1122 return nullptr;
1123 }
1126 TokError("expected '<' after bits type");
1127 return nullptr;
1128 }
1130 TokError("expected integer in bits type");
1131 return nullptr;
1132 }
1135 TokError("expected '>' at end of bits type");
1136 return nullptr;
1137 }
1138 Lex.Lex();
1140 }
1143 TokError("expected '<' after list type");
1144 return nullptr;
1145 }
1146 Lex.Lex();
1147 const RecTy *SubType = ParseType();
1148 if (!SubType) return nullptr;
1149
1151 TokError("expected '>' at end of list type");
1152 return nullptr;
1153 }
1155 }
1156 }
1157}
1158
1159
1161 SMRange NameLoc, IDParseMode Mode) {
1162 if (const Init *I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
1163 TrackReferenceLocs))
1164 return I;
1165
1166 if (Mode == ParseNameMode)
1167 return Name;
1168
1170
1171 if (TrackReferenceLocs) {
1172 if (const auto *Def = dyn_cast(I))
1173 Def->getDef()->appendReferenceLoc(NameLoc);
1174 }
1175 return I;
1176 }
1177
1178
1179
1180 if (CurRec && !CurRec->isClass() && !CurMultiClass &&
1183
1184 Error(NameLoc.Start, "Variable not defined: '" + Name->getValue() + "'");
1185 return nullptr;
1186}
1187
1188
1189
1190
1191
1192const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
1193 switch (Lex.getCode()) {
1194 default:
1195 TokError("unknown bang operator");
1196 return nullptr;
1212
1213 switch (Lex.getCode()) {
1216 Lex.Lex();
1218
1219 Type = ParseOperatorType();
1220
1221 if () {
1222 TokError("did not get type for unary operator");
1223 return nullptr;
1224 }
1225
1226 break;
1228 Lex.Lex();
1231 break;
1233 Lex.Lex();
1236 break;
1238 Lex.Lex();
1241 break;
1243 Lex.Lex();
1246 break;
1248 Lex.Lex();
1251 break;
1253 Lex.Lex();
1256 break;
1258 Lex.Lex();
1260 break;
1262 Lex.Lex();
1264 break;
1266 Lex.Lex();
1269 break;
1271 Lex.Lex();
1274 break;
1276 Lex.Lex();
1278
1279
1280
1281 Type = ParseOperatorType();
1282
1283 if () {
1284 TokError("did not get type for unary operator");
1285 return nullptr;
1286 }
1287
1288 if (!isa(Type)) {
1289 TokError("type for !getdagop must be a record type");
1290
1291 }
1292 } else {
1294 }
1296 break;
1298 Lex.Lex();
1301 break;
1302 }
1304 TokError("expected '(' after unary operator");
1305 return nullptr;
1306 }
1307
1308 const Init *LHS = ParseValue(CurRec);
1309 if (!LHS) return nullptr;
1310
1312 const auto *LHSl = dyn_cast(LHS);
1313 const auto *LHSs = dyn_cast(LHS);
1314 const auto *LHSd = dyn_cast(LHS);
1315 const auto *LHSt = dyn_cast(LHS);
1316 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1317 TokError("expected string, list, or dag type argument in unary operator");
1318 return nullptr;
1319 }
1320 if (LHSt) {
1321 if (!isa<ListRecTy, StringRecTy, DagRecTy>(LHSt->getType())) {
1322 TokError("expected string, list, or dag type argument in unary operator");
1323 return nullptr;
1324 }
1325 }
1326 }
1327
1330 const auto *LHSl = dyn_cast(LHS);
1331 const auto *LHSt = dyn_cast(LHS);
1332 if (!LHSl && !LHSt) {
1333 TokError("expected list type argument in unary operator");
1334 return nullptr;
1335 }
1336 if (LHSt) {
1337 if (!isa(LHSt->getType())) {
1338 TokError("expected list type argument in unary operator");
1339 return nullptr;
1340 }
1341 }
1342
1343 if (LHSl && LHSl->empty()) {
1344 TokError("empty list argument in unary operator");
1345 return nullptr;
1346 }
1347 bool UseElementType =
1349 if (LHSl) {
1350 const Init *Item = LHSl->getElement(0);
1351 const auto *Itemt = dyn_cast(Item);
1352 if (!Itemt) {
1353 TokError("untyped list element in unary operator");
1354 return nullptr;
1355 }
1356 Type = UseElementType ? Itemt->getType()
1358 } else {
1359 assert(LHSt && "expected list type argument in unary operator");
1360 const auto *LType = dyn_cast(LHSt->getType());
1361 Type = UseElementType ? LType->getElementType() : LType;
1362 }
1363
1364
1365
1367 const auto *InnerListTy = dyn_cast(Type);
1368 if (InnerListTy) {
1369
1371 } else {
1372
1374 }
1375 }
1376 }
1377
1379 TokError("expected ')' in unary operator");
1380 return nullptr;
1381 }
1383 }
1384
1386
1387 Lex.Lex();
1388
1389 const RecTy *Type = ParseOperatorType();
1391 return nullptr;
1392
1394 TokError("expected '(' after type of !isa");
1395 return nullptr;
1396 }
1397
1398 const Init *LHS = ParseValue(CurRec);
1399 if (!LHS)
1400 return nullptr;
1401
1403 TokError("expected ')' in !isa");
1404 return nullptr;
1405 }
1406
1408 }
1409
1411
1412 Lex.Lex();
1413
1414 const RecTy *Type = ParseOperatorType();
1416 return nullptr;
1417
1419 TokError("expected '(' after type of !exists");
1420 return nullptr;
1421 }
1422
1424 const Init *Expr = ParseValue(CurRec);
1425 if (!Expr)
1426 return nullptr;
1427
1428 const auto *ExprType = dyn_cast(Expr);
1429 if (!ExprType) {
1430 Error(ExprLoc, "expected string type argument in !exists operator");
1431 return nullptr;
1432 }
1433
1434 const auto *RecType = dyn_cast(ExprType->getType());
1435 if (RecType) {
1437 "expected string type argument in !exists operator, please "
1438 "use !isa instead");
1439 return nullptr;
1440 }
1441
1442 const auto *SType = dyn_cast(ExprType->getType());
1443 if (!SType) {
1444 Error(ExprLoc, "expected string type argument in !exists operator");
1445 return nullptr;
1446 }
1447
1449 TokError("expected ')' in !exists");
1450 return nullptr;
1451 }
1452
1454 }
1455
1480 case tgtok::XSetDagOp: {
1483 Lex.Lex();
1484
1486 switch (OpTok) {
1509 break;
1515 break;
1518 break;
1519 }
1520
1522 const RecTy *ArgType = nullptr;
1523 switch (OpTok) {
1524 default:
1530 break;
1532 Type = ParseOperatorType();
1533 if () {
1534 TokError("did not get type for !getdagarg operator");
1535 return nullptr;
1536 }
1538 break;
1542 break;
1555 break;
1563
1564 break;
1566
1567 ArgType = ItemType;
1568 break;
1570
1571 break;
1573
1574 ArgType = ItemType;
1575 break;
1579 break;
1582
1583 }
1584
1585 if (Type && ItemType && ->typeIsConvertibleTo(ItemType)) {
1586 Error(OpLoc, Twine("expected value of type '") +
1588 Type->getAsString() + "'");
1589 return nullptr;
1590 }
1591
1593 TokError("expected '(' after binary operator");
1594 return nullptr;
1595 }
1596
1598
1599
1600
1601 for (;;) {
1603 InitList.push_back(ParseValue(CurRec, ArgType));
1604 if (!InitList.back()) return nullptr;
1605
1606 const auto *InitListBack = dyn_cast(InitList.back());
1607 if (!InitListBack) {
1608 Error(OpLoc, Twine("expected value to be a typed value, got '" +
1609 InitList.back()->getAsString() + "'"));
1610 return nullptr;
1611 }
1612 const RecTy *ListType = InitListBack->getType();
1613
1614 if (!ArgType) {
1615
1616 ArgType = ListType;
1617
1618 switch (Code) {
1620 if (!isa(ArgType)) {
1621 Error(InitLoc, Twine("expected a list, got value of type '") +
1623 return nullptr;
1624 }
1625 break;
1627 if (ItemType && InitList.size() == 1) {
1628 if (!isa(ItemType)) {
1630 Twine("expected output type to be a list, got type '") +
1632 return nullptr;
1633 }
1635 Error(OpLoc, Twine("expected first arg type to be '") +
1637 "', got value of type '" +
1638 cast(ItemType)
1639 ->getElementType()
1640 ->getAsString() +
1641 "'");
1642 return nullptr;
1643 }
1644 }
1645 if (InitList.size() == 2 && !isa(ArgType)) {
1646 Error(InitLoc, Twine("expected second parameter to be an int, got "
1647 "value of type '") +
1649 return nullptr;
1650 }
1651 ArgType = nullptr;
1652 break;
1654 if (!isa(ArgType)) {
1655 Error(InitLoc, Twine("expected a list, got value of type '") +
1657 return nullptr;
1658 }
1659 break;
1665 Error(InitLoc, Twine("expected bit, bits, int, string, or record; "
1666 "got value of type '") +
1668 return nullptr;
1669 }
1670 break;
1672
1679 Error(InitLoc, Twine("expected bit, bits, int, or string; "
1680 "got value of type '") +
1682 return nullptr;
1683 }
1684 break;
1686 switch (InitList.size()) {
1687 case 1:
1691 Error(InitLoc, Twine("expected list of string, int, bits, or bit; "
1692 "got value of type '") +
1694 return nullptr;
1695 }
1696 break;
1697 case 2:
1698 if (!isa(ArgType)) {
1699 Error(InitLoc, Twine("expected second argument to be a string, "
1700 "got value of type '") +
1702 return nullptr;
1703 }
1704 break;
1705 default: ;
1706 }
1707 ArgType = nullptr;
1708 break;
1709 default: llvm_unreachable("other ops have fixed argument types");
1710 }
1711
1712 } else {
1713
1715 if (!Resolved) {
1716 Error(InitLoc, Twine("expected value of type '") +
1719 return nullptr;
1720 }
1727 }
1728
1729
1730
1731 switch (Code) {
1733
1734
1736 break;
1738
1739
1740 ArgType = nullptr;
1741 break;
1743
1745 break;
1746 default:
1747 break;
1748 }
1749
1751 break;
1752 }
1753
1755 TokError("expected ')' in operator");
1756 return nullptr;
1757 }
1758
1759
1761 Type = ArgType;
1762
1764 Type = cast(InitList.front())->getType()->getListTy();
1765
1767 Type = ArgType;
1768
1769
1770
1775 while (InitList.size() > 2) {
1779 }
1780 }
1781
1782 if (InitList.size() == 2)
1784 ->Fold(CurRec);
1785
1786 Error(OpLoc, "expected two operands to operator");
1787 return nullptr;
1788 }
1789
1792 return ParseOperationForEachFilter(CurRec, ItemType);
1793 }
1794
1797 Lex.Lex();
1798
1800 TokError("expected '(' after !range operator");
1801 return nullptr;
1802 }
1803
1805 bool FirstArgIsList = false;
1806 for (;;) {
1807 if (Args.size() >= 3) {
1808 TokError("expected at most three values of integer");
1809 return nullptr;
1810 }
1811
1813 Args.push_back(ParseValue(CurRec));
1814 if (.back())
1815 return nullptr;
1816
1817 const auto *ArgBack = dyn_cast(Args.back());
1818 if (!ArgBack) {
1819 Error(OpLoc, Twine("expected value to be a typed value, got '" +
1820 Args.back()->getAsString() + "'"));
1821 return nullptr;
1822 }
1823
1824 const RecTy *ArgBackType = ArgBack->getType();
1825 if (!FirstArgIsList || Args.size() == 1) {
1826 if (Args.size() == 1 && isa(ArgBackType)) {
1827 FirstArgIsList = true;
1828 } else if (isa(ArgBackType)) {
1829
1830 } else {
1831 if (Args.size() != 1)
1832 Error(InitLoc, Twine("expected value of type 'int', got '" +
1834 else
1835 Error(InitLoc, Twine("expected list or int, got value of type '") +
1837 return nullptr;
1838 }
1839 } else {
1840
1841 assert(isa(cast(Args[0])->getType()));
1842 Error(InitLoc, Twine("expected one list, got extra value of type '") +
1844 return nullptr;
1845 }
1847 break;
1848 }
1849
1851 TokError("expected ')' in operator");
1852 return nullptr;
1853 }
1854
1856 auto ArgCount = Args.size();
1857 assert(ArgCount >= 1);
1858 const auto *Arg0 = cast(Args[0]);
1859 const auto *Arg0Ty = Arg0->getType();
1860 if (ArgCount == 1) {
1861 if (isa(Arg0Ty)) {
1862
1865 ->Fold(CurRec);
1867 } else {
1868 assert(isa(Arg0Ty));
1869
1871 MHS = Arg0;
1873 }
1874 } else {
1875 assert(isa(Arg0Ty));
1876 const auto *Arg1 = cast(Args[1]);
1877 assert(isa(Arg1->getType()));
1878 LHS = Arg0;
1879 MHS = Arg1;
1880 if (ArgCount == 3) {
1881
1882 const auto *Arg2 = cast(Args[2]);
1883 assert(isa(Arg2->getType()));
1884 RHS = Arg2;
1885 } else
1886
1888 }
1891 ->Fold(CurRec);
1892 }
1893
1898 case tgtok::XSubst: {
1901
1903 Lex.Lex();
1904 switch (LexCode) {
1909 ItemType = nullptr;
1910 break;
1913 break;
1916 break;
1920 ItemType = nullptr;
1921 break;
1925 ItemType = nullptr;
1926 break;
1927 }
1929 TokError("expected '(' after ternary operator");
1930 return nullptr;
1931 }
1932
1933 const Init *LHS = ParseValue(CurRec);
1934 if (!LHS) return nullptr;
1935
1937 TokError("expected ',' in ternary operator");
1938 return nullptr;
1939 }
1940
1942 const Init *MHS = ParseValue(CurRec, ItemType);
1943 if (!MHS)
1944 return nullptr;
1945
1947 TokError("expected ',' in ternary operator");
1948 return nullptr;
1949 }
1950
1952 const Init *RHS = ParseValue(CurRec, ItemType);
1953 if (!RHS)
1954 return nullptr;
1955
1957 TokError("expected ')' in binary operator");
1958 return nullptr;
1959 }
1960
1961 switch (LexCode) {
1964 const auto *MHSt = dyn_cast(MHS);
1965 if (!MHSt && !isa(MHS)) {
1966 Error(MHSLoc, "could not determine type of the child list in !dag");
1967 return nullptr;
1968 }
1969 if (MHSt && !isa(MHSt->getType())) {
1970 Error(MHSLoc, Twine("expected list of children, got type '") +
1971 MHSt->getType()->getAsString() + "'");
1972 return nullptr;
1973 }
1974
1975 const auto *RHSt = dyn_cast(RHS);
1976 if (!RHSt && !isa(RHS)) {
1977 Error(RHSLoc, "could not determine type of the name list in !dag");
1978 return nullptr;
1979 }
1980 if (RHSt && StringRecTy::get(Records)->getListTy() != RHSt->getType()) {
1981 Error(RHSLoc, Twine("expected list, got type '") +
1982 RHSt->getType()->getAsString() + "'");
1983 return nullptr;
1984 }
1985
1986 if (!MHSt && !RHSt) {
1988 "cannot have both unset children and unset names in !dag");
1989 return nullptr;
1990 }
1991 break;
1992 }
1994 const RecTy *MHSTy = nullptr;
1995 const RecTy *RHSTy = nullptr;
1996
1997 if (const auto *MHSt = dyn_cast(MHS))
1998 MHSTy = MHSt->getType();
1999 if (const auto *MHSbits = dyn_cast(MHS))
2000 MHSTy = BitsRecTy::get(Records, MHSbits->getNumBits());
2001 if (isa(MHS))
2003
2004 if (const auto *RHSt = dyn_cast(RHS))
2005 RHSTy = RHSt->getType();
2006 if (const auto *RHSbits = dyn_cast(RHS))
2007 RHSTy = BitsRecTy::get(Records, RHSbits->getNumBits());
2008 if (isa(RHS))
2010
2011
2012 if (isa(MHS))
2013 MHSTy = RHSTy;
2014 if (isa(RHS))
2015 RHSTy = MHSTy;
2016
2017 if (!MHSTy || !RHSTy) {
2018 TokError("could not get type for !if");
2019 return nullptr;
2020 }
2021
2023 if () {
2025 "' and '" + RHSTy->getAsString() + "' for !if");
2026 return nullptr;
2027 }
2028 break;
2029 }
2031 const auto *RHSt = dyn_cast(RHS);
2032 if (!RHSt) {
2033 TokError("could not get type for !subst");
2034 return nullptr;
2035 }
2036 Type = RHSt->getType();
2037 break;
2038 }
2040 const auto *MHSt = dyn_cast(MHS);
2041 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
2042 Error(MHSLoc, Twine("expected integer index or string name, got ") +
2043 (MHSt ? ("type '" + MHSt->getType()->getAsString())
2045 "'");
2046 return nullptr;
2047 }
2048 break;
2049 }
2051 const auto *MHSt = dyn_cast(MHS);
2052 if (!MHSt || !isa<IntRecTy, StringRecTy>(MHSt->getType())) {
2053 Error(MHSLoc, Twine("expected integer index or string name, got ") +
2054 (MHSt ? ("type '" + MHSt->getType()->getAsString())
2056 "'");
2057 return nullptr;
2058 }
2059 const auto *RHSt = dyn_cast(RHS);
2060
2061 if (RHSt && !isa(RHSt->getType())) {
2062 Error(RHSLoc, Twine("expected string or unset name, got type '") +
2063 RHSt->getType()->getAsString() + "'");
2064 return nullptr;
2065 }
2066 break;
2067 }
2068 }
2070 }
2071
2073 return ParseOperationSubstr(CurRec, ItemType);
2074
2076 return ParseOperationFind(CurRec, ItemType);
2077
2079 return ParseOperationCond(CurRec, ItemType);
2080
2082
2083 Lex.Lex();
2085 TokError("expected '(' after !foldl");
2086 return nullptr;
2087 }
2088
2089 const Init *StartUntyped = ParseValue(CurRec);
2090 if (!StartUntyped)
2091 return nullptr;
2092
2093 const auto *Start = dyn_cast(StartUntyped);
2094 if (!Start) {
2095 TokError(Twine("could not get type of !foldl start: '") +
2097 return nullptr;
2098 }
2099
2101 TokError("expected ',' in !foldl");
2102 return nullptr;
2103 }
2104
2105 const Init *ListUntyped = ParseValue(CurRec);
2106 if (!ListUntyped)
2107 return nullptr;
2108
2109 const auto *List = dyn_cast(ListUntyped);
2110 if () {
2111 TokError(Twine("could not get type of !foldl list: '") +
2113 return nullptr;
2114 }
2115
2116 const auto *ListType = dyn_cast(List->getType());
2117 if (!ListType) {
2118 TokError(Twine("!foldl list must be a list, but is of type '") +
2119 List->getType()->getAsString());
2120 return nullptr;
2121 }
2122
2124 TokError("expected ',' in !foldl");
2125 return nullptr;
2126 }
2127
2128 if (Lex.Lex() != tgtok::Id) {
2129 TokError("third argument of !foldl must be an identifier");
2130 return nullptr;
2131 }
2132
2134 if (CurRec && CurRec->getValue(A)) {
2135 TokError((Twine("left !foldl variable '") + A->getAsString() +
2136 "' already defined")
2137 .str());
2138 return nullptr;
2139 }
2140
2142 TokError("expected ',' in !foldl");
2143 return nullptr;
2144 }
2145
2146 if (Lex.Lex() != tgtok::Id) {
2147 TokError("fourth argument of !foldl must be an identifier");
2148 return nullptr;
2149 }
2150
2152 if (CurRec && CurRec->getValue(B)) {
2153 TokError((Twine("right !foldl variable '") + B->getAsString() +
2154 "' already defined")
2155 .str());
2156 return nullptr;
2157 }
2158
2160 TokError("expected ',' in !foldl");
2161 return nullptr;
2162 }
2163 Lex.Lex();
2164
2165
2166
2167 std::unique_ptr ParseRecTmp;
2168 Record *ParseRec = CurRec;
2169 if (!ParseRec) {
2170 ParseRecTmp = std::make_unique(".parse", ArrayRef{}, Records);
2171 ParseRec = ParseRecTmp.get();
2172 }
2173
2176 ParseRec->addValue(
2178 const Init *ExprUntyped = ParseValue(ParseRec);
2179 ParseRec->removeValue(A);
2180 ParseRec->removeValue(B);
2182 if (!ExprUntyped)
2183 return nullptr;
2184
2185 const auto *Expr = dyn_cast(ExprUntyped);
2186 if (!Expr) {
2187 TokError("could not get type of !foldl expression");
2188 return nullptr;
2189 }
2190
2191 if (Expr->getType() != Start->getType()) {
2192 TokError(Twine("!foldl expression must be of same type as start (") +
2193 Start->getType()->getAsString() + "), but is of type " +
2195 return nullptr;
2196 }
2197
2199 TokError("expected ')' in fold operator");
2200 return nullptr;
2201 }
2202
2204 ->Fold(CurRec);
2205 }
2206 }
2207}
2208
2209
2210
2211
2212
2213
2214const RecTy *TGParser::ParseOperatorType() {
2216
2218 TokError("expected type name for operator");
2219 return nullptr;
2220 }
2221
2223 TokError("the 'code' type is not allowed in bang operators; use 'string'");
2224
2225 Type = ParseType();
2226
2227 if () {
2228 TokError("expected type name for operator");
2229 return nullptr;
2230 }
2231
2233 TokError("expected type name for operator");
2234 return nullptr;
2235 }
2236
2237 return Type;
2238}
2239
2240
2241
2242
2243const Init *TGParser::ParseOperationSubstr(Record *CurRec,
2244 const RecTy *ItemType) {
2247
2248 Lex.Lex();
2249
2251 TokError("expected '(' after !substr operator");
2252 return nullptr;
2253 }
2254
2255 const Init *LHS = ParseValue(CurRec);
2256 if (!LHS)
2257 return nullptr;
2258
2260 TokError("expected ',' in !substr operator");
2261 return nullptr;
2262 }
2263
2265 const Init *MHS = ParseValue(CurRec);
2266 if (!MHS)
2267 return nullptr;
2268
2272 RHSLoc = Lex.getLoc();
2273 RHS = ParseValue(CurRec);
2274 if (!RHS)
2275 return nullptr;
2276 } else {
2277 RHS = IntInit::get(Records, std::numeric_limits<int64_t>::max());
2278 }
2279
2281 TokError("expected ')' in !substr operator");
2282 return nullptr;
2283 }
2284
2285 if (ItemType && ->typeIsConvertibleTo(ItemType)) {
2286 Error(RHSLoc, Twine("expected value of type '") +
2288 Type->getAsString() + "'");
2289 }
2290
2291 const auto *LHSt = dyn_cast(LHS);
2292 if (!LHSt && !isa(LHS)) {
2293 TokError("could not determine type of the string in !substr");
2294 return nullptr;
2295 }
2296 if (LHSt && !isa(LHSt->getType())) {
2298 LHSt->getType()->getAsString() + "'");
2299 return nullptr;
2300 }
2301
2302 const auto *MHSt = dyn_cast(MHS);
2303 if (!MHSt && !isa(MHS)) {
2304 TokError("could not determine type of the start position in !substr");
2305 return nullptr;
2306 }
2307 if (MHSt && !isa(MHSt->getType())) {
2308 Error(MHSLoc, Twine("expected int, got type '") +
2309 MHSt->getType()->getAsString() + "'");
2310 return nullptr;
2311 }
2312
2313 if (RHS) {
2314 const auto *RHSt = dyn_cast(RHS);
2315 if (!RHSt && !isa(RHS)) {
2316 TokError("could not determine type of the length in !substr");
2317 return nullptr;
2318 }
2319 if (RHSt && !isa(RHSt->getType())) {
2321 RHSt->getType()->getAsString() + "'");
2322 return nullptr;
2323 }
2324 }
2325
2327}
2328
2329
2330
2331
2332const Init *TGParser::ParseOperationFind(Record *CurRec,
2333 const RecTy *ItemType) {
2336
2337 Lex.Lex();
2338
2340 TokError("expected '(' after !find operator");
2341 return nullptr;
2342 }
2343
2344 const Init *LHS = ParseValue(CurRec);
2345 if (!LHS)
2346 return nullptr;
2347
2349 TokError("expected ',' in !find operator");
2350 return nullptr;
2351 }
2352
2354 const Init *MHS = ParseValue(CurRec);
2355 if (!MHS)
2356 return nullptr;
2357
2361 RHSLoc = Lex.getLoc();
2362 RHS = ParseValue(CurRec);
2363 if (!RHS)
2364 return nullptr;
2365 } else {
2367 }
2368
2370 TokError("expected ')' in !find operator");
2371 return nullptr;
2372 }
2373
2374 if (ItemType && ->typeIsConvertibleTo(ItemType)) {
2375 Error(RHSLoc, Twine("expected value of type '") +
2377 Type->getAsString() + "'");
2378 }
2379
2380 const auto *LHSt = dyn_cast(LHS);
2381 if (!LHSt && !isa(LHS)) {
2382 TokError("could not determine type of the source string in !find");
2383 return nullptr;
2384 }
2385 if (LHSt && !isa(LHSt->getType())) {
2387 LHSt->getType()->getAsString() + "'");
2388 return nullptr;
2389 }
2390
2391 const auto *MHSt = dyn_cast(MHS);
2392 if (!MHSt && !isa(MHS)) {
2393 TokError("could not determine type of the target string in !find");
2394 return nullptr;
2395 }
2396 if (MHSt && !isa(MHSt->getType())) {
2397 Error(MHSLoc, Twine("expected string, got type '") +
2398 MHSt->getType()->getAsString() + "'");
2399 return nullptr;
2400 }
2401
2402 if (RHS) {
2403 const auto *RHSt = dyn_cast(RHS);
2404 if (!RHSt && !isa(RHS)) {
2405 TokError("could not determine type of the start position in !find");
2406 return nullptr;
2407 }
2408 if (RHSt && !isa(RHSt->getType())) {
2410 RHSt->getType()->getAsString() + "'");
2411 return nullptr;
2412 }
2413 }
2414
2416}
2417
2418
2419
2420
2421
2422const Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
2423 const RecTy *ItemType) {
2426 Lex.Lex();
2428 TokError("expected '(' after !foreach/!filter");
2429 return nullptr;
2430 }
2431
2432 if (Lex.Lex() != tgtok::Id) {
2433 TokError("first argument of !foreach/!filter must be an identifier");
2434 return nullptr;
2435 }
2436
2438 Lex.Lex();
2439
2440 if (CurRec && CurRec->getValue(LHS)) {
2441 TokError((Twine("iteration variable '") + LHS->getAsString() +
2442 "' is already defined")
2443 .str());
2444 return nullptr;
2445 }
2446
2448 TokError("expected ',' in !foreach/!filter");
2449 return nullptr;
2450 }
2451
2452 const Init *MHS = ParseValue(CurRec);
2453 if (!MHS)
2454 return nullptr;
2455
2457 TokError("expected ',' in !foreach/!filter");
2458 return nullptr;
2459 }
2460
2461 const auto *MHSt = dyn_cast(MHS);
2462 if (!MHSt) {
2463 TokError("could not get type of !foreach/!filter list or dag");
2464 return nullptr;
2465 }
2466
2467 const RecTy *InEltType = nullptr;
2468 const RecTy *ExprEltType = nullptr;
2469 bool IsDAG = false;
2470
2471 if (const auto *InListTy = dyn_cast(MHSt->getType())) {
2472 InEltType = InListTy->getElementType();
2473 if (ItemType) {
2474 if (const auto *OutListTy = dyn_cast(ItemType)) {
2476 ? OutListTy->getElementType()
2478 } else {
2480 "expected value of type '" +
2482 "', but got list type");
2483 return nullptr;
2484 }
2485 }
2486 } else if (const auto *InDagTy = dyn_cast(MHSt->getType())) {
2488 TokError("!filter must have a list argument");
2489 return nullptr;
2490 }
2491 InEltType = InDagTy;
2492 if (ItemType && !isa(ItemType)) {
2494 "expected value of type '" + Twine(ItemType->getAsString()) +
2495 "', but got dag type");
2496 return nullptr;
2497 }
2498 IsDAG = true;
2499 } else {
2501 TokError("!foreach must have a list or dag argument");
2502 else
2503 TokError("!filter must have a list argument");
2504 return nullptr;
2505 }
2506
2507
2508
2509 std::unique_ptr ParseRecTmp;
2510 Record *ParseRec = CurRec;
2511 if (!ParseRec) {
2512 ParseRecTmp =
2513 std::make_unique(".parse", ArrayRef{}, Records);
2514 ParseRec = ParseRecTmp.get();
2515 }
2518 const Init *RHS = ParseValue(ParseRec, ExprEltType);
2519 ParseRec->removeValue(LHS);
2521 if (!RHS)
2522 return nullptr;
2523
2525 TokError("expected ')' in !foreach/!filter");
2526 return nullptr;
2527 }
2528
2529 const RecTy *OutType = InEltType;
2531 const auto *RHSt = dyn_cast(RHS);
2532 if (!RHSt) {
2533 TokError("could not get type of !foreach result expression");
2534 return nullptr;
2535 }
2536 OutType = RHSt->getType()->getListTy();
2538 OutType = InEltType->getListTy();
2539 }
2540
2543 LHS, MHS, RHS, OutType))
2544 ->Fold(CurRec);
2545}
2546
2547const Init *TGParser::ParseOperationCond(Record *CurRec,
2548 const RecTy *ItemType) {
2549 Lex.Lex();
2550
2552 TokError("expected '(' after !cond operator");
2553 return nullptr;
2554 }
2555
2556
2559 while (true) {
2561 break;
2562
2563 const Init *V = ParseValue(CurRec);
2564 if (!V)
2565 return nullptr;
2567
2569 TokError("expected ':' following a condition in !cond operator");
2570 return nullptr;
2571 }
2572
2573 V = ParseValue(CurRec, ItemType);
2574 if (!V)
2575 return nullptr;
2577
2579 break;
2580
2582 TokError("expected ',' or ')' following a value in !cond operator");
2583 return nullptr;
2584 }
2585 }
2586
2587 if (Case.size() < 1) {
2588 TokError("there should be at least 1 'condition : value' in the !cond operator");
2589 return nullptr;
2590 }
2591
2592
2594 for (const Init *V : Val) {
2595 const RecTy *VTy = nullptr;
2596 if (const auto *Vt = dyn_cast(V))
2597 VTy = Vt->getType();
2598 if (const auto *Vbits = dyn_cast(V))
2600 if (isa(V))
2602
2603 if (Type == nullptr) {
2604 if (!isa(V))
2606 } else {
2607 if (!isa(V)) {
2609 if (!RType) {
2611 "' and '" + VTy->getAsString() + "' for !cond");
2612 return nullptr;
2613 }
2614 Type = RType;
2615 }
2616 }
2617 }
2618
2619 if () {
2620 TokError("could not determine type for !cond from its arguments");
2621 return nullptr;
2622 }
2624}
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653const Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
2654 IDParseMode Mode) {
2657
2658
2660 return ParseOperation(CurRec, ItemType);
2661
2662 switch (Code) {
2663 default: TokError("Unknown or reserved token when parsing a value"); break;
2664
2667 Lex.Lex();
2668 break;
2671 Lex.Lex();
2672 break;
2675 Lex.Lex();
2676 break;
2680 for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2681 Bits[i] = BitInit::get(Records, BinaryVal.first & (1LL << i));
2683 Lex.Lex();
2684 break;
2685 }
2688 Lex.Lex();
2689
2690
2693 Lex.Lex();
2694 }
2695
2697 break;
2698 }
2701 Lex.Lex();
2702 break;
2705 Lex.Lex();
2706 break;
2711 if (Next == tgtok::equal)
2712 return Name;
2713 if (Next != tgtok::less)
2714 return ParseIDValue(CurRec, Name, NameLoc, Mode);
2715
2716
2717
2718
2720 if (!Class) {
2722 "Expected a class name, got '" + Name->getValue() + "'");
2723 return nullptr;
2724 }
2725
2728 Lex.Lex();
2729 if (ParseTemplateArgValueList(Args, ArgLocs, CurRec, Class))
2730 return nullptr;
2731
2732 if (CheckTemplateArgValues(Args, ArgLocs, Class))
2733 return nullptr;
2734
2735 if (resolveArguments(Class, Args, NameLoc.Start))
2736 return nullptr;
2737
2738 if (TrackReferenceLocs)
2739 Class->appendReferenceLoc(NameLoc);
2741 }
2742 case tgtok::l_brace: {
2744 Lex.Lex();
2746
2748 ParseValueList(Vals, CurRec);
2749 if (Vals.empty()) return nullptr;
2750 }
2752 TokError("expected '}' at end of bit list value");
2753 return nullptr;
2754 }
2755
2757
2758
2759
2760
2761 for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
2762
2763
2764
2765
2766 if (const auto *BI = dyn_cast(Vals[i])) {
2767 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
2769 continue;
2770 }
2771
2772 if (const auto *VI = dyn_cast(Vals[i])) {
2773 if (const auto *BitsRec = dyn_cast(VI->getType())) {
2774 for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
2775 NewBits.push_back(VI->getBit((e - i) - 1));
2776 continue;
2777 }
2778
2779 }
2780
2782 if (!Bit) {
2783 Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
2784 ") is not convertable to a bit");
2785 return nullptr;
2786 }
2788 }
2789 std::reverse(NewBits.begin(), NewBits.end());
2791 }
2793 Lex.Lex();
2795
2796 const RecTy *DeducedEltTy = nullptr;
2797 const ListRecTy *GivenListTy = nullptr;
2798
2799 if (ItemType) {
2800 const auto *ListType = dyn_cast(ItemType);
2801 if (!ListType) {
2802 TokError(Twine("Encountered a list when expecting a ") +
2804 return nullptr;
2805 }
2806 GivenListTy = ListType;
2807 }
2808
2810 ParseValueList(Vals, CurRec,
2811 GivenListTy ? GivenListTy->getElementType() : nullptr);
2812 if (Vals.empty()) return nullptr;
2813 }
2815 TokError("expected ']' at end of list value");
2816 return nullptr;
2817 }
2818
2819 const RecTy *GivenEltTy = nullptr;
2821
2822 GivenEltTy = ParseType();
2823 if (!GivenEltTy) {
2824
2825 return nullptr;
2826 }
2827
2829 TokError("expected '>' at end of list element type");
2830 return nullptr;
2831 }
2832 }
2833
2834
2835 const RecTy *EltTy = nullptr;
2836 for (const Init *V : Vals) {
2837 const auto *TArg = dyn_cast(V);
2838 if (TArg) {
2839 if (EltTy) {
2840 EltTy = resolveTypes(EltTy, TArg->getType());
2841 if (!EltTy) {
2842 TokError("Incompatible types in list elements");
2843 return nullptr;
2844 }
2845 } else {
2846 EltTy = TArg->getType();
2847 }
2848 }
2849 }
2850
2851 if (GivenEltTy) {
2852 if (EltTy) {
2853
2855 TokError("Incompatible types in list elements");
2856 return nullptr;
2857 }
2858 }
2859 EltTy = GivenEltTy;
2860 }
2861
2862 if (!EltTy) {
2863 if (!ItemType) {
2864 TokError("No type for list");
2865 return nullptr;
2866 }
2868 } else {
2869
2870 if (GivenListTy) {
2872 TokError(Twine("Element type mismatch for list: element type '") +
2873 EltTy->getAsString() + "' not convertible to '" +
2875 return nullptr;
2876 }
2877 }
2878 DeducedEltTy = EltTy;
2879 }
2880
2882 }
2883 case tgtok::l_paren: {
2884
2885 Lex.Lex();
2889 TokError("expected identifier or list of value types in dag init");
2890 return nullptr;
2891 }
2892
2894 if () return nullptr;
2895
2896
2897 const StringInit *OperatorName = nullptr;
2900 TokError("expected variable name in dag operator");
2901 return nullptr;
2902 }
2904 Lex.Lex();
2905 }
2906
2909 ParseDagArgList(DagArgs, CurRec);
2910 if (DagArgs.empty()) return nullptr;
2911 }
2912
2914 TokError("expected ')' in dag init");
2915 return nullptr;
2916 }
2917
2919 }
2920 }
2921
2922 return R;
2923}
2924
2925
2926
2927
2928
2929
2930
2931
2932const Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
2933 IDParseMode Mode) {
2935 const Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
2936 if (!Result) return nullptr;
2937
2938
2939 while (true) {
2940 switch (Lex.getCode()) {
2941 default: return Result;
2943 if (Mode == ParseNameMode)
2944
2946
2948 Lex.Lex();
2950 ParseRangeList(Ranges);
2951 if (Ranges.empty()) return nullptr;
2952
2953
2955 Result = Result->convertInitializerBitRange(Ranges);
2956 if (!Result) {
2957 Error(CurlyLoc, "Invalid bit range for value");
2958 return nullptr;
2959 }
2960
2961
2963 TokError("expected '}' at end of bit range list");
2964 return nullptr;
2965 }
2966 break;
2967 }
2969 const auto *LHS = dyn_cast(Result);
2970 if (!LHS) {
2971 Error(LHSLoc, "Invalid value, list expected");
2972 return nullptr;
2973 }
2974
2975 const auto *LHSTy = dyn_cast(LHS->getType());
2976 if (!LHSTy) {
2978 "' is invalid, list expected");
2979 return nullptr;
2980 }
2981
2982 Lex.Lex();
2983 const TypedInit *RHS = ParseSliceElements(CurRec, true);
2984 if (!RHS)
2985 return nullptr;
2986
2987 if (isa(RHS->getType())) {
2990 } else {
2992 LHSTy->getElementType())
2993 ->Fold(CurRec);
2994 }
2995
2997
2998
3000 TokError("expected ']' at end of list slice");
3001 return nullptr;
3002 }
3003 break;
3004 }
3007 TokError("expected field identifier after '.'");
3008 return nullptr;
3009 }
3013 if (->getFieldType(FieldName)) {
3015 Result->getAsString() + "'");
3016 return nullptr;
3017 }
3018
3019
3020 if (TrackReferenceLocs) {
3021 if (const auto *DI = dyn_cast(Result)) {
3022 const RecordVal *V = DI->getDef()->getValue(FieldName);
3023 const_cast<RecordVal *>(V)->addReferenceLoc(FieldNameLoc);
3024 } else if (const auto *TI = dyn_cast(Result)) {
3025 if (const auto *RecTy = dyn_cast(TI->getType())) {
3026 for (const Record *R : RecTy->getClasses())
3027 if (const auto *RV = R->getValue(FieldName))
3029 }
3030 }
3031 }
3032
3034 Lex.Lex();
3035 break;
3036 }
3037
3040 const auto *LHS = dyn_cast(Result);
3041 if (!LHS) {
3042 Error(PasteLoc, "LHS of paste is not typed!");
3043 return nullptr;
3044 }
3045
3046
3047 if (isa(LHS->getType())) {
3048 Lex.Lex();
3049
3050 assert(Mode == ParseValueMode && "encountered paste of lists in name");
3051
3052 switch (Lex.getCode()) {
3057 break;
3058 default:
3059 const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3060 if (!RHSResult)
3061 return nullptr;
3063 break;
3064 }
3065 break;
3066 }
3067
3068
3069
3071 auto CastLHS = dyn_cast(
3073 ->Fold(CurRec));
3074 if (!CastLHS) {
3076 Twine("can't cast '") + LHS->getAsString() + "' to string");
3077 return nullptr;
3078 }
3079 LHS = CastLHS;
3080 }
3081
3083
3084 Lex.Lex();
3085 switch (Lex.getCode()) {
3089
3090
3091
3092
3093
3095 break;
3096
3097 default:
3098 const Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
3099 if (!RHSResult)
3100 return nullptr;
3101 RHS = dyn_cast(RHSResult);
3102 if (!RHS) {
3103 Error(PasteLoc, "RHS of paste is not typed!");
3104 return nullptr;
3105 }
3106
3108 auto CastRHS = dyn_cast(
3110 ->Fold(CurRec));
3111 if (!CastRHS) {
3113 Twine("can't cast '") + RHS->getAsString() + "' to string");
3114 return nullptr;
3115 }
3116 RHS = CastRHS;
3117 }
3118
3119 break;
3120 }
3121
3123 break;
3124 }
3125 }
3126}
3127
3128
3129
3130
3131
3132
3133
3134void TGParser::ParseDagArgList(
3135 SmallVectorImpl<std::pair<const Init *, const StringInit *>> &Result,
3137
3138 while (true) {
3139
3141
3144 Lex.Lex();
3145 } else {
3146
3147 const Init *Val = ParseValue(CurRec);
3148 if (!Val) {
3150 return;
3151 }
3152
3153
3157 TokError("expected variable name in dag literal");
3159 return;
3160 }
3162 Lex.Lex();
3163 }
3164
3165 Result.emplace_back(Val, VarName);
3166 }
3168 break;
3169 }
3170}
3171
3172
3173
3174
3175
3176
3177
3179 Record *CurRec, const RecTy *ItemType) {
3180 Result.push_back(ParseValue(CurRec, ItemType));
3181 if (.back()) {
3183 return;
3184 }
3185
3187
3189 return;
3190 Result.push_back(ParseValue(CurRec, ItemType));
3191 if (.back()) {
3193 return;
3194 }
3195 }
3196}
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206bool TGParser::ParseTemplateArgValueList(
3209 assert(Result.empty() && "Result vector is not empty");
3211
3213 return false;
3214
3215 bool HasNamedArg = false;
3216 unsigned ArgIndex = 0;
3217 while (true) {
3218 if (ArgIndex >= TArgs.size()) {
3219 TokError("Too many template arguments: " + utostr(ArgIndex + 1));
3220 return true;
3221 }
3222
3224
3225
3227 CurRec,
3228 HasNamedArg ? nullptr : ArgsRec->getValue(TArgs[ArgIndex])->getType());
3230 return true;
3231
3232
3234 if (!isa(Value))
3235 return Error(ValueLoc,
3236 "The name of named argument should be a valid identifier");
3237
3238 auto *Name = cast(Value);
3241 if (!NamedArg)
3242 return Error(ValueLoc,
3243 "Argument " + Name->getAsString() + " doesn't exist");
3244
3245 Lex.Lex();
3246 ValueLoc = Lex.getLoc();
3247 Value = ParseValue(CurRec, NamedArg->getType());
3248
3249 if (isa(Value))
3250 return Error(ValueLoc,
3251 "The value of named argument should be initialized, "
3252 "but we got '" +
3253 Value->getAsString() + "'");
3254
3256 HasNamedArg = true;
3257 } else {
3258
3259 if (HasNamedArg)
3260 return Error(ValueLoc,
3261 "Positional argument should be put before named argument");
3262
3264 }
3265
3267 return false;
3269 return TokError("Expected comma before next argument");
3270 ++ArgIndex;
3271 }
3272}
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284const Init *TGParser::ParseDeclaration(Record *CurRec,
3285 bool ParsingTemplateArgs) {
3286
3288
3289 const RecTy *Type = ParseType();
3290 if () return nullptr;
3291
3293 TokError("Expected identifier in declaration");
3294 return nullptr;
3295 }
3296
3298 if (Str == "NAME") {
3299 TokError("'" + Str + "' is a reserved variable name");
3300 return nullptr;
3301 }
3302
3303 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {
3304 TokError("local variable of this name already exists");
3305 return nullptr;
3306 }
3307
3310 Lex.Lex();
3311
3312 bool BadField;
3313 if (!ParsingTemplateArgs) {
3314 BadField = AddValue(CurRec, IdLoc,
3318 } else if (CurRec) {
3319 DeclName = QualifyName(*CurRec, DeclName);
3320 BadField =
3321 AddValue(CurRec, IdLoc,
3323 } else {
3324 assert(CurMultiClass && "invalid context for template argument");
3325 DeclName = QualifyName(CurMultiClass, DeclName);
3326 BadField =
3327 AddValue(CurRec, IdLoc,
3329 }
3330 if (BadField)
3331 return nullptr;
3332
3333
3336 const Init *Val = ParseValue(CurRec, Type);
3337 if (!Val ||
3338 SetValue(CurRec, ValLoc, DeclName, {}, Val,
3339 false, false)) {
3340
3341
3342
3343 return DeclName;
3344 }
3345 }
3346
3347 return DeclName;
3348}
3349
3350
3351
3352
3353
3354
3355
3356
3357
3359TGParser::ParseForeachDeclaration(const Init *&ForeachListValue) {
3361 TokError("Expected identifier in foreach declaration");
3362 return nullptr;
3363 }
3364
3366 Lex.Lex();
3367
3368
3370 TokError("Expected '=' in foreach declaration");
3371 return nullptr;
3372 }
3373
3374 const RecTy *IterType = nullptr;
3376
3377 switch (Lex.getCode()) {
3379 Lex.Lex();
3380 ParseRangeList(Ranges);
3382 TokError("expected '}' at end of bit range list");
3383 return nullptr;
3384 }
3385 break;
3386 }
3387
3388 default: {
3390 const Init *I = ParseValue(nullptr);
3391 if ()
3392 return nullptr;
3393
3394 const auto *TI = dyn_cast(I);
3395 if (TI && isa(TI->getType())) {
3396 ForeachListValue = I;
3397 IterType = cast(TI->getType())->getElementType();
3398 break;
3399 }
3400
3401 if (TI) {
3402 if (ParseRangePiece(Ranges, TI))
3403 return nullptr;
3404 break;
3405 }
3406
3407 Error(ValueLoc, "expected a list, got '" + I->getAsString() + "'");
3408 if (CurMultiClass) {
3409 PrintNote({}, "references to multiclass template arguments cannot be "
3410 "resolved at this time");
3411 }
3412 return nullptr;
3413 }
3414 }
3415
3416
3417 if (.empty()) {
3418 assert(!IterType && "Type already initialized?");
3420 std::vector<Init *> Values;
3421 for (unsigned R : Ranges)
3423 ForeachListValue = ListInit::get(Values, IterType);
3424 }
3425
3426 if (!IterType)
3427 return nullptr;
3428
3430}
3431
3432
3433
3434
3435
3436
3437
3438
3439bool TGParser::ParseTemplateArgList(Record *CurRec) {
3441 Lex.Lex();
3442
3443 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
3444
3445
3446 const Init *TemplArg = ParseDeclaration(CurRec, true );
3447 if (!TemplArg)
3448 return true;
3449
3451
3453
3455 TemplArg = ParseDeclaration(CurRec, true);
3456 if (!TemplArg)
3457 return true;
3458
3460 return Error(Loc, "template argument with the same name has already been "
3461 "defined");
3462
3464 }
3465
3467 return TokError("expected '>' at end of template argument list");
3468 return false;
3469}
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479bool TGParser::ParseBodyItem(Record *CurRec) {
3481 return ParseAssert(nullptr, CurRec);
3482
3484 return ParseDefvar(CurRec);
3485
3487 return ParseDump(nullptr, CurRec);
3488
3490 if (!ParseDeclaration(CurRec, false))
3491 return true;
3492
3494 return TokError("expected ';' after declaration");
3495 return false;
3496 }
3497
3498
3500 return TokError("expected field identifier after let");
3501
3504 Lex.Lex();
3505
3507 if (ParseOptionalBitList(BitList))
3508 return true;
3509 std::reverse(BitList.begin(), BitList.end());
3510
3512 return TokError("expected '=' in let expression");
3513
3516 return Error(IdLoc, "Value '" + FieldName->getValue() + "' unknown!");
3517
3519 if (!BitList.empty() && isa(Type)) {
3520
3521
3523 }
3524
3525 const Init *Val = ParseValue(CurRec, Type);
3526 if (!Val) return true;
3527
3529 return TokError("expected ';' after let expression");
3530
3531 return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
3532}
3533
3534
3535
3536
3537
3538
3539
3540
3541bool TGParser::ParseBody(Record *CurRec) {
3542
3544 return false;
3545
3547 return TokError("Expected '{' to start body or ';' for declaration only");
3548
3550 if (ParseBodyItem(CurRec))
3551 return true;
3552
3553
3554 Lex.Lex();
3555
3556
3559 PrintError(SemiLoc, "A class or def body should not end with a semicolon");
3560 PrintNote("Semicolon ignored; remove to eliminate this error");
3561 }
3562
3563 return false;
3564}
3565
3566
3567
3568bool TGParser::ApplyLetStack(Record *CurRec) {
3571 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
3572 return true;
3573 return false;
3574}
3575
3576
3577bool TGParser::ApplyLetStack(RecordsEntry &Entry) {
3579 return ApplyLetStack(Entry.Rec.get());
3580
3581
3582 if (Entry.Assertion)
3583 return false;
3584
3585
3587 return false;
3588
3589 for (auto &E : Entry.Loop->Entries) {
3590 if (ApplyLetStack(E))
3591 return true;
3592 }
3593
3594 return false;
3595}
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606bool TGParser::ParseObjectBody(Record *CurRec) {
3607
3609
3611
3612
3613 SubClassReference SubClass = ParseSubClassReference(CurRec, false);
3614 while (true) {
3615
3616 if (!SubClass.Rec) return true;
3617
3618
3619 if (AddSubClass(CurRec, SubClass))
3620 return true;
3621
3623 break;
3624 SubClass = ParseSubClassReference(CurRec, false);
3625 }
3626 }
3627
3628 if (ApplyLetStack(CurRec))
3629 return true;
3630
3631 bool Result = ParseBody(CurRec);
3634}
3635
3636
3637
3638
3639
3640
3641bool TGParser::ParseDef(MultiClass *CurMultiClass) {
3644 Lex.Lex();
3645
3646
3647
3648
3650
3651
3652 std::unique_ptr CurRec;
3653 const Init *Name = ParseObjectName(CurMultiClass);
3655 return true;
3656
3657 if (isa(Name)) {
3658 CurRec = std::make_unique(Records.getNewAnonymousName(), DefLoc,
3660 } else {
3661 CurRec = std::make_unique(Name, NameLoc, Records);
3662 }
3663
3664 if (ParseObjectBody(CurRec.get()))
3665 return true;
3666
3667 return addEntry(std::move(CurRec));
3668}
3669
3670
3671
3672
3673
3674bool TGParser::ParseDefset() {
3676 Lex.Lex();
3677
3680 const RecTy *Type = ParseType();
3682 return true;
3683 if (!isa(Type))
3684 return Error(Defset.Loc, "expected list type");
3685 Defset.EltTy = cast(Type)->getElementType();
3686
3688 return TokError("expected identifier");
3691 return TokError("def or global variable of this name already exists");
3692
3694 return TokError("expected '='");
3696 return TokError("expected '{'");
3698 Lex.Lex();
3699
3700 Defsets.push_back(&Defset);
3701 bool Err = ParseObjectList(nullptr);
3702 Defsets.pop_back();
3703 if (Err)
3704 return true;
3705
3707 TokError("expected '}' at end of defset");
3708 return Error(BraceLoc, "to match this '{'");
3709 }
3710
3713 return false;
3714}
3715
3716
3717
3718
3719
3720bool TGParser::ParseDeftype() {
3722 Lex.Lex();
3723
3725 return TokError("expected identifier");
3726
3728 if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
3729 return TokError("type of this name '" + TypeName + "' already exists");
3730
3731 Lex.Lex();
3733 return TokError("expected '='");
3734
3736 const RecTy *Type = ParseType();
3738 return true;
3739
3741 return Error(Loc, "cannot define type alias for class type '" +
3742 Type->getAsString() + "'");
3743
3745
3747 return TokError("expected ';'");
3748
3749 return false;
3750}
3751
3752
3753
3754
3755
3756bool TGParser::ParseDefvar(Record *CurRec) {
3758 Lex.Lex();
3759
3761 return TokError("expected identifier");
3763 if (CurScope->varAlreadyDefined(DeclName->getValue()))
3764 return TokError("local variable of this name already exists");
3765
3766
3767 if (CurRec) {
3769 if (V && ->isTemplateArg())
3770 return TokError("field of this name already exists");
3771 }
3772
3773
3774
3775 if (CurScope->isOutermost() && Records.getGlobal(DeclName->getValue()))
3776 return TokError("def or global variable of this name already exists");
3777
3778 Lex.Lex();
3780 return TokError("expected '='");
3781
3782 const Init *Value = ParseValue(CurRec);
3784 return true;
3785
3787 return TokError("expected ';'");
3788
3789 if (!CurScope->isOutermost())
3791 else
3793
3794 return false;
3795}
3796
3797
3798
3799
3800
3801
3802
3803bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
3806 Lex.Lex();
3807
3808
3809
3810 const Init *ListValue = nullptr;
3811 const VarInit *IterName = ParseForeachDeclaration(ListValue);
3812 if (!IterName)
3813 return TokError("expected declaration in for");
3814
3816 return TokError("Unknown tok");
3817
3818
3819 auto TheLoop = std::make_unique(Loc, IterName, ListValue);
3820
3822 Loops.push_back(std::move(TheLoop));
3823
3825
3826 if (ParseObject(CurMultiClass))
3827 return true;
3828 } else {
3830
3831 Lex.Lex();
3832
3833
3834 if (ParseObjectList(CurMultiClass))
3835 return true;
3836
3838 TokError("expected '}' at end of foreach command");
3839 return Error(BraceLoc, "to match this '{'");
3840 }
3841 }
3842
3844
3845
3846 std::unique_ptr Loop = std::move(Loops.back());
3847 Loops.pop_back();
3848
3849 return addEntry(std::move(Loop));
3850}
3851
3852
3853
3854
3855
3856
3857bool TGParser::ParseIf(MultiClass *CurMultiClass) {
3860 Lex.Lex();
3861
3862
3863
3864 const Init *Condition = ParseValue(nullptr);
3865 if (!Condition)
3866 return true;
3867
3869 return TokError("Unknown tok");
3870
3871
3872
3873
3874
3875
3876
3878 const ListInit *SingletonList =
3881
3882
3883
3884 const Init *ThenClauseList =
3886 BitListTy)
3887 ->Fold(nullptr);
3888 Loops.push_back(std::make_unique(Loc, nullptr, ThenClauseList));
3889
3890 if (ParseIfBody(CurMultiClass, "then"))
3891 return true;
3892
3893 std::unique_ptr Loop = std::move(Loops.back());
3894 Loops.pop_back();
3895
3896 if (addEntry(std::move(Loop)))
3897 return true;
3898
3899
3900
3901
3902
3904
3905
3906 const Init *ElseClauseList =
3908 BitListTy)
3909 ->Fold(nullptr);
3910 Loops.push_back(
3911 std::make_unique(Loc, nullptr, ElseClauseList));
3912
3913 if (ParseIfBody(CurMultiClass, "else"))
3914 return true;
3915
3916 Loop = std::move(Loops.back());
3917 Loops.pop_back();
3918
3919 if (addEntry(std::move(Loop)))
3920 return true;
3921 }
3922
3923 return false;
3924}
3925
3926
3927
3928
3929
3930
3932
3934
3936
3937 if (ParseObject(CurMultiClass))
3938 return true;
3939 } else {
3941
3942 Lex.Lex();
3943
3944
3945 if (ParseObjectList(CurMultiClass))
3946 return true;
3947
3949 TokError("expected '}' at end of '" + Kind + "' clause");
3950 return Error(BraceLoc, "to match this '{'");
3951 }
3952 }
3953
3955 return false;
3956}
3957
3958
3959
3960
3961bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
3963 Lex.Lex();
3964
3966 const Init *Condition = ParseValue(CurRec);
3967 if (!Condition)
3968 return true;
3969
3971 TokError("expected ',' in assert statement");
3972 return true;
3973 }
3974
3975 const Init *Message = ParseValue(CurRec);
3976 if (!Message)
3977 return true;
3978
3980 return TokError("expected ';'");
3981
3982 if (CurRec)
3983 CurRec->addAssertion(ConditionLoc, Condition, Message);
3984 else
3985 addEntry(std::make_uniqueRecord::AssertionInfo(ConditionLoc, Condition,
3986 Message));
3987 return false;
3988}
3989
3990
3991
3992
3993
3994bool TGParser::ParseClass() {
3996 Lex.Lex();
3997
3999 return TokError("expected class name after 'class' keyword");
4000
4003 if (CurRec) {
4004
4005 if (!CurRec->getValues().empty() ||
4009 "' already defined");
4010
4012 } else {
4013
4014 auto NewRec = std::make_unique(Lex.getCurStrVal(), Lex.getLoc(),
4016 CurRec = NewRec.get();
4017 Records.addClass(std::move(NewRec));
4018 }
4019
4020 if (TypeAliases.count(Name))
4021 return TokError("there is already a defined type alias '" + Name + "'");
4022
4023 Lex.Lex();
4024
4025
4027
4029 if (ParseTemplateArgList(CurRec))
4030 return true;
4031
4032 if (ParseObjectBody(CurRec))
4033 return true;
4034
4035 if (!NoWarnOnUnusedTemplateArgs)
4037
4039 return false;
4040}
4041
4042
4043
4044
4045
4046
4047
4049 do {
4051 TokError("expected identifier in let definition");
4053 return;
4054 }
4055
4058 Lex.Lex();
4059
4060
4062 if (ParseOptionalRangeList(Bits)) {
4064 return;
4065 }
4066 std::reverse(Bits.begin(), Bits.end());
4067
4069 TokError("expected '=' in let expression");
4071 return;
4072 }
4073
4074 const Init *Val = ParseValue(nullptr);
4075 if (!Val) {
4077 return;
4078 }
4079
4080
4081 Result.emplace_back(Name, Bits, Val, NameLoc);
4083}
4084
4085
4086
4087
4088
4089
4090
4091bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
4093 Lex.Lex();
4094
4095
4097 ParseLetList(LetInfo);
4098 if (LetInfo.empty()) return true;
4099 LetStack.push_back(std::move(LetInfo));
4100
4102 return TokError("expected 'in' at end of top-level 'let'");
4103
4104
4106
4107 if (ParseObject(CurMultiClass))
4108 return true;
4109 } else {
4111
4112 Lex.Lex();
4113
4114
4116
4117
4118 if (ParseObjectList(CurMultiClass))
4119 return true;
4120
4122 TokError("expected '}' at end of top level let command");
4123 return Error(BraceLoc, "to match this '{'");
4124 }
4125
4127 }
4128
4129
4131 return false;
4132}
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147bool TGParser::ParseMultiClass() {
4149 Lex.Lex();
4150
4152 return TokError("expected identifier after multiclass for name");
4154
4155 auto Result = MultiClasses.try_emplace(
4156 Name, std::make_unique(Name, Lex.getLoc(), Records));
4157
4159 return TokError("multiclass '" + Name + "' already defined");
4160
4161 CurMultiClass = Result.first->second.get();
4162 Lex.Lex();
4163
4164
4166
4167
4169 if (ParseTemplateArgList(nullptr))
4170 return true;
4171
4172 bool inherits = false;
4173
4174
4176 inherits = true;
4177
4178
4180 ParseSubMultiClassReference(CurMultiClass);
4181 while (true) {
4182
4183 if (!SubMultiClass.MC) return true;
4184
4185
4186 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
4187 return true;
4188
4190 break;
4191 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
4192 }
4193 }
4194
4196 if (!inherits)
4197 return TokError("expected '{' in multiclass definition");
4199 return TokError("expected ';' in multiclass definition");
4200 } else {
4202 return TokError("multiclass must contain at least one def");
4203
4205 switch (Lex.getCode()) {
4206 default:
4207 return TokError("expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4208 "'foreach', 'if', or 'let' in multiclass body");
4209
4218 if (ParseObject(CurMultiClass))
4219 return true;
4220 break;
4221 }
4222 }
4223 Lex.Lex();
4224
4225
4228 PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
4229 PrintNote("Semicolon ignored; remove to eliminate this error");
4230 }
4231 }
4232
4233 if (!NoWarnOnUnusedTemplateArgs)
4235
4237 CurMultiClass = nullptr;
4238 return false;
4239}
4240
4241
4242
4243
4244
4245bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
4247 Lex.Lex();
4248
4249 const Init *DefmName = ParseObjectName(CurMultiClass);
4250 if (!DefmName)
4251 return true;
4252 if (isa(DefmName)) {
4254 if (CurMultiClass)
4258 DefmName);
4259 }
4260
4262 return TokError("expected ':' after defm identifier");
4263
4264
4265 std::vector NewEntries;
4266
4267
4268 bool InheritFromClass = false;
4269
4270
4271 Lex.Lex();
4272
4275
4276 while (true) {
4277 if (.Rec) return true;
4278
4279
4280
4281
4282
4283 MultiClass *MC = MultiClasses[std::string(Ref.Rec->getName())].get();
4284 assert(MC && "Didn't lookup multiclass correctly?");
4285
4286 SubstStack Substs;
4287 if (resolveArgumentsOfMultiClass(Substs, MC, Ref.TemplateArgs, DefmName,
4288 SubClassLoc))
4289 return true;
4290
4291 if (resolve(MC->Entries, Substs, !CurMultiClass && Loops.empty(),
4292 &NewEntries, &SubClassLoc))
4293 return true;
4294
4296 break;
4297
4299 return TokError("expected identifier");
4300
4301 SubClassLoc = Lex.getLoc();
4302
4303
4304
4306
4307 if (InheritFromClass)
4308 break;
4309
4310 Ref = ParseSubClassReference(nullptr, true);
4311 }
4312
4313 if (InheritFromClass) {
4314
4315
4316 SubClassReference SubClass = ParseSubClassReference(nullptr, false);
4317 while (true) {
4318
4319 if (!SubClass.Rec) return true;
4320
4321
4322
4323 for (auto &E : NewEntries) {
4324
4325 if (AddSubClass(E, SubClass))
4326 return true;
4327 }
4328
4330 break;
4331 SubClass = ParseSubClassReference(nullptr, false);
4332 }
4333 }
4334
4335 for (auto &E : NewEntries) {
4336 if (ApplyLetStack(E))
4337 return true;
4338
4339 addEntry(std::move(E));
4340 }
4341
4343 return TokError("expected ';' at end of defm");
4344
4345 return false;
4346}
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360bool TGParser::ParseObject(MultiClass *MC) {
4361 switch (Lex.getCode()) {
4362 default:
4364 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4366 case tgtok::Def: return ParseDef(MC);
4369 return ParseDeftype();
4372 return ParseDump(MC);
4374 case tgtok::If: return ParseIf(MC);
4375 case tgtok::Let: return ParseTopLevelLet(MC);
4377 if (MC)
4378 return TokError("defset is not allowed inside multiclass");
4379 return ParseDefset();
4381 if (MC)
4382 return TokError("class is not allowed inside multiclass");
4383 if (!Loops.empty())
4384 return TokError("class is not allowed inside foreach loop");
4385 return ParseClass();
4387 if (!Loops.empty())
4388 return TokError("multiclass is not allowed inside foreach loop");
4389 return ParseMultiClass();
4390 }
4391}
4392
4393
4394
4395bool TGParser::ParseObjectList(MultiClass *MC) {
4397 if (ParseObject(MC))
4398 return true;
4399 }
4400 return false;
4401}
4402
4404 Lex.Lex();
4406 if (ParseObjectList())
4407 return true;
4409
4410
4412 return false;
4413
4414 return TokError("Unexpected token at top level");
4415}
4416
4417
4418
4419
4420
4421bool TGParser::CheckTemplateArgValues(
4423 const Record *ArgsRec) {
4425 "expected as many values as locations");
4426
4428
4429 bool HasError = false;
4431 const Init *ArgName = nullptr;
4432 if (Value->isPositional())
4433 ArgName = TArgs[Value->getIndex()];
4434 if (Value->isNamed())
4436
4439
4440 if (const auto *ArgValue = dyn_cast(Value->getValue())) {
4441 auto *CastValue = ArgValue->getCastTo(ArgType);
4442 if (CastValue) {
4443 assert((!isa(CastValue) ||
4444 cast(CastValue)->getType()->typeIsA(ArgType)) &&
4445 "result of template arg value cast has wrong type");
4446 Value = Value->cloneWithValue(CastValue);
4447 } else {
4448 HasError |= Error(
4449 Loc, "Value specified for template argument '" +
4451 ArgValue->getType()->getAsString() + "; expected type " +
4453 }
4454 }
4455 }
4456
4457 return HasError;
4458}
4459
4460#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4464 if (Rec)
4465 Rec->dump();
4466}
4467
4471
4472 for (const auto &E : Entries)
4474
4475 errs() << "}\n";
4476}
4477
4479 errs() << "Record:\n";
4481
4482 errs() << "Defs:\n";
4483 for (const auto &E : Entries)
4485}
4486#endif
4487
4488bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {
4489
4492 Lex.Lex();
4493
4494 const Init *Message = ParseValue(CurRec);
4495 if (!Message)
4496 return true;
4497
4498
4499
4500 if (isa(Message))
4502 ->Fold(CurRec);
4503
4505 return TokError("expected ';'");
4506
4507 if (CurRec)
4508 CurRec->addDump(Loc, Message);
4509 else {
4512
4514 addEntry(std::make_uniqueRecord::DumpInfo(Loc, ResolvedMessage));
4515 }
4516
4517 return false;
4518}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
uint64_t IntrinsicInst * II
PowerPC Reduce CR logical Operation
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static bool checkBitsConcrete(Record &R, const RecordVal &RV)
static const Init * QualifyName(const Record &CurRec, const Init *Name)
Return an Init with a qualifier prefix referring to CurRec's name.
static const Init * QualifiedNameOfImplicitName(const Record &Rec)
Return the qualified version of the implicit 'NAME' template argument.
static void checkConcrete(Record &R)
static SymbolRef::Type getType(const Symbol *Sym)
static const ArgumentInit * get(const Init *Value, ArgAuxType Aux)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
static const BinOpInit * get(BinaryOp opc, const Init *lhs, const Init *rhs, const RecTy *Type)
static const Init * getStrConcat(const Init *lhs, const Init *rhs)
static const Init * getListConcat(const TypedInit *lhs, const Init *rhs)
const Init * Fold(const Record *CurRec) const
static BitInit * get(RecordKeeper &RK, bool V)
static const BitRecTy * get(RecordKeeper &RK)
static BitsInit * get(RecordKeeper &RK, ArrayRef< const Init * > Range)
static const BitsRecTy * get(RecordKeeper &RK, unsigned Sz)
static const CondOpInit * get(ArrayRef< const Init * > C, ArrayRef< const Init * > V, const RecTy *Type)
const Init * Fold(const Record *CurRec) const
static const DagInit * get(const Init *V, const StringInit *VN, ArrayRef< const Init * > ArgRange, ArrayRef< const StringInit * > NameRange)
static const DagRecTy * get(RecordKeeper &RK)
AL - Represent a reference to a 'def' in the description.
Lightweight error class with error context and mandatory checking.
static const ExistsOpInit * get(const RecTy *CheckType, const Init *Expr)
const Init * Fold(const Record *CurRec) const
static const FieldInit * get(const Init *R, const StringInit *FN)
const Init * Fold(const Record *CurRec) const
static const FoldOpInit * get(const Init *Start, const Init *List, const Init *A, const Init *B, const Init *Expr, const RecTy *Type)
Do not resolve anything, but keep track of whether a given variable was referenced.
virtual const Init * resolveReferences(Resolver &R) const
This function is used by classes that refer to other variables which may not be defined at the time t...
virtual std::string getAsUnquotedString() const
Convert this value to a literal form, without adding quotes around a string.
virtual std::string getAsString() const =0
Convert this value to a literal form.
virtual const Init * getBit(unsigned Bit) const =0
Get the Init value of the specified bit.
virtual const Init * getCastTo(const RecTy *Ty) const =0
If this value is convertible to type Ty, return a value whose type is Ty, generating a !...
static IntInit * get(RecordKeeper &RK, int64_t V)
static const IntRecTy * get(RecordKeeper &RK)
static const IsAOpInit * get(const RecTy *CheckType, const Init *Expr)
const Init * Fold() const
[AL, AH, CL] - Represent a list of defs
static const ListInit * get(ArrayRef< const Init * > Range, const RecTy *EltTy)
'list' - Represent a list of element values, all of which must be of the specified type.
const RecTy * getElementType() const
static const ListRecTy * get(const RecTy *T)
bool typeIsConvertibleTo(const RecTy *RHS) const override
Return true if all values of 'this' type can be converted to the specified type.
Represents a single loop in the control flow graph.
Resolve arbitrary mappings.
This is a utility class that provides an abstraction for the common functionality between Instruction...
virtual bool typeIsConvertibleTo(const RecTy *RHS) const
Return true if all values of 'this' type can be converted to the specified type.
virtual std::string getAsString() const =0
const ListRecTy * getListTy() const
Returns the type representing list.
void addDef(std::unique_ptr< Record > R)
void addClass(std::unique_ptr< Record > R)
const Record * getClass(StringRef Name) const
Get the class with the specified name.
const Init * getNewAnonymousName()
GetNewAnonymousName - Generate a unique anonymous name that can be used as an identifier.
const Init * getGlobal(StringRef Name) const
Get the Init value of the specified global variable.
void addExtraGlobal(StringRef Name, const Init *I)
const Record * getDef(StringRef Name) const
Get the concrete record with the specified name.
static const RecordRecTy * get(RecordKeeper &RK, ArrayRef< const Record * > Classes)
Get the record type with the given non-redundant list of superclasses.
This class represents a field in a record, including its name, type, value, and source location.
std::string getNameInitAsString() const
Get the name of the field as a std::string.
void setUsed(bool Used)
Whether this value is used.
bool setValue(const Init *V)
Set the value of the field from an Init.
const Init * getValue() const
Get the value of the field as an Init.
StringRef getName() const
Get the name of the field as a StringRef.
void addReferenceLoc(SMRange Loc)
Add a reference to this record value.
const Init * getNameInit() const
Get the name of the field as an Init.
const RecTy * getType() const
Get the type of the field value as a RecTy.
const RecordRecTy * getType() const
ArrayRef< std::pair< const Record *, SMRange > > getSuperClasses() const
void addDump(SMLoc Loc, const Init *Message)
void checkUnusedTemplateArgs()
std::string getNameInitAsString() const
RecordKeeper & getRecords() const
const RecordVal * getValue(const Init *Name) const
void addTemplateArg(const Init *Name)
bool isMultiClass() const
void addValue(const RecordVal &RV)
void addAssertion(SMLoc Loc, const Init *Condition, const Init *Message)
bool isTemplateArg(const Init *Name) const
void appendDumps(const Record *Rec)
bool isSubClassOf(const Record *R) const
ArrayRef< RecordVal > getValues() const
SMLoc getFieldLoc(StringRef FieldName) const
Return the source location for the named field.
void resolveReferences(const Init *NewName=nullptr)
If there are any field references that refer to fields that have been filled in, we can propagate the...
ArrayRef< const Init * > getTemplateArgs() const
void updateClassLoc(SMLoc Loc)
void appendAssertions(const Record *Rec)
const Init * getNameInit() const
void addSuperClass(const Record *R, SMRange Range)
void setFinal(bool Final)
Represents a location in source code.
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
"foo" - Represent an initialization by a string value.
static const StringInit * get(RecordKeeper &RK, StringRef, StringFormat Fmt=SF_String)
StringRef getValue() const
static const StringRecTy * get(RecordKeeper &RK)
StringRef - Represent a constant reference to a string, i.e.
SMRange getLocRange() const
int64_t getCurIntVal() const
std::pair< int64_t, unsigned > getCurBinaryIntVal() const
const std::string & getCurStrVal() const
tgtok::TokKind getCode() const
void PopScope(TGVarScope *ExpectedStackTop)
bool TokError(const Twine &Msg) const
bool ParseFile()
ParseFile - Main entrypoint for parsing a tblgen file.
const Init * getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass, const StringInit *Name, SMRange NameLoc, bool TrackReferenceLocs) const
const Init * Fold(const Record *CurRec) const
static const TernOpInit * get(TernaryOp opc, const Init *lhs, const Init *mhs, const Init *rhs, const RecTy *Type)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
This is the common superclass of types that have a specific, explicit type, stored in ValueTy.
const RecTy * getType() const
Get the type of the Init as a RecTy.
static const UnOpInit * get(UnaryOp opc, const Init *lhs, const RecTy *Type)
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
static UnsetInit * get(RecordKeeper &RK)
Get the singleton unset Init.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
StringRef getName() const
Return a constant reference to the value's name.
static const VarDefInit * get(SMLoc Loc, const Record *Class, ArrayRef< const ArgumentInit * > Args)
const Init * Fold() const
'Opcode' - Represent a reference to an entire variable object.
static const VarInit * get(StringRef VN, const RecTy *T)
std::string getAsString() const override
Convert this value to a literal form.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ Resolved
Queried, materialization begun.
NodeAddr< DefNode * > Def
NodeAddr< CodeNode * > Code
static bool isBangOperator(tgtok::TokKind Kind)
isBangOperator - Return true if this is a bang operator.
static bool isObjectStart(tgtok::TokKind Kind)
isObjectStart - Return true if this is a valid first token for a statement.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
void PrintError(const Twine &Msg)
bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
void PrintNote(const Twine &Msg)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
void dumpMessage(SMLoc Loc, const Init *Message)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const RecTy * resolveTypes(const RecTy *T1, const RecTy *T2)
Find a common type that T1 and T2 convert to.
@ Default
The result values are uniform if and only if all operands are uniform.
ForeachLoop - Record the iteration state associated with a for loop.
std::vector< RecordsEntry > Entries
std::vector< RecordsEntry > Entries
RecordsEntry - Holds exactly one of a Record, ForeachLoop, or AssertionInfo.
std::unique_ptr< ForeachLoop > Loop
std::unique_ptr< Record::AssertionInfo > Assertion
std::unique_ptr< Record::DumpInfo > Dump
std::unique_ptr< Record > Rec
SubClassReference()=default
SmallVector< const ArgumentInit *, 4 > TemplateArgs
SubMultiClassReference()=default
SmallVector< const ArgumentInit *, 4 > TemplateArgs