LLVM: lib/TableGen/TGParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
18#include "llvm/Config/llvm-config.h"
23#include
24#include
25#include
26#include
27
28using namespace llvm;
29
30
31
32
33
41
42namespace llvm {
52
57
59
61 void dump() const;
62};
63}
64
65#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
67 errs() << "Multiclass:\n";
68
69 MC->dump();
70
71 errs() << "Template args:\n";
73 TA->dump();
74}
75#endif
76
79 for (unsigned i = 0, e = BV->getNumBits(); i != e; ++i) {
80 const Init *Bit = BV->getBit(i);
81 bool IsReference = false;
84 if (R.getValue(VI->getName()))
85 IsReference = true;
86 }
88 IsReference = true;
89 }
90 if (!(IsReference || Bit->isConcrete()))
91 return false;
92 }
93 return true;
94}
95
97 for (const RecordVal &RV : R.getValues()) {
98
99
100
101
102 if (RV.isNonconcreteOK())
103 continue;
104
105 if (const Init *V = RV.getValue()) {
107 if (!Ok) {
109 RV.getNameInitAsString() + "' in '" +
110 R.getNameInitAsString() +
111 "' could not be fully resolved: " +
112 RV.getValue()->getAsString());
113 }
114 }
115 }
116}
117
118
119
126
128 NewName = BinOp->Fold(&CurRec);
129 return NewName;
130}
131
135
136
140
144
148 bool TrackReferenceLocs) const {
149
150 auto It = Vars.find(Name->getValue());
151 if (It != Vars.end())
152 return It->second;
153
154 auto FindValueInArgs = [&](Record *Rec,
156 if (!Rec)
157 return nullptr;
161 assert(RV && "Template arg doesn't exist??");
163 if (TrackReferenceLocs)
166 }
167 return Name->getValue() == "NAME"
169 : nullptr;
170 };
171
172
173
174 switch (Kind) {
176 break;
178 if (CurRec) {
179
181 if (TrackReferenceLocs)
182 RV->addReferenceLoc(NameLoc);
184 }
185
186
187 if (CurRec->isClass())
188 if (auto *V = FindValueInArgs(CurRec, Name))
189 return V;
190 }
191 break;
192 }
194
195 if (CurLoop->IterVar) {
197 if (IterVar && IterVar->getNameInit() == Name)
198 return IterVar;
199 }
200 break;
201 }
203
204 if (CurMultiClass)
205 if (auto *V = FindValueInArgs(&CurMultiClass->Rec, Name))
206 return V;
207 break;
208 }
209 }
210
211
212 if (Parent)
213 return Parent->getVar(Records, ParsingMultiClass, Name, NameLoc,
214 TrackReferenceLocs);
215
216 return nullptr;
217}
218
220 if (!CurRec)
221 CurRec = &CurMultiClass->Rec;
222
224
225 if (ERV->setValue(RV.getValue()))
226 return Error(Loc, "New definition of '" + RV.getName() + "' of type '" +
228 "' is incompatible with " +
229 "previous definition of type '" +
230 ERV->getType()->getAsString() + "'");
231 } else {
233 }
234 return false;
235}
236
237
238
239bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const Init *ValName,
241 bool AllowSelfAssignment, bool OverrideDefLoc) {
242 if (!V)
243 return false;
244
245 if (!CurRec)
246 CurRec = &CurMultiClass->Rec;
247
248 RecordVal *RV = CurRec->getValue(ValName);
249 if (!RV)
250 return Error(Loc,
252
253
254
255 if (BitList.empty())
257 if (VI->getNameInit() == ValName && !AllowSelfAssignment)
258 return Error(Loc, "Recursion / self-assignment forbidden");
259
260
261
262 if (!BitList.empty()) {
264 if (!CurVal)
266 "' is not a bits type");
267
268
270 if (!BI)
271 return Error(Loc, "Initializer is not compatible with bit range");
272
274
275
276 for (unsigned i = 0, e = BitList.size(); i != e; ++i) {
277 unsigned Bit = BitList[i];
278 if (NewBits[Bit])
279 return Error(Loc, "Cannot set bit #" + Twine(Bit) + " of value '" +
281 "' more than once");
283 }
284
285 for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
286 if (!NewBits[i])
287 NewBits[i] = CurVal->getBit(i);
288
290 }
291
292 if (OverrideDefLoc ? RV->setValue(V, Loc) : RV->setValue(V)) {
293 std::string InitType;
295 InitType = (Twine("' of type bit initializer with length ") +
296 Twine(BI->getNumBits()))
297 .str();
299 InitType =
300 (Twine("' of type '") + TI->getType()->getAsString() + "'").str();
301
304 "' is incompatible with value '" + V->getAsString() +
305 InitType);
306 }
307 return false;
308}
309
310
311
313 const Record *SC = SubClass.Rec;
314 MapResolver R(CurRec);
315
316
317
319 if (.isTemplateArg())
321 return true;
322
323 if (resolveArgumentsOfClass(R, SC, SubClass.TemplateArgs,
325 return true;
326
327
329
330
332
333 const Init *Name;
337 else
340
342
343
344
347 "Already subclass of '" + SC->getName() + "'!\n");
349 return false;
350}
351
354 return AddSubClass(Entry.Rec.get(), SubClass);
355
356 if (Entry.Assertion)
357 return false;
358
359 for (auto &E : Entry.Loop->Entries) {
360 if (AddSubClass(E, SubClass))
361 return true;
362 }
363
364 return false;
365}
366
367
368
369
370bool TGParser::AddSubMultiClass(MultiClass *CurMC,
373
374 SubstStack Substs;
375 if (resolveArgumentsOfMultiClass(
380 return true;
381
382
383 return resolve(SMC->Entries, Substs, false, &CurMC->Entries);
384}
385
386
388 assert((!.Rec + !
.Loop + !
.Assertion + !
.Dump) == 1 &&
389 "RecordsEntry has invalid number of items");
390
391
392 if (!Loops.empty()) {
393 Loops.back()->Entries.push_back(std::move(E));
394 return false;
395 }
396
397
398 if (E.Loop) {
399 SubstStack Stack;
400 return resolve(*E.Loop, Stack, CurMultiClass == nullptr,
401 CurMultiClass ? &CurMultiClass->Entries : nullptr);
402 }
403
404
405 if (CurMultiClass) {
406 CurMultiClass->Entries.push_back(std::move(E));
407 return false;
408 }
409
410
411 if (E.Assertion) {
412 CheckAssert(E.Assertion->Loc, E.Assertion->Condition, E.Assertion->Message);
413 return false;
414 }
415
416 if (E.Dump) {
418 return false;
419 }
420
421
422 return addDefOne(std::move(E.Rec));
423}
424
425
426
427
428
429
430bool TGParser::resolve(const ForeachLoop &Loop, SubstStack &Substs, bool Final,
431 std::vector *Dest, SMLoc *Loc) {
432
433 MapResolver R;
434 for (const auto &S : Substs)
435 R.set(S.first, S.second);
437
438
439
440
441
442
443
446 const Init *OldLHS = TI->getLHS();
447 R.setFinal(true);
449 if (LHS == OldLHS) {
450 PrintError(Loop.Loc, Twine("unable to resolve if condition '") +
451 LHS->getAsString() +
452 "' at end of containing scope");
453 return true;
454 }
455 const Init *MHS = TI->getMHS();
456 const Init *RHS = TI->getRHS();
458 ->Fold(nullptr);
459 }
460
462 if (!LI) {
463 if (!Final) {
464 Dest->emplace_back(
465 std::make_unique(Loop.Loc, Loop.IterVar, List));
466 return resolve(Loop.Entries, Substs, Final, &Dest->back().Loop->Entries,
467 Loc);
468 }
469
470 PrintError(Loop.Loc, Twine("attempting to loop over '") +
471 List->getAsString() + "', expected a list");
472 return true;
473 }
474
475 bool Error = false;
476 for (auto *Elt : *LI) {
479 Error = resolve(Loop.Entries, Substs, Final, Dest);
481 Substs.pop_back();
483 break;
484 }
486}
487
488
489
490
491
492
493bool TGParser::resolve(const std::vector &Source,
494 SubstStack &Substs, bool Final,
495 std::vector *Dest, SMLoc *Loc) {
496 bool Error = false;
497 for (auto &E : Source) {
498 if (E.Loop) {
499 Error = resolve(*E.Loop, Substs, Final, Dest);
500
501 } else if (E.Assertion) {
502 MapResolver R;
503 for (const auto &S : Substs)
504 R.set(S.first, S.second);
505 const Init *Condition = E.Assertion->Condition->resolveReferences(R);
506 const Init *Message = E.Assertion->Message->resolveReferences(R);
507
508 if (Dest)
509 Dest->push_back(std::make_uniqueRecord::AssertionInfo(
510 E.Assertion->Loc, Condition, Message));
511 else
512 CheckAssert(E.Assertion->Loc, Condition, Message);
513
514 } else if (E.Dump) {
515 MapResolver R;
516 for (const auto &S : Substs)
517 R.set(S.first, S.second);
519
520 if (Dest)
521 Dest->push_back(
522 std::make_uniqueRecord::DumpInfo(E.Dump->Loc, Message));
523 else
525
526 } else {
527 auto Rec = std::make_unique(*E.Rec);
528 if (Loc)
529 Rec->appendLoc(*Loc);
530
531 MapResolver R(Rec.get());
532 for (const auto &S : Substs)
533 R.set(S.first, S.second);
534 Rec->resolveReferences(R);
535
536 if (Dest)
537 Dest->push_back(std::move(Rec));
538 else
539 Error = addDefOne(std::move(Rec));
540 }
542 break;
543 }
545}
546
547
548bool TGParser::addDefOne(std::unique_ptr Rec) {
549 const Init *NewName = nullptr;
550 if (const Record *Prev = Records.getDef(Rec->getNameInitAsString())) {
551 if (!Rec->isAnonymous()) {
553 "def already exists: " + Rec->getNameInitAsString());
554 PrintNote(Prev->getLoc(), "location of previous definition");
555 return true;
556 }
557 NewName = Records.getNewAnonymousName();
558 }
559
560 Rec->resolveReferences(NewName);
562
564 PrintError(Rec->getLoc(), Twine("record name '") +
565 Rec->getNameInit()->getAsString() +
566 "' could not be fully resolved");
567 return true;
568 }
569
570
571 Rec->checkRecordAssertions();
572
573
574 Rec->emitRecordDumps();
575
576
577 assert(Rec->getTemplateArgs().empty() && "How'd this get template args?");
578
579 for (DefsetRecord *Defset : Defsets) {
580 DefInit *I = Rec->getDefInit();
581 if (->getType()->typeIsA(Defset->EltTy)) {
582 PrintError(Rec->getLoc(), Twine("adding record of incompatible type '") +
583 I->getType()->getAsString() +
584 "' to defset");
585 PrintNote(Defset->Loc, "location of defset declaration");
586 return true;
587 }
588 Defset->Elements.push_back(I);
589 }
590
591 Records.addDef(std::move(Rec));
592 return false;
593}
594
595bool TGParser::resolveArguments(const Record *Rec,
597 SMLoc Loc, ArgValueHandler ArgValueHandler) {
600 "Too many template arguments allowed");
601
602
604 for (auto *Arg : ArgValues) {
605 const Init *ArgName = nullptr;
606 const Init *ArgValue = Arg->getValue();
607 if (Arg->isPositional())
608 ArgName = ArgNames[Arg->getIndex()];
609 if (Arg->isNamed())
610 ArgName = Arg->getName();
611
612
613 if ((UnsolvedArgNames, ArgName))
614 return Error(Loc, "We can only specify the template argument '" +
616
617 ArgValueHandler(ArgName, ArgValue);
619 }
620
621
622 for (auto *UnsolvedArgName : UnsolvedArgNames) {
624 if (->isComplete()) {
625 std::string Name = UnsolvedArgName->getAsUnquotedString();
626 Error(Loc, "value not specified for template argument '" + Name + "'");
629 return true;
630 }
631 ArgValueHandler(UnsolvedArgName, Default);
632 }
633
634 return false;
635}
636
637
638
639bool TGParser::resolveArgumentsOfClass(MapResolver &R, const Record *Rec,
642 return resolveArguments(
643 Rec, ArgValues, Loc,
644 [&](const Init *Name, const Init *Value) { R.set(Name, Value); });
645}
646
647
648
649bool TGParser::resolveArgumentsOfMultiClass(
652
654 return resolveArguments(&MC->Rec, ArgValues, Loc,
655 [&](const Init *Name, const Init *Value) {
656 Substs.emplace_back(Name, Value);
657 });
658}
659
660
661
662
663
665 if (Lex.getCode() == K) {
666 Lex.Lex();
667 return true;
668 }
669 return false;
670}
671
672
673
674
675
676
677
678const Init *TGParser::ParseObjectName(MultiClass *CurMultiClass) {
679 switch (Lex.getCode()) {
683
684
685
687 default:
688 break;
689 }
690
691 Record *CurRec = nullptr;
692 if (CurMultiClass)
693 CurRec = &CurMultiClass->Rec;
694
695 const Init *Name =
696 ParseValue(CurRec, StringRecTy::get(Records), ParseNameMode);
697 if (!Name)
698 return nullptr;
699
700 if (CurMultiClass) {
702 HasReferenceResolver R(NameStr);
703 Name->resolveReferences(R);
704 if (.found())
707 }
708
710}
711
712
713
714
715
716
717const Record *TGParser::ParseClassID() {
718 if (Lex.getCode() != tgtok::Id) {
719 TokError("expected name for ClassID");
720 return nullptr;
721 }
722
723 const Record *Result = Records.getClass(Lex.getCurStrVal());
724 if (!Result) {
725 std::string Msg("Couldn't find class '" + Lex.getCurStrVal() + "'");
726 if (MultiClasses[Lex.getCurStrVal()].get())
727 TokError(Msg + ". Use 'defm' if you meant to use multiclass '" +
728 Lex.getCurStrVal() + "'");
729 else
731 } else if (TrackReferenceLocs) {
732 Result->appendReferenceLoc(Lex.getLocRange());
733 }
734
735 Lex.Lex();
737}
738
739
740
741
742
743
744MultiClass *TGParser::ParseMultiClassID() {
745 if (Lex.getCode() != tgtok::Id) {
746 TokError("expected name for MultiClassID");
747 return nullptr;
748 }
749
751 if (!Result)
752 TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'");
753
754 Lex.Lex();
756}
757
758
759
760
761
762
763
765 bool isDefm) {
766 SubClassReference Result;
767 Result.RefRange.Start = Lex.getLoc();
768
769 if (isDefm) {
770 if (MultiClass *MC = ParseMultiClassID())
772 } else {
773 Result.Rec = ParseClassID();
774 }
777
778
780 Result.RefRange.End = Lex.getLoc();
782 }
783
785 if (ParseTemplateArgValueList(Result.TemplateArgs, ArgLocs, CurRec,
787 Result.Rec = nullptr;
789 }
790
791 if (CheckTemplateArgValues(Result.TemplateArgs, ArgLocs, Result.Rec)) {
792 Result.Rec = nullptr;
794 }
795
796 Result.RefRange.End = Lex.getLoc();
798}
799
800
801
802
803
804
805
806
808TGParser::ParseSubMultiClassReference(MultiClass *CurMC) {
809 SubMultiClassReference Result;
810 Result.RefRange.Start = Lex.getLoc();
811
812 Result.MC = ParseMultiClassID();
815
816
818 Result.RefRange.End = Lex.getLoc();
820 }
821
823 if (ParseTemplateArgValueList(Result.TemplateArgs, ArgLocs, &CurMC->Rec,
825 Result.MC = nullptr;
827 }
828
829 Result.RefRange.End = Lex.getLoc();
830
832}
833
834
835
836
837
838
839
840
841
842
843
844const TypedInit *TGParser::ParseSliceElement(Record *CurRec) {
845 auto LHSLoc = Lex.getLoc();
846 auto *CurVal = ParseValue(CurRec);
847 if (!CurVal)
848 return nullptr;
850
851 const TypedInit *RHS = nullptr;
852 switch (Lex.getCode()) {
855 Lex.Lex();
856 auto RHSLoc = Lex.getLoc();
857 CurVal = ParseValue(CurRec);
858 if (!CurVal)
859 return nullptr;
863 "expected int...int, got " + Twine(RHS->getType()->getAsString()));
864 return nullptr;
865 }
866 break;
867 }
869 auto i = -Lex.getCurIntVal();
870 if (i < 0) {
871 TokError("invalid range, cannot be negative");
872 return nullptr;
873 }
875 Lex.Lex();
876 break;
877 }
878 default:
879 return LHS;
880 }
881
884
885
888 "expected int...int, got " + Twine(LHS->getType()->getAsString()));
889 return nullptr;
890 }
891
894 ->Fold(CurRec));
895}
896
897
898
899
900
901
902
903
904
905
906
907
908const TypedInit *TGParser::ParseSliceElements(Record *CurRec, bool Single) {
909 const TypedInit *CurVal;
912
913 auto FlushElems = [&] {
914 if (!Elems.empty()) {
917 }
918 };
919
920 do {
921 auto LHSLoc = Lex.getLoc();
922 CurVal = ParseSliceElement(CurRec);
923 if (!CurVal)
924 return nullptr;
925 auto *CurValTy = CurVal->getType();
926
928 if ((ListValTy->getElementType())) {
930 "expected list, got " + Twine(ListValTy->getAsString()));
931 return nullptr;
932 }
933
934 FlushElems();
937 CurVal = nullptr;
940 "unhandled type " + Twine(CurValTy->getAsString()) + " in range");
941 return nullptr;
942 }
943
945 break;
946
947 Lex.Lex();
948
949
951 if (CurVal)
953 CurVal = nullptr;
955
956 if (CurVal) {
957
958 if (Single)
959 return CurVal;
960
962 }
963
964 FlushElems();
965
966
967 const TypedInit *Result = nullptr;
968 for (auto *Slice : Slices) {
970 : Slice);
971 }
972
974}
975
976
977
978
979
980
981
984 const Init *CurVal = FirstItem;
985 if (!CurVal)
986 CurVal = ParseValue(nullptr);
987
989 if ()
990 return TokError("expected integer or bitrange");
991
992 int64_t Start = II->getValue();
993 int64_t End;
994
995 if (Start < 0)
996 return TokError("invalid range, cannot be negative");
997
998 switch (Lex.getCode()) {
999 default:
1000 Ranges.push_back(Start);
1001 return false;
1002
1005 Lex.Lex();
1006
1007 const Init *I_End = ParseValue(nullptr);
1009 if (!II_End) {
1010 TokError("expected integer value as end of range");
1011 return true;
1012 }
1013
1014 End = II_End->getValue();
1015 break;
1016 }
1018 End = -Lex.getCurIntVal();
1019 Lex.Lex();
1020 break;
1021 }
1022 }
1023 if (End < 0)
1024 return TokError("invalid range, cannot be negative");
1025
1026
1027 if (Start < End)
1029 Ranges.push_back(Start);
1030 else
1032 Ranges.push_back(Start);
1033 return false;
1034}
1035
1036
1037
1038
1039
1041
1042 if (ParseRangePiece(Result)) {
1044 return;
1045 }
1047
1048 if (ParseRangePiece(Result)) {
1050 return;
1051 }
1052}
1053
1054
1055
1056
1058 SMLoc StartLoc = Lex.getLoc();
1060 return false;
1061
1062
1063 ParseRangeList(Ranges);
1065 return true;
1066
1068 TokError("expected '>' at end of range list");
1069 return Error(StartLoc, "to match this '<'");
1070 }
1071 return false;
1072}
1073
1074
1075
1076
1078 SMLoc StartLoc = Lex.getLoc();
1080 return false;
1081
1082
1083 ParseRangeList(Ranges);
1085 return true;
1086
1088 TokError("expected '}' at end of bit list");
1089 return Error(StartLoc, "to match this '{'");
1090 }
1091 return false;
1092}
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105const RecTy *TGParser::ParseType() {
1106 switch (Lex.getCode()) {
1107 default:
1108 TokError("Unknown token when expecting a type");
1109 return nullptr;
1112 Lex.Lex();
1115 Lex.Lex();
1118 Lex.Lex();
1121 Lex.Lex();
1124 auto I = TypeAliases.find(Lex.getCurStrVal());
1125 if (I != TypeAliases.end()) {
1126 Lex.Lex();
1127 return I->second;
1128 }
1129 if (const Record *R = ParseClassID())
1131 TokError("unknown class name");
1132 return nullptr;
1133 }
1135 if (Lex.Lex() != tgtok::less) {
1136 TokError("expected '<' after bits type");
1137 return nullptr;
1138 }
1140 TokError("expected integer in bits type");
1141 return nullptr;
1142 }
1143 uint64_t Val = Lex.getCurIntVal();
1145 TokError("expected '>' at end of bits type");
1146 return nullptr;
1147 }
1148 Lex.Lex();
1150 }
1152 if (Lex.Lex() != tgtok::less) {
1153 TokError("expected '<' after list type");
1154 return nullptr;
1155 }
1156 Lex.Lex();
1157 const RecTy *SubType = ParseType();
1158 if (!SubType)
1159 return nullptr;
1160
1162 TokError("expected '>' at end of list type");
1163 return nullptr;
1164 }
1166 }
1167 }
1168}
1169
1170
1173 if (const Init *I = CurScope->getVar(Records, CurMultiClass, Name, NameLoc,
1174 TrackReferenceLocs))
1175 return I;
1176
1177 if (Mode == ParseNameMode)
1178 return Name;
1179
1180 if (const Init *I = Records.getGlobal(Name->getValue())) {
1181
1182 if (TrackReferenceLocs) {
1184 Def->getDef()->appendReferenceLoc(NameLoc);
1185 }
1186 return I;
1187 }
1188
1189
1190
1191 if (CurRec && !CurRec->isClass() && !CurMultiClass &&
1194
1195 Error(NameLoc.Start, "Variable not defined: '" + Name->getValue() + "'");
1196 return nullptr;
1197}
1198
1199
1200
1201
1202
1203const Init *TGParser::ParseOperation(Record *CurRec, const RecTy *ItemType) {
1204 switch (Lex.getCode()) {
1205 default:
1206 TokError("unknown bang operator");
1207 return nullptr;
1223 const RecTy *Type = nullptr;
1224
1225 switch (Lex.getCode()) {
1226 default:
1229 Lex.Lex();
1231
1232 Type = ParseOperatorType();
1233
1234 if () {
1235 TokError("did not get type for unary operator");
1236 return nullptr;
1237 }
1238
1239 break;
1241 Lex.Lex();
1244 break;
1246 Lex.Lex();
1249 break;
1251 Lex.Lex();
1254 break;
1256 Lex.Lex();
1259 break;
1261 Lex.Lex();
1264 break;
1266 Lex.Lex();
1269 break;
1271 Lex.Lex();
1273 break;
1275 Lex.Lex();
1277 break;
1279 Lex.Lex();
1282 break;
1284 Lex.Lex();
1287 break;
1289 Lex.Lex();
1291
1292
1293
1294 Type = ParseOperatorType();
1295
1296 if () {
1297 TokError("did not get type for unary operator");
1298 return nullptr;
1299 }
1300
1302 TokError("type for !getdagop must be a record type");
1303
1304 }
1305 } else {
1307 }
1309 break;
1311 Lex.Lex();
1314 break;
1316 Lex.Lex();
1319 break;
1320 }
1322 TokError("expected '(' after unary operator");
1323 return nullptr;
1324 }
1325
1326 const Init *LHS = ParseValue(CurRec);
1327 if ()
1328 return nullptr;
1329
1335 if (!LHSl && !LHSs && !LHSd && !LHSt) {
1337 "expected string, list, or dag type argument in unary operator");
1338 return nullptr;
1339 }
1340 if (LHSt) {
1343 "expected string, list, or dag type argument in unary operator");
1344 return nullptr;
1345 }
1346 }
1347 }
1348
1353 if (!LHSl && !LHSt) {
1354 TokError("expected list type argument in unary operator");
1355 return nullptr;
1356 }
1357 if (LHSt) {
1359 TokError("expected list type argument in unary operator");
1360 return nullptr;
1361 }
1362 }
1363
1364 if (LHSl && LHSl->empty()) {
1365 TokError("empty list argument in unary operator");
1366 return nullptr;
1367 }
1368 bool UseElementType =
1370 if (LHSl) {
1371 const Init *Item = LHSl->getElement(0);
1373 if (!Itemt) {
1374 TokError("untyped list element in unary operator");
1375 return nullptr;
1376 }
1377 Type = UseElementType ? Itemt->getType()
1379 } else {
1380 assert(LHSt && "expected list type argument in unary operator");
1382 Type = UseElementType ? LType->getElementType() : LType;
1383 }
1384
1385
1386
1389 if (InnerListTy) {
1390
1392 } else {
1393
1395 }
1396 }
1397 }
1398
1400 TokError("expected ')' in unary operator");
1401 return nullptr;
1402 }
1404 }
1405
1407
1408 Lex.Lex();
1409
1410 const RecTy *Type = ParseOperatorType();
1412 return nullptr;
1413
1415 TokError("expected '(' after type of !isa");
1416 return nullptr;
1417 }
1418
1419 const Init *LHS = ParseValue(CurRec);
1420 if ()
1421 return nullptr;
1422
1424 TokError("expected ')' in !isa");
1425 return nullptr;
1426 }
1427
1429 }
1430
1432
1433 Lex.Lex();
1434
1435 const RecTy *Type = ParseOperatorType();
1437 return nullptr;
1438
1440 TokError("expected '(' after type of !exists");
1441 return nullptr;
1442 }
1443
1444 SMLoc ExprLoc = Lex.getLoc();
1445 const Init *Expr = ParseValue(CurRec);
1446 if (!Expr)
1447 return nullptr;
1448
1450 if (!ExprType) {
1451 Error(ExprLoc, "expected string type argument in !exists operator");
1452 return nullptr;
1453 }
1454
1456 if (RecType) {
1458 "expected string type argument in !exists operator, please "
1459 "use !isa instead");
1460 return nullptr;
1461 }
1462
1464 if (!SType) {
1465 Error(ExprLoc, "expected string type argument in !exists operator");
1466 return nullptr;
1467 }
1468
1470 TokError("expected ')' in !exists");
1471 return nullptr;
1472 }
1473
1475 }
1476
1478
1479 Lex.Lex();
1480
1481 const RecTy *Type = ParseOperatorType();
1483 return nullptr;
1484
1486 TokError("expected '(' after type of !instances");
1487 return nullptr;
1488 }
1489
1490
1491 const Init *Regex;
1493 SMLoc RegexLoc = Lex.getLoc();
1494 Regex = ParseValue(CurRec);
1495
1497 if (!RegexType) {
1498 Error(RegexLoc, "expected string type argument in !instances operator");
1499 return nullptr;
1500 }
1501
1503 if (!SType) {
1504 Error(RegexLoc, "expected string type argument in !instances operator");
1505 return nullptr;
1506 }
1507 } else {
1508
1510 }
1511
1513 TokError("expected ')' in !instances");
1514 return nullptr;
1515 }
1516
1518 }
1519
1548 SMLoc OpLoc = Lex.getLoc();
1549 Lex.Lex();
1550
1552 switch (OpTok) {
1553 default:
1557 break;
1560 break;
1563 break;
1566 break;
1569 break;
1572 break;
1575 break;
1578 break;
1581 break;
1584 break;
1587 break;
1590 break;
1593 break;
1596 break;
1599 break;
1602 break;
1605 break;
1608 break;
1611 break;
1614 break;
1617 break;
1620 break;
1623 break;
1626 break;
1629 break;
1632 break;
1635 break;
1636 }
1637
1638 const RecTy *Type = nullptr;
1639 const RecTy *ArgType = nullptr;
1640 switch (OpTok) {
1641 default:
1646 break;
1651 break;
1653 Type = ParseOperatorType();
1654 if () {
1655 TokError("did not get type for !getdagarg operator");
1656 return nullptr;
1657 }
1659 break;
1663 break;
1667 break;
1680 break;
1688
1689 break;
1691
1692 ArgType = ItemType;
1693 break;
1695
1696 break;
1698
1699 ArgType = ItemType;
1700 break;
1704 break;
1707
1708 }
1709
1710 if (Type && ItemType && ->typeIsConvertibleTo(ItemType)) {
1711 Error(OpLoc, Twine("expected value of type '") + ItemType->getAsString() +
1712 "', got '" + Type->getAsString() + "'");
1713 return nullptr;
1714 }
1715
1717 TokError("expected '(' after binary operator");
1718 return nullptr;
1719 }
1720
1722
1723
1724
1725 for (;;) {
1726 SMLoc InitLoc = Lex.getLoc();
1727 InitList.push_back(ParseValue(CurRec, ArgType));
1728 if (!InitList.back())
1729 return nullptr;
1730
1732 if (!InitListBack) {
1733 Error(OpLoc, Twine("expected value to be a typed value, got '" +
1734 InitList.back()->getAsString() + "'"));
1735 return nullptr;
1736 }
1737 const RecTy *ListType = InitListBack->getType();
1738
1739 if (!ArgType) {
1740
1741 ArgType = ListType;
1742
1743 switch (Code) {
1746 Error(InitLoc, Twine("expected a list, got value of type '") +
1748 return nullptr;
1749 }
1750 break;
1752 if (ItemType && InitList.size() == 1) {
1755 Twine("expected output type to be a list, got type '") +
1757 return nullptr;
1758 }
1760 Error(OpLoc, Twine("expected first arg type to be '") +
1762 "', got value of type '" +
1764 ->getElementType()
1765 ->getAsString() +
1766 "'");
1767 return nullptr;
1768 }
1769 }
1771 Error(InitLoc, Twine("expected second parameter to be an int, got "
1772 "value of type '") +
1774 return nullptr;
1775 }
1776 ArgType = nullptr;
1777 break;
1780 Error(InitLoc, Twine("expected a list, got value of type '") +
1782 return nullptr;
1783 }
1784 break;
1790 Error(InitLoc, Twine("expected bit, bits, int, string, or record; "
1791 "got value of type '") +
1793 return nullptr;
1794 }
1795 break;
1797
1804 Error(InitLoc, Twine("expected bit, bits, int, or string; "
1805 "got value of type '") +
1807 return nullptr;
1808 }
1809 break;
1811 switch (InitList.size()) {
1812 case 1:
1817 Twine("expected list of string, int, bits, or bit; "
1818 "got value of type '") +
1820 return nullptr;
1821 }
1822 break;
1823 case 2:
1825 Error(InitLoc, Twine("expected second argument to be a string, "
1826 "got value of type '") +
1828 return nullptr;
1829 }
1830 break;
1831 default:;
1832 }
1833 ArgType = nullptr;
1834 break;
1835 default:
1837 }
1838
1839 } else {
1840
1842 if (!Resolved) {
1843 Error(InitLoc, Twine("expected value of type '") +
1846 return nullptr;
1847 }
1854 }
1855
1856
1857
1858 switch (Code) {
1860
1862 break;
1864
1865
1867 break;
1869
1870
1871 ArgType = nullptr;
1872 break;
1874
1876 break;
1877 default:
1878 break;
1879 }
1880
1882 break;
1883 }
1884
1886 TokError("expected ')' in operator");
1887 return nullptr;
1888 }
1889
1890
1892 Type = ArgType;
1893
1896
1898 Type = ArgType;
1899
1900
1901
1906 while (InitList.size() > 2) {
1910 }
1911 }
1912
1913 if (InitList.size() == 2)
1915 ->Fold(CurRec);
1916
1917 Error(OpLoc, "expected two operands to operator");
1918 return nullptr;
1919 }
1920
1923 return ParseOperationForEachFilter(CurRec, ItemType);
1924 }
1925
1927 SMLoc OpLoc = Lex.getLoc();
1928 Lex.Lex();
1929
1931 TokError("expected '(' after !range operator");
1932 return nullptr;
1933 }
1934
1936 bool FirstArgIsList = false;
1937 for (;;) {
1938 if (Args.size() >= 3) {
1939 TokError("expected at most three values of integer");
1940 return nullptr;
1941 }
1942
1943 SMLoc InitLoc = Lex.getLoc();
1944 Args.push_back(ParseValue(CurRec));
1945 if (.back())
1946 return nullptr;
1947
1949 if (!ArgBack) {
1950 Error(OpLoc, Twine("expected value to be a typed value, got '" +
1951 Args.back()->getAsString() + "'"));
1952 return nullptr;
1953 }
1954
1955 const RecTy *ArgBackType = ArgBack->getType();
1956 if (!FirstArgIsList || Args.size() == 1) {
1958 FirstArgIsList = true;
1960
1961 } else {
1962 if (Args.size() != 1)
1963 Error(InitLoc, Twine("expected value of type 'int', got '" +
1965 else
1966 Error(InitLoc, Twine("expected list or int, got value of type '") +
1968 return nullptr;
1969 }
1970 } else {
1971
1973 Error(InitLoc, Twine("expected one list, got extra value of type '") +
1975 return nullptr;
1976 }
1978 break;
1979 }
1980
1982 TokError("expected ')' in operator");
1983 return nullptr;
1984 }
1985
1986 const Init *LHS, *MHS, *RHS;
1987 auto ArgCount = Args.size();
1988 assert(ArgCount >= 1);
1990 const auto *Arg0Ty = Arg0->getType();
1991 if (ArgCount == 1) {
1993
1996 ->Fold(CurRec);
1998 } else {
2000
2002 MHS = Arg0;
2004 }
2005 } else {
2009 LHS = Arg0;
2010 MHS = Arg1;
2011 if (ArgCount == 3) {
2012
2015 RHS = Arg2;
2016 } else {
2017
2019 }
2020 }
2023 ->Fold(CurRec);
2024 }
2025
2030 case tgtok::XSubst: {
2032 const RecTy *Type = nullptr;
2033
2035 Lex.Lex();
2036 switch (LexCode) {
2037 default:
2042 ItemType = nullptr;
2043 break;
2046 break;
2049 break;
2053 ItemType = nullptr;
2054 break;
2058 ItemType = nullptr;
2059 break;
2060 }
2062 TokError("expected '(' after ternary operator");
2063 return nullptr;
2064 }
2065
2066 const Init *LHS = ParseValue(CurRec);
2067 if ()
2068 return nullptr;
2069
2071 TokError("expected ',' in ternary operator");
2072 return nullptr;
2073 }
2074
2075 SMLoc MHSLoc = Lex.getLoc();
2076 const Init *MHS = ParseValue(CurRec, ItemType);
2077 if (!MHS)
2078 return nullptr;
2079
2081 TokError("expected ',' in ternary operator");
2082 return nullptr;
2083 }
2084
2085 SMLoc RHSLoc = Lex.getLoc();
2086 const Init *RHS = ParseValue(CurRec, ItemType);
2087 if ()
2088 return nullptr;
2089
2091 TokError("expected ')' in binary operator");
2092 return nullptr;
2093 }
2094
2095 switch (LexCode) {
2096 default:
2101 Error(MHSLoc, "could not determine type of the child list in !dag");
2102 return nullptr;
2103 }
2105 Error(MHSLoc, Twine("expected list of children, got type '") +
2106 MHSt->getType()->getAsString() + "'");
2107 return nullptr;
2108 }
2109
2112 Error(RHSLoc, "could not determine type of the name list in !dag");
2113 return nullptr;
2114 }
2115 if (RHSt && StringRecTy::get(Records)->getListTy() != RHSt->getType()) {
2116 Error(RHSLoc, Twine("expected list, got type '") +
2117 RHSt->getType()->getAsString() + "'");
2118 return nullptr;
2119 }
2120
2121 if (!MHSt && !RHSt) {
2123 "cannot have both unset children and unset names in !dag");
2124 return nullptr;
2125 }
2126 break;
2127 }
2129 const RecTy *MHSTy = nullptr;
2130 const RecTy *RHSTy = nullptr;
2131
2133 MHSTy = MHSt->getType();
2135 MHSTy = BitsRecTy::get(Records, MHSbits->getNumBits());
2138
2140 RHSTy = RHSt->getType();
2142 RHSTy = BitsRecTy::get(Records, RHSbits->getNumBits());
2145
2146
2148 MHSTy = RHSTy;
2150 RHSTy = MHSTy;
2151
2152 if (!MHSTy || !RHSTy) {
2153 TokError("could not get type for !if");
2154 return nullptr;
2155 }
2156
2158 if () {
2160 "' and '" + RHSTy->getAsString() + "' for !if");
2161 return nullptr;
2162 }
2163 break;
2164 }
2167 if (!RHSt) {
2168 TokError("could not get type for !subst");
2169 return nullptr;
2170 }
2171 Type = RHSt->getType();
2172 break;
2173 }
2177 Error(MHSLoc, Twine("expected integer index or string name, got ") +
2178 (MHSt ? ("type '" + MHSt->getType()->getAsString())
2180 "'");
2181 return nullptr;
2182 }
2183 break;
2184 }
2188 Error(MHSLoc, Twine("expected integer index or string name, got ") +
2189 (MHSt ? ("type '" + MHSt->getType()->getAsString())
2191 "'");
2192 return nullptr;
2193 }
2195
2197 Error(RHSLoc, Twine("expected string or unset name, got type '") +
2198 RHSt->getType()->getAsString() + "'");
2199 return nullptr;
2200 }
2201 break;
2202 }
2203 }
2205 }
2206
2208 return ParseOperationSubstr(CurRec, ItemType);
2209
2211 return ParseOperationFind(CurRec, ItemType);
2212
2214 return ParseOperationCond(CurRec, ItemType);
2215
2217
2218 Lex.Lex();
2220 TokError("expected '(' after !foldl");
2221 return nullptr;
2222 }
2223
2224 const Init *StartUntyped = ParseValue(CurRec);
2225 if (!StartUntyped)
2226 return nullptr;
2227
2229 if (!Start) {
2230 TokError(Twine("could not get type of !foldl start: '") +
2232 return nullptr;
2233 }
2234
2236 TokError("expected ',' in !foldl");
2237 return nullptr;
2238 }
2239
2240 const Init *ListUntyped = ParseValue(CurRec);
2241 if (!ListUntyped)
2242 return nullptr;
2243
2245 if () {
2246 TokError(Twine("could not get type of !foldl list: '") +
2248 return nullptr;
2249 }
2250
2252 if (!ListType) {
2253 TokError(Twine("!foldl list must be a list, but is of type '") +
2254 List->getType()->getAsString());
2255 return nullptr;
2256 }
2257
2259 TokError("expected ',' in !foldl");
2260 return nullptr;
2261 }
2262
2263 if (Lex.Lex() != tgtok::Id) {
2264 TokError("third argument of !foldl must be an identifier");
2265 return nullptr;
2266 }
2267
2268 const Init *A = StringInit::get(Records, Lex.getCurStrVal());
2269 if (CurRec && CurRec->getValue(A)) {
2270 TokError((Twine("left !foldl variable '") + A->getAsString() +
2271 "' already defined")
2272 .str());
2273 return nullptr;
2274 }
2275
2276 if (Lex.Lex() != tgtok::comma) {
2277 TokError("expected ',' in !foldl");
2278 return nullptr;
2279 }
2280
2281 if (Lex.Lex() != tgtok::Id) {
2282 TokError("fourth argument of !foldl must be an identifier");
2283 return nullptr;
2284 }
2285
2286 const Init *B = StringInit::get(Records, Lex.getCurStrVal());
2287 if (CurRec && CurRec->getValue(B)) {
2288 TokError((Twine("right !foldl variable '") + B->getAsString() +
2289 "' already defined")
2290 .str());
2291 return nullptr;
2292 }
2293
2294 if (Lex.Lex() != tgtok::comma) {
2295 TokError("expected ',' in !foldl");
2296 return nullptr;
2297 }
2298 Lex.Lex();
2299
2300
2301
2302 std::unique_ptr ParseRecTmp;
2303 Record *ParseRec = CurRec;
2304 if (!ParseRec) {
2305 ParseRecTmp =
2306 std::make_unique(".parse", ArrayRef{}, Records);
2307 ParseRec = ParseRecTmp.get();
2308 }
2309
2310 TGVarScope *FoldScope = PushScope(ParseRec);
2312 ParseRec->addValue(
2314 const Init *ExprUntyped = ParseValue(ParseRec);
2315 ParseRec->removeValue(A);
2316 ParseRec->removeValue(B);
2318 if (!ExprUntyped)
2319 return nullptr;
2320
2322 if (!Expr) {
2323 TokError("could not get type of !foldl expression");
2324 return nullptr;
2325 }
2326
2327 if (Expr->getType() != Start->getType()) {
2328 TokError(Twine("!foldl expression must be of same type as start (") +
2329 Start->getType()->getAsString() + "), but is of type " +
2331 return nullptr;
2332 }
2333
2335 TokError("expected ')' in fold operator");
2336 return nullptr;
2337 }
2338
2340 ->Fold(CurRec);
2341 }
2342 }
2343}
2344
2345
2346
2347
2348
2349
2350const RecTy *TGParser::ParseOperatorType() {
2351 const RecTy *Type = nullptr;
2352
2354 TokError("expected type name for operator");
2355 return nullptr;
2356 }
2357
2359 TokError("the 'code' type is not allowed in bang operators; use 'string'");
2360
2361 Type = ParseType();
2362
2363 if () {
2364 TokError("expected type name for operator");
2365 return nullptr;
2366 }
2367
2369 TokError("expected type name for operator");
2370 return nullptr;
2371 }
2372
2373 return Type;
2374}
2375
2376
2377
2378
2379const Init *TGParser::ParseOperationSubstr(Record *CurRec,
2380 const RecTy *ItemType) {
2383
2384 Lex.Lex();
2385
2387 TokError("expected '(' after !substr operator");
2388 return nullptr;
2389 }
2390
2391 const Init *LHS = ParseValue(CurRec);
2392 if ()
2393 return nullptr;
2394
2396 TokError("expected ',' in !substr 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;
2408 RHSLoc = Lex.getLoc();
2409 RHS = ParseValue(CurRec);
2410 if ()
2411 return nullptr;
2412 } else {
2413 RHS = IntInit::get(Records, std::numeric_limits<int64_t>::max());
2414 }
2415
2417 TokError("expected ')' in !substr operator");
2418 return nullptr;
2419 }
2420
2421 if (ItemType && ->typeIsConvertibleTo(ItemType)) {
2422 Error(RHSLoc, Twine("expected value of type '") + ItemType->getAsString() +
2423 "', got '" + Type->getAsString() + "'");
2424 }
2425
2428 TokError("could not determine type of the string in !substr");
2429 return nullptr;
2430 }
2432 TokError(Twine("expected string, got type '") +
2433 LHSt->getType()->getAsString() + "'");
2434 return nullptr;
2435 }
2436
2439 TokError("could not determine type of the start position in !substr");
2440 return nullptr;
2441 }
2443 Error(MHSLoc, Twine("expected int, got type '") +
2444 MHSt->getType()->getAsString() + "'");
2445 return nullptr;
2446 }
2447
2448 if (RHS) {
2451 TokError("could not determine type of the length in !substr");
2452 return nullptr;
2453 }
2455 TokError(Twine("expected int, got type '") +
2456 RHSt->getType()->getAsString() + "'");
2457 return nullptr;
2458 }
2459 }
2460
2462}
2463
2464
2465
2466
2467const Init *TGParser::ParseOperationFind(Record *CurRec,
2468 const RecTy *ItemType) {
2471
2472 Lex.Lex();
2473
2475 TokError("expected '(' after !find operator");
2476 return nullptr;
2477 }
2478
2479 const Init *LHS = ParseValue(CurRec);
2480 if ()
2481 return nullptr;
2482
2484 TokError("expected ',' in !find operator");
2485 return nullptr;
2486 }
2487
2488 SMLoc MHSLoc = Lex.getLoc();
2489 const Init *MHS = ParseValue(CurRec);
2490 if (!MHS)
2491 return nullptr;
2492
2493 SMLoc RHSLoc = Lex.getLoc();
2494 const Init *RHS;
2496 RHSLoc = Lex.getLoc();
2497 RHS = ParseValue(CurRec);
2498 if ()
2499 return nullptr;
2500 } else {
2502 }
2503
2505 TokError("expected ')' in !find operator");
2506 return nullptr;
2507 }
2508
2509 if (ItemType && ->typeIsConvertibleTo(ItemType)) {
2510 Error(RHSLoc, Twine("expected value of type '") + ItemType->getAsString() +
2511 "', got '" + Type->getAsString() + "'");
2512 }
2513
2516 TokError("could not determine type of the source string in !find");
2517 return nullptr;
2518 }
2520 TokError(Twine("expected string, got type '") +
2521 LHSt->getType()->getAsString() + "'");
2522 return nullptr;
2523 }
2524
2527 TokError("could not determine type of the target string in !find");
2528 return nullptr;
2529 }
2531 Error(MHSLoc, Twine("expected string, got type '") +
2532 MHSt->getType()->getAsString() + "'");
2533 return nullptr;
2534 }
2535
2536 if (RHS) {
2539 TokError("could not determine type of the start position in !find");
2540 return nullptr;
2541 }
2543 TokError(Twine("expected int, got type '") +
2544 RHSt->getType()->getAsString() + "'");
2545 return nullptr;
2546 }
2547 }
2548
2550}
2551
2552
2553
2554
2555
2556const Init *TGParser::ParseOperationForEachFilter(Record *CurRec,
2557 const RecTy *ItemType) {
2558 SMLoc OpLoc = Lex.getLoc();
2560 Lex.Lex();
2562 TokError("expected '(' after !foreach/!filter");
2563 return nullptr;
2564 }
2565
2566 if (Lex.Lex() != tgtok::Id) {
2567 TokError("first argument of !foreach/!filter must be an identifier");
2568 return nullptr;
2569 }
2570
2572 Lex.Lex();
2573
2575 TokError((Twine("iteration variable '") + LHS->getAsString() +
2576 "' is already defined")
2577 .str());
2578 return nullptr;
2579 }
2580
2582 TokError("expected ',' in !foreach/!filter");
2583 return nullptr;
2584 }
2585
2586 const Init *MHS = ParseValue(CurRec);
2587 if (!MHS)
2588 return nullptr;
2589
2591 TokError("expected ',' in !foreach/!filter");
2592 return nullptr;
2593 }
2594
2596 if (!MHSt) {
2597 TokError("could not get type of !foreach/!filter list or dag");
2598 return nullptr;
2599 }
2600
2601 const RecTy *InEltType = nullptr;
2602 const RecTy *ExprEltType = nullptr;
2603 bool IsDAG = false;
2604
2606 InEltType = InListTy->getElementType();
2607 if (ItemType) {
2610 ? OutListTy->getElementType()
2612 } else {
2613 Error(OpLoc, "expected value of type '" +
2615 "', but got list type");
2616 return nullptr;
2617 }
2618 }
2619 } else if (const auto *InDagTy = dyn_cast(MHSt->getType())) {
2621 TokError("!filter must have a list argument");
2622 return nullptr;
2623 }
2624 InEltType = InDagTy;
2626 Error(OpLoc, "expected value of type '" + Twine(ItemType->getAsString()) +
2627 "', but got dag type");
2628 return nullptr;
2629 }
2630 IsDAG = true;
2631 } else {
2633 TokError("!foreach must have a list or dag argument");
2634 else
2635 TokError("!filter must have a list argument");
2636 return nullptr;
2637 }
2638
2639
2640
2641 std::unique_ptr ParseRecTmp;
2642 Record *ParseRec = CurRec;
2643 if (!ParseRec) {
2644 ParseRecTmp =
2645 std::make_unique(".parse", ArrayRef{}, Records);
2646 ParseRec = ParseRecTmp.get();
2647 }
2648 TGVarScope *TempScope = PushScope(ParseRec);
2650 const Init *RHS = ParseValue(ParseRec, ExprEltType);
2651 ParseRec->removeValue(LHS);
2653 if ()
2654 return nullptr;
2655
2657 TokError("expected ')' in !foreach/!filter");
2658 return nullptr;
2659 }
2660
2661 const RecTy *OutType = InEltType;
2664 if (!RHSt) {
2665 TokError("could not get type of !foreach result expression");
2666 return nullptr;
2667 }
2668 OutType = RHSt->getType()->getListTy();
2670 OutType = InEltType->getListTy();
2671 }
2672
2676 ->Fold(CurRec);
2677}
2678
2679const Init *TGParser::ParseOperationCond(Record *CurRec,
2680 const RecTy *ItemType) {
2681 Lex.Lex();
2682
2684 TokError("expected '(' after !cond operator");
2685 return nullptr;
2686 }
2687
2688
2691 while (true) {
2693 break;
2694
2695 const Init *V = ParseValue(CurRec);
2696 if (!V)
2697 return nullptr;
2699
2701 TokError("expected ':' following a condition in !cond operator");
2702 return nullptr;
2703 }
2704
2705 V = ParseValue(CurRec, ItemType);
2706 if (!V)
2707 return nullptr;
2709
2711 break;
2712
2714 TokError("expected ',' or ')' following a value in !cond operator");
2715 return nullptr;
2716 }
2717 }
2718
2719 if (Case.size() < 1) {
2721 "there should be at least 1 'condition : value' in the !cond operator");
2722 return nullptr;
2723 }
2724
2725
2726 const RecTy *Type = nullptr;
2727 for (const Init *V : Val) {
2728 const RecTy *VTy = nullptr;
2730 VTy = Vt->getType();
2735
2736 if (Type == nullptr) {
2739 } else {
2742 if (!RType) {
2743 TokError(Twine("inconsistent types '") + Type->getAsString() +
2744 "' and '" + VTy->getAsString() + "' for !cond");
2745 return nullptr;
2746 }
2747 Type = RType;
2748 }
2749 }
2750 }
2751
2752 if () {
2753 TokError("could not determine type for !cond from its arguments");
2754 return nullptr;
2755 }
2757}
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786const Init *TGParser::ParseSimpleValue(Record *CurRec, const RecTy *ItemType,
2787 IDParseMode Mode) {
2788 const Init *R = nullptr;
2790
2791
2793 return ParseOperation(CurRec, ItemType);
2794
2795 switch (Code) {
2796 default:
2797 TokError("Unknown or reserved token when parsing a value");
2798 break;
2799
2802 Lex.Lex();
2803 break;
2806 Lex.Lex();
2807 break;
2810 Lex.Lex();
2811 break;
2813 auto BinaryVal = Lex.getCurBinaryIntVal();
2815 for (unsigned i = 0, e = BinaryVal.second; i != e; ++i)
2816 Bits[i] = BitInit::get(Records, BinaryVal.first & (1LL << i));
2818 Lex.Lex();
2819 break;
2820 }
2822 std::string Val = Lex.getCurStrVal();
2823 Lex.Lex();
2824
2825
2827 Val += Lex.getCurStrVal();
2828 Lex.Lex();
2829 }
2830
2832 break;
2833 }
2836 Lex.Lex();
2837 break;
2840 Lex.Lex();
2841 break;
2843 SMRange NameLoc = Lex.getLocRange();
2847 return Name;
2849 return ParseIDValue(CurRec, Name, NameLoc, Mode);
2850
2851
2852
2853
2854 const Record *Class = Records.getClass(Name->getValue());
2855 if (!Class) {
2857 "Expected a class name, got '" + Name->getValue() + "'");
2858 return nullptr;
2859 }
2860
2863 Lex.Lex();
2864 if (ParseTemplateArgValueList(Args, ArgLocs, CurRec, Class))
2865 return nullptr;
2866
2867 if (CheckTemplateArgValues(Args, ArgLocs, Class))
2868 return nullptr;
2869
2870 if (resolveArguments(Class, Args, NameLoc.Start))
2871 return nullptr;
2872
2873 if (TrackReferenceLocs)
2874 Class->appendReferenceLoc(NameLoc);
2876 }
2877 case tgtok::l_brace: {
2878 SMLoc BraceLoc = Lex.getLoc();
2879 Lex.Lex();
2881
2883 ParseValueList(Vals, CurRec);
2884 if (Vals.empty())
2885 return nullptr;
2886 }
2888 TokError("expected '}' at end of bit list value");
2889 return nullptr;
2890 }
2891
2893
2894
2895
2896
2897 for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
2898
2899
2900
2901
2903 for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
2905 continue;
2906 }
2907
2910 for (unsigned i = 0, e = BitsRec->getNumBits(); i != e; ++i)
2911 NewBits.push_back(VI->getBit((e - i) - 1));
2912 continue;
2913 }
2914
2915 }
2916
2917 const Init *Bit = Vals[i]->getCastTo(BitRecTy::get(Records));
2918 if (!Bit) {
2919 Error(BraceLoc, "Element #" + Twine(i) + " (" + Vals[i]->getAsString() +
2920 ") is not convertable to a bit");
2921 return nullptr;
2922 }
2924 }
2925 std::reverse(NewBits.begin(), NewBits.end());
2927 }
2929 Lex.Lex();
2931
2932 const RecTy *DeducedEltTy = nullptr;
2933 const ListRecTy *GivenListTy = nullptr;
2934
2935 if (ItemType) {
2937 if (!ListType) {
2938 TokError(Twine("Encountered a list when expecting a ") +
2940 return nullptr;
2941 }
2942 GivenListTy = ListType;
2943 }
2944
2946 ParseValueList(Vals, CurRec,
2947 GivenListTy ? GivenListTy->getElementType() : nullptr);
2948 if (Vals.empty())
2949 return nullptr;
2950 }
2952 TokError("expected ']' at end of list value");
2953 return nullptr;
2954 }
2955
2956 const RecTy *GivenEltTy = nullptr;
2958
2959 GivenEltTy = ParseType();
2960 if (!GivenEltTy) {
2961
2962 return nullptr;
2963 }
2964
2966 TokError("expected '>' at end of list element type");
2967 return nullptr;
2968 }
2969 }
2970
2971
2972 const RecTy *EltTy = nullptr;
2973 for (const Init *V : Vals) {
2975 if (TArg) {
2976 if (EltTy) {
2977 EltTy = resolveTypes(EltTy, TArg->getType());
2978 if (!EltTy) {
2979 TokError("Incompatible types in list elements");
2980 return nullptr;
2981 }
2982 } else {
2983 EltTy = TArg->getType();
2984 }
2985 }
2986 }
2987
2988 if (GivenEltTy) {
2989 if (EltTy) {
2990
2992 TokError("Incompatible types in list elements");
2993 return nullptr;
2994 }
2995 }
2996 EltTy = GivenEltTy;
2997 }
2998
2999 if (!EltTy) {
3000 if (!ItemType) {
3001 TokError("No type for list");
3002 return nullptr;
3003 }
3005 } else {
3006
3007 if (GivenListTy) {
3009 TokError(Twine("Element type mismatch for list: element type '") +
3010 EltTy->getAsString() + "' not convertible to '" +
3012 return nullptr;
3013 }
3014 }
3015 DeducedEltTy = EltTy;
3016 }
3017
3019 }
3020 case tgtok::l_paren: {
3021
3022 Lex.Lex();
3026 TokError("expected identifier or list of value types in dag init");
3027 return nullptr;
3028 }
3029
3030 const Init *Operator = ParseValue(CurRec);
3031 if (!Operator)
3032 return nullptr;
3033
3034
3035 const StringInit *OperatorName = nullptr;
3037 if (Lex.getCode() != tgtok::VarName) {
3038 TokError("expected variable name in dag operator");
3039 return nullptr;
3040 }
3041 OperatorName = StringInit::get(Records, Lex.getCurStrVal());
3042 Lex.Lex();
3043 }
3044
3047 ParseDagArgList(DagArgs, CurRec);
3048 if (DagArgs.empty())
3049 return nullptr;
3050 }
3051
3053 TokError("expected ')' in dag init");
3054 return nullptr;
3055 }
3056
3057 return DagInit::get(Operator, OperatorName, DagArgs);
3058 }
3059 }
3060
3061 return R;
3062}
3063
3064
3065
3066
3067
3068
3069
3070
3071const Init *TGParser::ParseValue(Record *CurRec, const RecTy *ItemType,
3072 IDParseMode Mode) {
3073 SMLoc LHSLoc = Lex.getLoc();
3074 const Init *Result = ParseSimpleValue(CurRec, ItemType, Mode);
3075 if (!Result)
3076 return nullptr;
3077
3078
3079 while (true) {
3080 switch (Lex.getCode()) {
3081 default:
3084 if (Mode == ParseNameMode)
3085
3087
3088 SMLoc CurlyLoc = Lex.getLoc();
3089 Lex.Lex();
3090 SmallVector<unsigned, 16> Ranges;
3091 ParseRangeList(Ranges);
3093 return nullptr;
3094
3095
3097 Result = Result->convertInitializerBitRange(Ranges);
3098 if (!Result) {
3099 Error(CurlyLoc, "Invalid bit range for value");
3100 return nullptr;
3101 }
3102
3103
3105 TokError("expected '}' at end of bit range list");
3106 return nullptr;
3107 }
3108 break;
3109 }
3112 if () {
3113 Error(LHSLoc, "Invalid value, list expected");
3114 return nullptr;
3115 }
3116
3118 if (!LHSTy) {
3119 Error(LHSLoc, "Type '" + Twine(LHS->getType()->getAsString()) +
3120 "' is invalid, list expected");
3121 return nullptr;
3122 }
3123
3124 Lex.Lex();
3125 const TypedInit *RHS = ParseSliceElements(CurRec, true);
3126 if ()
3127 return nullptr;
3128
3132 } else {
3134 LHSTy->getElementType())
3135 ->Fold(CurRec);
3136 }
3137
3139
3140
3142 TokError("expected ']' at end of list slice");
3143 return nullptr;
3144 }
3145 break;
3146 }
3148 if (Lex.Lex() != tgtok::Id) {
3149 TokError("expected field identifier after '.'");
3150 return nullptr;
3151 }
3152 SMRange FieldNameLoc = Lex.getLocRange();
3153 const StringInit *FieldName =
3155 if (->getFieldType(FieldName)) {
3156 TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" +
3157 Result->getAsString() + "'");
3158 return nullptr;
3159 }
3160
3161
3162 if (TrackReferenceLocs) {
3164 const RecordVal *V = DI->getDef()->getValue(FieldName);
3165 const_cast<RecordVal *>(V)->addReferenceLoc(FieldNameLoc);
3168 for (const Record *R : RecTy->getClasses())
3169 if (const auto *RV = R->getValue(FieldName))
3170 const_cast<RecordVal *>(RV)->addReferenceLoc(FieldNameLoc);
3171 }
3172 }
3173 }
3174
3176 Lex.Lex();
3177 break;
3178 }
3179
3181 SMLoc PasteLoc = Lex.getLoc();
3183 if () {
3184 Error(PasteLoc, "LHS of paste is not typed!");
3185 return nullptr;
3186 }
3187
3188
3190 Lex.Lex();
3191
3192 assert(Mode == ParseValueMode && "encountered paste of lists in name");
3193
3194 switch (Lex.getCode()) {
3199 break;
3200 default:
3201 const Init *RHSResult = ParseValue(CurRec, ItemType, ParseValueMode);
3202 if (!RHSResult)
3203 return nullptr;
3205 break;
3206 }
3207 break;
3208 }
3209
3210
3211
3215 ->Fold(CurRec));
3216 if (!CastLHS) {
3218 Twine("can't cast '") + LHS->getAsString() + "' to string");
3219 return nullptr;
3220 }
3221 LHS = CastLHS;
3222 }
3223
3224 const TypedInit *RHS = nullptr;
3225
3226 Lex.Lex();
3227 switch (Lex.getCode()) {
3231
3232
3233
3234
3235
3237 break;
3238
3239 default:
3240 const Init *RHSResult = ParseValue(CurRec, nullptr, ParseNameMode);
3241 if (!RHSResult)
3242 return nullptr;
3244 if () {
3245 Error(PasteLoc, "RHS of paste is not typed!");
3246 return nullptr;
3247 }
3248
3252 ->Fold(CurRec));
3253 if (!CastRHS) {
3255 Twine("can't cast '") + RHS->getAsString() + "' to string");
3256 return nullptr;
3257 }
3258 RHS = CastRHS;
3259 }
3260
3261 break;
3262 }
3263
3265 break;
3266 }
3267 }
3268}
3269
3270
3271
3272
3273
3274
3275
3276void TGParser::ParseDagArgList(
3277 SmallVectorImpl<std::pair<const Init *, const StringInit *>> &Result,
3279
3280 while (true) {
3281
3283
3286 Lex.Lex();
3287 } else {
3288
3289 const Init *Val = ParseValue(CurRec);
3290 if (!Val) {
3292 return;
3293 }
3294
3295
3296 const StringInit *VarName = nullptr;
3299 TokError("expected variable name in dag literal");
3301 return;
3302 }
3304 Lex.Lex();
3305 }
3306
3307 Result.emplace_back(Val, VarName);
3308 }
3310 break;
3311 }
3312}
3313
3314
3315
3316
3317
3318
3319
3321 Record *CurRec, const RecTy *ItemType) {
3322 Result.push_back(ParseValue(CurRec, ItemType));
3323 if (.back()) {
3325 return;
3326 }
3327
3329
3331 return;
3332 Result.push_back(ParseValue(CurRec, ItemType));
3333 if (.back()) {
3335 return;
3336 }
3337 }
3338}
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348bool TGParser::ParseTemplateArgValueList(
3351 assert(Result.empty() && "Result vector is not empty");
3353
3355 return false;
3356
3357 bool HasNamedArg = false;
3358 unsigned ArgIndex = 0;
3359 while (true) {
3360 if (ArgIndex >= TArgs.size()) {
3361 TokError("Too many template arguments: " + utostr(ArgIndex + 1));
3362 return true;
3363 }
3364
3365 SMLoc ValueLoc = ArgLocs.emplace_back(Lex.getLoc());
3366
3367
3368 const Init *Value = ParseValue(
3369 CurRec,
3370 HasNamedArg ? nullptr : ArgsRec->getValue(TArgs[ArgIndex])->getType());
3372 return true;
3373
3374
3377 return Error(ValueLoc,
3378 "The name of named argument should be a valid identifier");
3379
3382 auto *NamedArg = ArgsRec->getValue(QualifiedName);
3383 if (!NamedArg)
3384 return Error(ValueLoc,
3385 "Argument " + Name->getAsString() + " doesn't exist");
3386
3387 Lex.Lex();
3388 ValueLoc = Lex.getLoc();
3389 Value = ParseValue(CurRec, NamedArg->getType());
3390
3392 return Error(ValueLoc,
3393 "The value of named argument should be initialized, "
3394 "but we got '" +
3395 Value->getAsString() + "'");
3396
3398 HasNamedArg = true;
3399 } else {
3400
3401 if (HasNamedArg)
3402 return Error(ValueLoc,
3403 "Positional argument should be put before named argument");
3404
3406 }
3407
3409 return false;
3411 return TokError("Expected comma before next argument");
3412 ++ArgIndex;
3413 }
3414}
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426const Init *TGParser::ParseDeclaration(Record *CurRec,
3427 bool ParsingTemplateArgs) {
3428
3430
3431 const RecTy *Type = ParseType();
3433 return nullptr;
3434
3435 if (Lex.getCode() != tgtok::Id) {
3436 TokError("Expected identifier in declaration");
3437 return nullptr;
3438 }
3439
3440 std::string Str = Lex.getCurStrVal();
3441 if (Str == "NAME") {
3442 TokError("'" + Str + "' is a reserved variable name");
3443 return nullptr;
3444 }
3445
3446 if (!ParsingTemplateArgs && CurScope->varAlreadyDefined(Str)) {
3447 TokError("local variable of this name already exists");
3448 return nullptr;
3449 }
3450
3451 SMLoc IdLoc = Lex.getLoc();
3453 Lex.Lex();
3454
3455 bool BadField;
3456 if (!ParsingTemplateArgs) {
3457 BadField = AddValue(CurRec, IdLoc,
3458 RecordVal(DeclName, IdLoc, Type,
3461 } else if (CurRec) {
3462 DeclName = QualifyName(*CurRec, DeclName);
3463 BadField =
3464 AddValue(CurRec, IdLoc,
3466 } else {
3467 assert(CurMultiClass && "invalid context for template argument");
3468 DeclName = QualifyName(CurMultiClass, DeclName);
3469 BadField =
3470 AddValue(CurRec, IdLoc,
3472 }
3473 if (BadField)
3474 return nullptr;
3475
3476
3478 SMLoc ValLoc = Lex.getLoc();
3479 const Init *Val = ParseValue(CurRec, Type);
3480 if (!Val ||
3481 SetValue(CurRec, ValLoc, DeclName, {}, Val,
3482 false, false)) {
3483
3484
3485
3486 return DeclName;
3487 }
3488 }
3489
3490 return DeclName;
3491}
3492
3493
3494
3495
3496
3497
3498
3499
3500
3502TGParser::ParseForeachDeclaration(const Init *&ForeachListValue) {
3503 if (Lex.getCode() != tgtok::Id) {
3504 TokError("Expected identifier in foreach declaration");
3505 return nullptr;
3506 }
3507
3508 const Init *DeclName = StringInit::get(Records, Lex.getCurStrVal());
3509 Lex.Lex();
3510
3511
3513 TokError("Expected '=' in foreach declaration");
3514 return nullptr;
3515 }
3516
3517 const RecTy *IterType = nullptr;
3518 SmallVector<unsigned, 16> Ranges;
3519
3520 switch (Lex.getCode()) {
3522 Lex.Lex();
3523 ParseRangeList(Ranges);
3525 TokError("expected '}' at end of bit range list");
3526 return nullptr;
3527 }
3528 break;
3529 }
3530
3531 default: {
3532 SMLoc ValueLoc = Lex.getLoc();
3533 const Init *I = ParseValue(nullptr);
3534 if ()
3535 return nullptr;
3536
3539 ForeachListValue = I;
3540 IterType = cast(TI->getType())->getElementType();
3541 break;
3542 }
3543
3544 if (TI) {
3545 if (ParseRangePiece(Ranges, TI))
3546 return nullptr;
3547 break;
3548 }
3549
3550 Error(ValueLoc, "expected a list, got '" + I->getAsString() + "'");
3551 if (CurMultiClass) {
3552 PrintNote({}, "references to multiclass template arguments cannot be "
3553 "resolved at this time");
3554 }
3555 return nullptr;
3556 }
3557 }
3558
3559 if (.empty()) {
3560 assert(!IterType && "Type already initialized?");
3562 std::vector<Init *> Values;
3563 for (unsigned R : Ranges)
3565 ForeachListValue = ListInit::get(Values, IterType);
3566 }
3567
3568 if (!IterType)
3569 return nullptr;
3570
3572}
3573
3574
3575
3576
3577
3578
3579
3580
3581bool TGParser::ParseTemplateArgList(Record *CurRec) {
3582 assert(Lex.getCode() == tgtok::less && "Not a template arg list!");
3583 Lex.Lex();
3584
3585 Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec;
3586
3587
3588 const Init *TemplArg = ParseDeclaration(CurRec, true );
3589 if (!TemplArg)
3590 return true;
3591
3593
3595
3596 SMLoc Loc = Lex.getLoc();
3597 TemplArg = ParseDeclaration(CurRec, true );
3598 if (!TemplArg)
3599 return true;
3600
3602 return Error(Loc, "template argument with the same name has already been "
3603 "defined");
3604
3606 }
3607
3609 return TokError("expected '>' at end of template argument list");
3610 return false;
3611}
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621bool TGParser::ParseBodyItem(Record *CurRec) {
3623 return ParseAssert(nullptr, CurRec);
3624
3626 return ParseDefvar(CurRec);
3627
3629 return ParseDump(nullptr, CurRec);
3630
3632 if (!ParseDeclaration(CurRec, false))
3633 return true;
3634
3636 return TokError("expected ';' after declaration");
3637 return false;
3638 }
3639
3640
3642 return TokError("expected field identifier after let");
3643
3644 SMLoc IdLoc = Lex.getLoc();
3645 const StringInit *FieldName = StringInit::get(Records, Lex.getCurStrVal());
3646 Lex.Lex();
3647
3648 SmallVector<unsigned, 16> BitList;
3649 if (ParseOptionalBitList(BitList))
3650 return true;
3651 std::reverse(BitList.begin(), BitList.end());
3652
3654 return TokError("expected '=' in let expression");
3655
3658 return Error(IdLoc, "Value '" + FieldName->getValue() + "' unknown!");
3659
3660 const RecTy *Type = Field->getType();
3662
3663
3665 }
3666
3667 const Init *Val = ParseValue(CurRec, Type);
3668 if (!Val)
3669 return true;
3670
3672 return TokError("expected ';' after let expression");
3673
3674 return SetValue(CurRec, IdLoc, FieldName, BitList, Val);
3675}
3676
3677
3678
3679
3680
3681
3682
3683
3684bool TGParser::ParseBody(Record *CurRec) {
3685
3687 return false;
3688
3690 return TokError("Expected '{' to start body or ';' for declaration only");
3691
3693 if (ParseBodyItem(CurRec))
3694 return true;
3695
3696
3697 Lex.Lex();
3698
3699
3700 SMLoc SemiLoc = Lex.getLoc();
3702 PrintError(SemiLoc, "A class or def body should not end with a semicolon");
3703 PrintNote("Semicolon ignored; remove to eliminate this error");
3704 }
3705
3706 return false;
3707}
3708
3709
3710
3711bool TGParser::ApplyLetStack(Record *CurRec) {
3712 for (SmallVectorImpl &LetInfo : LetStack)
3713 for (LetRecord &LR : LetInfo)
3714 if (SetValue(CurRec, LR.Loc, LR.Name, LR.Bits, LR.Value))
3715 return true;
3716 return false;
3717}
3718
3719
3720bool TGParser::ApplyLetStack(RecordsEntry &Entry) {
3722 return ApplyLetStack(Entry.Rec.get());
3723
3724
3725 if (Entry.Assertion)
3726 return false;
3727
3728
3730 return false;
3731
3732 for (auto &E : Entry.Loop->Entries) {
3733 if (ApplyLetStack(E))
3734 return true;
3735 }
3736
3737 return false;
3738}
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749bool TGParser::ParseObjectBody(Record *CurRec) {
3750
3751 TGVarScope *ObjectScope = PushScope(CurRec);
3752
3754
3755
3756 SubClassReference SubClass = ParseSubClassReference(CurRec, false);
3757 while (true) {
3758
3759 if (!SubClass.Rec)
3760 return true;
3761
3762
3763 if (AddSubClass(CurRec, SubClass))
3764 return true;
3765
3767 break;
3768 SubClass = ParseSubClassReference(CurRec, false);
3769 }
3770 }
3771
3772 if (ApplyLetStack(CurRec))
3773 return true;
3774
3775 bool Result = ParseBody(CurRec);
3778}
3779
3780
3781
3782
3783
3784
3785bool TGParser::ParseDef(MultiClass *CurMultiClass) {
3786 SMLoc DefLoc = Lex.getLoc();
3788 Lex.Lex();
3789
3790
3791
3792
3793 SMLoc NameLoc = Lex.getCode() == tgtok::Id ? Lex.getLoc() : DefLoc;
3794
3795
3796 std::unique_ptr CurRec;
3797 const Init *Name = ParseObjectName(CurMultiClass);
3798 if (!Name)
3799 return true;
3800
3802 CurRec = std::make_unique(Records.getNewAnonymousName(), DefLoc,
3804 } else {
3805 CurRec = std::make_unique(Name, NameLoc, Records);
3806 }
3807
3808 if (ParseObjectBody(CurRec.get()))
3809 return true;
3810
3811 return addEntry(std::move(CurRec));
3812}
3813
3814
3815
3816
3817
3818bool TGParser::ParseDefset() {
3820 Lex.Lex();
3821
3822 DefsetRecord Defset;
3823 Defset.Loc = Lex.getLoc();
3824 const RecTy *Type = ParseType();
3826 return true;
3828 return Error(Defset.Loc, "expected list type");
3830
3832 return TokError("expected identifier");
3833 const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
3834 if (Records.getGlobal(DeclName->getValue()))
3835 return TokError("def or global variable of this name already exists");
3836
3837 if (Lex.Lex() != tgtok::equal)
3838 return TokError("expected '='");
3840 return TokError("expected '{'");
3841 SMLoc BraceLoc = Lex.getLoc();
3842 Lex.Lex();
3843
3844 Defsets.push_back(&Defset);
3845 bool Err = ParseObjectList(nullptr);
3846 Defsets.pop_back();
3847 if (Err)
3848 return true;
3849
3851 TokError("expected '}' at end of defset");
3852 return Error(BraceLoc, "to match this '{'");
3853 }
3854
3855 Records.addExtraGlobal(DeclName->getValue(),
3857 return false;
3858}
3859
3860
3861
3862
3863
3864bool TGParser::ParseDeftype() {
3866 Lex.Lex();
3867
3869 return TokError("expected identifier");
3870
3871 const std::string TypeName = Lex.getCurStrVal();
3872 if (TypeAliases.count(TypeName) || Records.getClass(TypeName))
3873 return TokError("type of this name '" + TypeName + "' already exists");
3874
3875 Lex.Lex();
3877 return TokError("expected '='");
3878
3879 SMLoc Loc = Lex.getLoc();
3880 const RecTy *Type = ParseType();
3882 return true;
3883
3885 return Error(Loc, "cannot define type alias for class type '" +
3886 Type->getAsString() + "'");
3887
3889
3891 return TokError("expected ';'");
3892
3893 return false;
3894}
3895
3896
3897
3898
3899
3900bool TGParser::ParseDefvar(Record *CurRec) {
3902 Lex.Lex();
3903
3905 return TokError("expected identifier");
3906 const StringInit *DeclName = StringInit::get(Records, Lex.getCurStrVal());
3907 if (CurScope->varAlreadyDefined(DeclName->getValue()))
3908 return TokError("local variable of this name already exists");
3909
3910
3911 if (CurRec) {
3913 if (V && ->isTemplateArg())
3914 return TokError("field of this name already exists");
3915 }
3916
3917
3918
3919 if (CurScope->isOutermost() && Records.getGlobal(DeclName->getValue()))
3920 return TokError("def or global variable of this name already exists");
3921
3922 Lex.Lex();
3924 return TokError("expected '='");
3925
3926 const Init *Value = ParseValue(CurRec);
3928 return true;
3929
3931 return TokError("expected ';'");
3932
3933 if (!CurScope->isOutermost())
3935 else
3936 Records.addExtraGlobal(DeclName->getValue(), Value);
3937
3938 return false;
3939}
3940
3941
3942
3943
3944
3945
3946
3947bool TGParser::ParseForeach(MultiClass *CurMultiClass) {
3948 SMLoc Loc = Lex.getLoc();
3950 Lex.Lex();
3951
3952
3953
3954 const Init *ListValue = nullptr;
3955 const VarInit *IterName = ParseForeachDeclaration(ListValue);
3956 if (!IterName)
3957 return TokError("expected declaration in for");
3958
3960 return TokError("Unknown tok");
3961
3962
3963 auto TheLoop = std::make_unique(Loc, IterName, ListValue);
3964
3965 TGVarScope *ForeachScope = PushScope(TheLoop.get());
3966 Loops.push_back(std::move(TheLoop));
3967
3969
3970 if (ParseObject(CurMultiClass))
3971 return true;
3972 } else {
3973 SMLoc BraceLoc = Lex.getLoc();
3974
3975 Lex.Lex();
3976
3977
3978 if (ParseObjectList(CurMultiClass))
3979 return true;
3980
3982 TokError("expected '}' at end of foreach command");
3983 return Error(BraceLoc, "to match this '{'");
3984 }
3985 }
3986
3988
3989
3990 std::unique_ptr Loop = std::move(Loops.back());
3991 Loops.pop_back();
3992
3993 return addEntry(std::move(Loop));
3994}
3995
3996
3997
3998
3999
4000
4001bool TGParser::ParseIf(MultiClass *CurMultiClass) {
4002 SMLoc Loc = Lex.getLoc();
4004 Lex.Lex();
4005
4006
4007
4008 const Init *Condition = ParseValue(nullptr);
4009 if (!Condition)
4010 return true;
4011
4013 return TokError("Unknown tok");
4014
4015
4016
4017
4018
4019
4020
4022 const ListInit *SingletonList =
4025
4026
4027
4028 const Init *ThenClauseList =
4030 BitListTy)
4031 ->Fold(nullptr);
4032 Loops.push_back(std::make_unique(Loc, nullptr, ThenClauseList));
4033
4034 if (ParseIfBody(CurMultiClass, "then"))
4035 return true;
4036
4037 std::unique_ptr Loop = std::move(Loops.back());
4038 Loops.pop_back();
4039
4040 if (addEntry(std::move(Loop)))
4041 return true;
4042
4043
4044
4045
4046
4048
4049
4050 const Init *ElseClauseList =
4052 BitListTy)
4053 ->Fold(nullptr);
4054 Loops.push_back(
4055 std::make_unique(Loc, nullptr, ElseClauseList));
4056
4057 if (ParseIfBody(CurMultiClass, "else"))
4058 return true;
4059
4060 Loop = std::move(Loops.back());
4061 Loops.pop_back();
4062
4063 if (addEntry(std::move(Loop)))
4064 return true;
4065 }
4066
4067 return false;
4068}
4069
4070
4071
4072
4073
4074
4076
4077 TGVarScope *BodyScope = PushScope();
4078
4080
4081 if (ParseObject(CurMultiClass))
4082 return true;
4083 } else {
4084 SMLoc BraceLoc = Lex.getLoc();
4085
4086 Lex.Lex();
4087
4088
4089 if (ParseObjectList(CurMultiClass))
4090 return true;
4091
4093 TokError("expected '}' at end of '" + Kind + "' clause");
4094 return Error(BraceLoc, "to match this '{'");
4095 }
4096 }
4097
4099 return false;
4100}
4101
4102
4103
4104
4105bool TGParser::ParseAssert(MultiClass *CurMultiClass, Record *CurRec) {
4107 Lex.Lex();
4108
4109 SMLoc ConditionLoc = Lex.getLoc();
4110 const Init *Condition = ParseValue(CurRec);
4111 if (!Condition)
4112 return true;
4113
4115 TokError("expected ',' in assert statement");
4116 return true;
4117 }
4118
4119 const Init *Message = ParseValue(CurRec);
4120 if (!Message)
4121 return true;
4122
4124 return TokError("expected ';'");
4125
4126 if (CurRec)
4127 CurRec->addAssertion(ConditionLoc, Condition, Message);
4128 else
4129 addEntry(std::make_uniqueRecord::AssertionInfo(ConditionLoc, Condition,
4130 Message));
4131 return false;
4132}
4133
4134
4135
4136
4137
4138bool TGParser::ParseClass() {
4140 Lex.Lex();
4141
4143 return TokError("expected class name after 'class' keyword");
4144
4145 const std::string &Name = Lex.getCurStrVal();
4146 Record *CurRec = const_cast<Record *>(Records.getClass(Name));
4147 if (CurRec) {
4148
4149 if (!CurRec->getValues().empty() ||
4153 "' already defined");
4154
4156 } else {
4157
4158 auto NewRec = std::make_unique(Lex.getCurStrVal(), Lex.getLoc(),
4160 CurRec = NewRec.get();
4161 Records.addClass(std::move(NewRec));
4162 }
4163
4164 if (TypeAliases.count(Name))
4165 return TokError("there is already a defined type alias '" + Name + "'");
4166
4167 Lex.Lex();
4168
4169
4170 TGVarScope *ClassScope = PushScope(CurRec);
4171
4173 if (ParseTemplateArgList(CurRec))
4174 return true;
4175
4176 if (ParseObjectBody(CurRec))
4177 return true;
4178
4179 if (!NoWarnOnUnusedTemplateArgs)
4181
4183 return false;
4184}
4185
4186
4187
4188
4189
4190
4191
4193 do {
4194 if (Lex.getCode() != tgtok::Id) {
4195 TokError("expected identifier in let definition");
4197 return;
4198 }
4199
4201 SMLoc NameLoc = Lex.getLoc();
4202 Lex.Lex();
4203
4204
4205 SmallVector<unsigned, 16> Bits;
4206 if (ParseOptionalRangeList(Bits)) {
4208 return;
4209 }
4210 std::reverse(Bits.begin(), Bits.end());
4211
4213 TokError("expected '=' in let expression");
4215 return;
4216 }
4217
4218 const Init *Val = ParseValue(nullptr);
4219 if (!Val) {
4221 return;
4222 }
4223
4224
4225 Result.emplace_back(Name, Bits, Val, NameLoc);
4227}
4228
4229
4230
4231
4232
4233
4234
4235bool TGParser::ParseTopLevelLet(MultiClass *CurMultiClass) {
4237 Lex.Lex();
4238
4239
4241 ParseLetList(LetInfo);
4242 if (LetInfo.empty())
4243 return true;
4244 LetStack.push_back(std::move(LetInfo));
4245
4247 return TokError("expected 'in' at end of top-level 'let'");
4248
4249
4251
4252 if (ParseObject(CurMultiClass))
4253 return true;
4254 } else {
4255 SMLoc BraceLoc = Lex.getLoc();
4256
4257 Lex.Lex();
4258
4259
4260 TGVarScope *LetScope = PushScope();
4261
4262
4263 if (ParseObjectList(CurMultiClass))
4264 return true;
4265
4267 TokError("expected '}' at end of top level let command");
4268 return Error(BraceLoc, "to match this '{'");
4269 }
4270
4272 }
4273
4274
4275 LetStack.pop_back();
4276 return false;
4277}
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292bool TGParser::ParseMultiClass() {
4294 Lex.Lex();
4295
4297 return TokError("expected identifier after multiclass for name");
4298 std::string Name = Lex.getCurStrVal();
4299
4300 auto Result = MultiClasses.try_emplace(
4301 Name, std::make_unique(Name, Lex.getLoc(), Records));
4302
4304 return TokError("multiclass '" + Name + "' already defined");
4305
4306 CurMultiClass = Result.first->second.get();
4307 Lex.Lex();
4308
4309
4310 TGVarScope *MulticlassScope = PushScope(CurMultiClass);
4311
4312
4314 if (ParseTemplateArgList(nullptr))
4315 return true;
4316
4317 bool inherits = false;
4318
4319
4321 inherits = true;
4322
4323
4324 SubMultiClassReference SubMultiClass =
4325 ParseSubMultiClassReference(CurMultiClass);
4326 while (true) {
4327
4328 if (!SubMultiClass.MC)
4329 return true;
4330
4331
4332 if (AddSubMultiClass(CurMultiClass, SubMultiClass))
4333 return true;
4334
4336 break;
4337 SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
4338 }
4339 }
4340
4342 if (!inherits)
4343 return TokError("expected '{' in multiclass definition");
4345 return TokError("expected ';' in multiclass definition");
4346 } else {
4348 return TokError("multiclass must contain at least one def");
4349
4351 switch (Lex.getCode()) {
4352 default:
4353 return TokError("expected 'assert', 'def', 'defm', 'defvar', 'dump', "
4354 "'foreach', 'if', or 'let' in multiclass body");
4355
4364 if (ParseObject(CurMultiClass))
4365 return true;
4366 break;
4367 }
4368 }
4369 Lex.Lex();
4370
4371
4372 SMLoc SemiLoc = Lex.getLoc();
4374 PrintError(SemiLoc, "A multiclass body should not end with a semicolon");
4375 PrintNote("Semicolon ignored; remove to eliminate this error");
4376 }
4377 }
4378
4379 if (!NoWarnOnUnusedTemplateArgs)
4380 CurMultiClass->Rec.checkUnusedTemplateArgs();
4381
4383 CurMultiClass = nullptr;
4384 return false;
4385}
4386
4387
4388
4389
4390
4391bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
4393 Lex.Lex();
4394
4395 const Init *DefmName = ParseObjectName(CurMultiClass);
4396 if (!DefmName)
4397 return true;
4399 DefmName = Records.getNewAnonymousName();
4400 if (CurMultiClass)
4404 DefmName);
4405 }
4406
4408 return TokError("expected ':' after defm identifier");
4409
4410
4411 std::vector NewEntries;
4412
4413
4414 bool InheritFromClass = false;
4415
4416
4417 Lex.Lex();
4418
4419 SMLoc SubClassLoc = Lex.getLoc();
4420 SubClassReference Ref = ParseSubClassReference(nullptr, true);
4421
4422 while (true) {
4423 if (.Rec)
4424 return true;
4425
4426
4427
4428
4429
4430 MultiClass *MC = MultiClasses[Ref.Rec->getName().str()].get();
4431 assert(MC && "Didn't lookup multiclass correctly?");
4432
4433 SubstStack Substs;
4434 if (resolveArgumentsOfMultiClass(Substs, MC, Ref.TemplateArgs, DefmName,
4435 SubClassLoc))
4436 return true;
4437
4438 if (resolve(MC->Entries, Substs, !CurMultiClass && Loops.empty(),
4439 &NewEntries, &SubClassLoc))
4440 return true;
4441
4443 break;
4444
4446 return TokError("expected identifier");
4447
4448 SubClassLoc = Lex.getLoc();
4449
4450
4451
4452 InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != nullptr);
4453
4454 if (InheritFromClass)
4455 break;
4456
4457 Ref = ParseSubClassReference(nullptr, true);
4458 }
4459
4460 if (InheritFromClass) {
4461
4462
4463 SubClassReference SubClass = ParseSubClassReference(nullptr, false);
4464 while (true) {
4465
4466 if (!SubClass.Rec)
4467 return true;
4468
4469
4470
4471 for (auto &E : NewEntries) {
4472
4473 if (AddSubClass(E, SubClass))
4474 return true;
4475 }
4476
4478 break;
4479 SubClass = ParseSubClassReference(nullptr, false);
4480 }
4481 }
4482
4483 for (auto &E : NewEntries) {
4484 if (ApplyLetStack(E))
4485 return true;
4486
4487 addEntry(std::move(E));
4488 }
4489
4491 return TokError("expected ';' at end of defm");
4492
4493 return false;
4494}
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508bool TGParser::ParseObject(MultiClass *MC) {
4509 switch (Lex.getCode()) {
4510 default:
4512 "Expected assert, class, def, defm, defset, dump, foreach, if, or let");
4514 return ParseAssert(MC);
4516 return ParseDef(MC);
4518 return ParseDefm(MC);
4520 return ParseDeftype();
4522 return ParseDefvar();
4524 return ParseDump(MC);
4526 return ParseForeach(MC);
4528 return ParseIf(MC);
4530 return ParseTopLevelLet(MC);
4532 if (MC)
4533 return TokError("defset is not allowed inside multiclass");
4534 return ParseDefset();
4536 if (MC)
4537 return TokError("class is not allowed inside multiclass");
4538 if (!Loops.empty())
4539 return TokError("class is not allowed inside foreach loop");
4540 return ParseClass();
4542 if (!Loops.empty())
4543 return TokError("multiclass is not allowed inside foreach loop");
4544 return ParseMultiClass();
4545 }
4546}
4547
4548
4549
4550bool TGParser::ParseObjectList(MultiClass *MC) {
4552 if (ParseObject(MC))
4553 return true;
4554 }
4555 return false;
4556}
4557
4559 Lex.Lex();
4561 if (ParseObjectList())
4562 return true;
4564
4565
4567 return false;
4568
4569 return TokError("Unexpected token at top level");
4570}
4571
4572
4573
4574
4575
4576bool TGParser::CheckTemplateArgValues(
4578 const Record *ArgsRec) {
4580 "expected as many values as locations");
4581
4583
4584 bool HasError = false;
4586 const Init *ArgName = nullptr;
4587 if (Value->isPositional())
4588 ArgName = TArgs[Value->getIndex()];
4589 if (Value->isNamed())
4591
4594
4596 auto *CastValue = ArgValue->getCastTo(ArgType);
4597 if (CastValue) {
4600 "result of template arg value cast has wrong type");
4601 Value = Value->cloneWithValue(CastValue);
4602 } else {
4603 HasError |= Error(
4604 Loc, "Value specified for template argument '" +
4606 ArgValue->getType()->getAsString() + "; expected type " +
4608 }
4609 }
4610 }
4611
4612 return HasError;
4613}
4614
4615#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
4618 Loop->dump();
4619 if (Rec)
4620 Rec->dump();
4621}
4622
4624 errs() << "foreach " << IterVar->getAsString() << " = "
4625 << ListValue->getAsString() << " in {\n";
4626
4627 for (const auto &E : Entries)
4628 E.dump();
4629
4630 errs() << "}\n";
4631}
4632
4634 errs() << "Record:\n";
4635 Rec.dump();
4636
4637 errs() << "Defs:\n";
4638 for (const auto &E : Entries)
4639 E.dump();
4640}
4641#endif
4642
4643bool TGParser::ParseDump(MultiClass *CurMultiClass, Record *CurRec) {
4644
4647 Lex.Lex();
4648
4649 const Init *Message = ParseValue(CurRec);
4650 if (!Message)
4651 return true;
4652
4653
4654
4657 ->Fold(CurRec);
4658
4660 return TokError("expected ';'");
4661
4662 if (CurRec)
4664 else {
4667
4669 addEntry(std::make_uniqueRecord::DumpInfo(Loc, ResolvedMessage));
4670 }
4671
4672 return false;
4673}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
uint64_t IntrinsicInst * II
OptimizedStructLayoutField Field
PowerPC Reduce CR logical Operation
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallVector class.
static bool checkBitsConcrete(Record &R, const RecordVal &RV)
Definition TGParser.cpp:77
static const Init * QualifyName(const Record &CurRec, const Init *Name)
Return an Init with a qualifier prefix referring to CurRec's name.
Definition TGParser.cpp:120
static const Init * QualifiedNameOfImplicitName(const Record &Rec)
Return the qualified version of the implicit 'NAME' template argument.
Definition TGParser.cpp:137
static void checkConcrete(Record &R)
Definition TGParser.cpp:96
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)
const Init * Fold(const Record *CurRec) const
static const CondOpInit * get(ArrayRef< const Init * > Conds, ArrayRef< const Init * > Values, const RecTy *Type)
static const DagInit * get(const Init *V, const StringInit *VN, ArrayRef< const Init * > Args, ArrayRef< const StringInit * > ArgNames)
static const DagRecTy * get(RecordKeeper &RK)
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 !...
const Init * Fold(const Record *CurRec, bool IsFinal=false) const
static const InstancesOpInit * get(const RecTy *Type, const Init *Regex)
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
static const ListInit * get(ArrayRef< const Init * > Range, const RecTy *EltTy)
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.
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.
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
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)
ArrayRef< std::pair< const Record *, SMRange > > getDirectSuperClasses() const
Return the direct superclasses of this record.
StringRef getName() const
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 addDirectSuperClass(const Record *R, SMRange Range)
void appendAssertions(const Record *Rec)
const Init * getNameInit() const
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.
tgtok::TokKind getCode() const
void PopScope(TGVarScope *ExpectedStackTop)
bool Error(SMLoc L, const Twine &Msg) const
bool TokError(const Twine &Msg) const
bool ParseFile()
ParseFile - Main entrypoint for parsing a tblgen file.
Definition TGParser.cpp:4558
const Init * getVar(RecordKeeper &Records, MultiClass *ParsingMultiClass, const StringInit *Name, SMRange NameLoc, bool TrackReferenceLocs) const
Definition TGParser.cpp:145
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...
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.
LLVM_ABI 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)
const Init * getNameInit() const
#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.
@ 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.
FunctionAddr VTableAddr Value
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
void PrintError(const Twine &Msg)
std::string utostr(uint64_t X, bool isNeg=false)
bool CheckAssert(SMLoc Loc, const Init *Condition, const Init *Message)
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
void PrintNote(const Twine &Msg)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
FunctionAddr VTableAddr Next
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
void dumpMessage(SMLoc Loc, const Init *Message)
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
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.
Implement std::hash so that hash_code can be used in STL containers.
ForeachLoop - Record the iteration state associated with a for loop.
std::vector< RecordsEntry > Entries
void dump() const
Definition TGParser.cpp:4623
std::vector< RecordsEntry > Entries
void dump() const
Definition TGParser.cpp:4633
RecordsEntry - Holds exactly one of a Record, ForeachLoop, or AssertionInfo.
std::unique_ptr< ForeachLoop > Loop
std::unique_ptr< Record::AssertionInfo > Assertion
void dump() const
Definition TGParser.cpp:4616
std::unique_ptr< Record::DumpInfo > Dump
std::unique_ptr< Record > Rec
Definition TGParser.cpp:43
SubClassReference()=default
SmallVector< const ArgumentInit *, 4 > TemplateArgs
Definition TGParser.cpp:46
SMRange RefRange
Definition TGParser.cpp:44
bool isInvalid() const
Definition TGParser.cpp:50
const Record * Rec
Definition TGParser.cpp:45
Definition TGParser.cpp:53
MultiClass * MC
Definition TGParser.cpp:55
void dump() const
Definition TGParser.cpp:66
bool isInvalid() const
Definition TGParser.cpp:60
SubMultiClassReference()=default
SmallVector< const ArgumentInit *, 4 > TemplateArgs
Definition TGParser.cpp:56
SMRange RefRange
Definition TGParser.cpp:54