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 (Field.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 (I->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 (is\_contained(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 (Default->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 (R.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 (II)

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 (Type) {

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 (Type) {

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 (Type) {

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 && Type->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 (Args.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 (Type) {

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 (List) {

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 (Type) {

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 && Type->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 && Type->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 (Type) {

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) {

2655 const Init *R = nullptr;

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 (Operator) 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 (Result->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()) {

3056 Result = LHS;

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 (Result.back()) {

3183 return;

3184 }

3185

3187

3189 return;

3190 Result.push_back(ParseValue(CurRec, ItemType));

3191 if (Result.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 (Type) 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 (I)

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 (Ranges.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 && 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 (Ref.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