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 (Field.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((!E.Rec + !E.Loop + !E.Assertion + !E.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 (I->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 (is\_contained(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 (Default->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 (R.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 (isa<IntRecTy>(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 (II)

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

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

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 (LHS)

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 (LHS)

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

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

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 (RHS)

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

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

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

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 (LHS)

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 (RHS)

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

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 (RHS)

2499 return nullptr;

2500 } else {

2502 }

2503

2505 TokError("expected ')' in !find operator");

2506 return nullptr;

2507 }

2508

2509 if (ItemType && Type->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 (RHS)

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

2675 LHS, MHS, RHS, OutType))

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

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

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 (RHS)

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

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

3198 Result = LHS;

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

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

3325 return;

3326 }

3327

3329

3331 return;

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

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

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