clang: lib/AST/ByteCode/Interp.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13#ifndef LLVM_CLANG_AST_INTERP_INTERP_H

14#define LLVM_CLANG_AST_INTERP_INTERP_H

15

34#include "llvm/ADT/APFloat.h"

35#include "llvm/ADT/APSInt.h"

36#include <type_traits>

37

40

41using APSInt = llvm::APSInt;

43

44

46

47

50

51

54

55

56

58 uint32_t Offset);

59

60

62

63

65

67

72

73

76

77

79 bool WillBeActivated = false);

80

81

83

84

86

87

88

90

91

92

95

98

99

100

103

105 uint32_t VarArgSize);

107 uint32_t VarArgSize);

109 uint32_t VarArgSize);

111 uint32_t BuiltinID);

117 bool TargetIsUCharOrByte);

121

124

126

128

129

130template <ShiftDir Dir, typename LT, typename RT>

132 unsigned Bits) {

133 if (RHS.isNegative()) {

135 S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt();

137 return false;

138 }

139

140

141

142 if (Bits > 1 && RHS >= Bits) {

144 const APSInt Val = RHS.toAPSInt();

146 S.CCEDiag(E, diag::note_constexpr_large_shift) << Val << Ty << Bits;

148 return false;

149 }

150

152 if (LHS.isSigned() && !S.getLangOpts().CPlusPlus20) {

153

154

155 if (LHS.isNegative()) {

157 S.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt();

159 return false;

160 } else if (LHS.toUnsigned().countLeadingZeros() <

161 static_cast<unsigned>(RHS)) {

163 S.CCEDiag(E, diag::note_constexpr_lshift_discards);

165 return false;

166 }

167 }

168 }

169

170

171

172

173 return true;

174}

175

176

177template

179 if (RHS.isZero()) {

181 if constexpr (std::is_same_v<T, Floating>) {

182 S.CCEDiag(Op, diag::note_expr_divide_by_zero)

183 << Op->getRHS()->getSourceRange();

184 return true;

185 }

186

187 S.FFDiag(Op, diag::note_expr_divide_by_zero)

188 << Op->getRHS()->getSourceRange();

189 return false;

190 }

191

192 if constexpr (!std::is_same_v<T, FixedPoint>) {

193 if (LHS.isSigned() && LHS.isMin() && RHS.isNegative() && RHS.isMinusOne()) {

194 APSInt LHSInt = LHS.toAPSInt();

196 (-LHSInt.extend(LHSInt.getBitWidth() + 1)).toString(Trunc, 10);

199 S.CCEDiag(Loc, diag::note_constexpr_overflow) << Trunc << E->getType();

200 return false;

201 }

202 }

203 return true;

204}

205

206

207

209 APFloat::opStatus Status, FPOptions FPO);

210

211

213

215

216

217

218

219

222

223template <PrimType Name, class T = typename PrimConv::T>

226

231

237 } else {

240

241

242 }

243 return true;

244}

245

248

251

256 } else {

259 }

260 return true;

261}

262

263

264

265

266

268 template class OpAP>

270 const T &RHS) {

271

275

276 if (!OpFW(LHS, RHS, Bits, &Result)) {

278 return true;

279 }

280

282

283

284 if constexpr (std::is_same_v<T, FixedPoint>)

286

287

289

290

296 .toString(Trunc, 10, Result.isSigned(), false,

297 true, true);

298 S.report(E->getExprLoc(), diag::warn_integer_constant_overflow)

300 }

301

304 return false;

305 }

306 return true;

307}

308

309template <PrimType Name, class T = typename PrimConv::T>

311 const T &RHS = S.Stk.pop<T>();

312 const T &LHS = S.Stk.pop<T>();

313 const unsigned Bits = RHS.bitWidth() + 1;

314

316}

317

328

329template <PrimType Name, class T = typename PrimConv::T>

331 const T &RHS = S.Stk.pop<T>();

332 const T &LHS = S.Stk.pop<T>();

333 const unsigned Bits = RHS.bitWidth() + 1;

334

336}

337

348

349template <PrimType Name, class T = typename PrimConv::T>

351 const T &RHS = S.Stk.pop<T>();

352 const T &LHS = S.Stk.pop<T>();

353 const unsigned Bits = RHS.bitWidth() * 2;

354

356}

357

370

371template <PrimType Name, class T = typename PrimConv::T>

376

377 if constexpr (std::is_same_v<T, Floating>) {

382

383 APFloat ResR(A.getSemantics());

384 APFloat ResI(A.getSemantics());

386

387

389 RA.copy(ResR);

391

393 RI.copy(ResI);

395 Result.initializeAllElements();

396 } else {

397

398 const T &LHSR = LHS.elem<T>(0);

399 const T &LHSI = LHS.elem<T>(1);

400 const T &RHSR = RHS.elem<T>(0);

401 const T &RHSI = RHS.elem<T>(1);

402 unsigned Bits = LHSR.bitWidth();

403

404

405 T A;

406 if (T::mul(LHSR, RHSR, Bits, &A))

407 return false;

408 T B;

409 if (T::mul(LHSI, RHSI, Bits, &B))

410 return false;

411 if (T::sub(A, B, Bits, &Result.elem<T>(0)))

412 return false;

413

414

415 if (T::mul(LHSR, RHSI, Bits, &A))

416 return false;

417 if (T::mul(LHSI, RHSR, Bits, &B))

418 return false;

419 if (T::add(A, B, Bits, &Result.elem<T>(1)))

420 return false;

422 Result.initializeAllElements();

423 }

424

425 return true;

426}

427

428template <PrimType Name, class T = typename PrimConv::T>

433

434 if constexpr (std::is_same_v<T, Floating>) {

439

440 APFloat ResR(A.getSemantics());

441 APFloat ResI(A.getSemantics());

443

444

446 RA.copy(ResR);

448

450 RI.copy(ResI);

452

453 Result.initializeAllElements();

454 } else {

455

456 const T &LHSR = LHS.elem<T>(0);

457 const T &LHSI = LHS.elem<T>(1);

458 const T &RHSR = RHS.elem<T>(0);

459 const T &RHSI = RHS.elem<T>(1);

460 unsigned Bits = LHSR.bitWidth();

462

466 S.FFDiag(E, diag::note_expr_divide_by_zero);

467 return false;

468 }

469

470

471 T A, B;

472 if (T::mul(RHSR, RHSR, Bits, &A) || T::mul(RHSI, RHSI, Bits, &B)) {

473

474 }

475 T Den;

476 if (T::add(A, B, Bits, &Den))

477 return false;

478

481 S.FFDiag(E, diag::note_expr_divide_by_zero);

482 return false;

483 }

484

485

486 T &ResultR = Result.elem<T>(0);

487 T &ResultI = Result.elem<T>(1);

488

489 if (T::mul(LHSR, RHSR, Bits, &A) || T::mul(LHSI, RHSI, Bits, &B))

490 return false;

491 if (T::add(A, B, Bits, &ResultR))

492 return false;

493 if (T::div(ResultR, Den, Bits, &ResultR))

494 return false;

495

496

497 if (T::mul(LHSI, RHSR, Bits, &A) || T::mul(LHSR, RHSI, Bits, &B))

498 return false;

499 if (T::sub(A, B, Bits, &ResultI))

500 return false;

501 if (T::div(ResultI, Den, Bits, &ResultI))

502 return false;

503 Result.initializeAllElements();

504 }

505

506 return true;

507}

508

509

510

511

512template <PrimType Name, class T = typename PrimConv::T>

514 const T &RHS = S.Stk.pop<T>();

515 const T &LHS = S.Stk.pop<T>();

516 unsigned Bits = RHS.bitWidth();

517

521

522 if (!T::bitAnd(LHS, RHS, Bits, &Result)) {

524 return true;

525 }

526 return false;

527}

528

529

530

531

532template <PrimType Name, class T = typename PrimConv::T>

534 const T &RHS = S.Stk.pop<T>();

535 const T &LHS = S.Stk.pop<T>();

536 unsigned Bits = RHS.bitWidth();

537

541

542 if (!T::bitOr(LHS, RHS, Bits, &Result)) {

544 return true;

545 }

546 return false;

547}

548

549

550

551

552template <PrimType Name, class T = typename PrimConv::T>

554 const T &RHS = S.Stk.pop<T>();

555 const T &LHS = S.Stk.pop<T>();

556

557 unsigned Bits = RHS.bitWidth();

558

562

563 if (!T::bitXor(LHS, RHS, Bits, &Result)) {

565 return true;

566 }

567 return false;

568}

569

570

571

572

573template <PrimType Name, class T = typename PrimConv::T>

575 const T &RHS = S.Stk.pop<T>();

576 const T &LHS = S.Stk.pop<T>();

577 const unsigned Bits = RHS.bitWidth() * 2;

578

580 return false;

581

585

586 if (!T::rem(LHS, RHS, Bits, &Result)) {

588 return true;

589 }

590 return false;

591}

592

593

594

595

596template <PrimType Name, class T = typename PrimConv::T>

598 const T &RHS = S.Stk.pop<T>();

599 const T &LHS = S.Stk.pop<T>();

600 const unsigned Bits = RHS.bitWidth() * 2;

601

603 return false;

604

608

609 if (!T::div(LHS, RHS, Bits, &Result)) {

611 return true;

612 }

613

614 if constexpr (std::is_same_v<T, FixedPoint>) {

617 return true;

618 }

619 }

620 return false;

621}

622

626

628 return false;

629

631

634

637}

638

639

640

641

642

648

649

650

651

652

653template <PrimType Name, class T = typename PrimConv::T>

656

657 if constexpr (std::is_same_v<T, Floating>) {

659

662 return true;

663 }

664 return false;

665 } else {

669

672 return true;

673 }

674

676 "don't expect other types to fail at constexpr negation");

678

684 NegatedValue.trunc(Result.bitWidth())

685 .toString(Trunc, 10, Result.isSigned(), false,

686 true, true);

687 S.report(E->getExprLoc(), diag::warn_integer_constant_overflow)

689 return true;

690 }

691

693 }

694}

695

704

705template <typename T, IncDecOp Op, PushVal DoPush>

707 bool CanOverflow, UnsignedOrNone BitWidth = std::nullopt) {

709

712 return false;

713 }

714

715 if constexpr (std::is_same_v<T, Boolean>) {

718 }

719

724

727

729 if (!T::increment(Value, &Result) || !CanOverflow) {

730 if (BitWidth)

732 else

734 return true;

735 }

736 } else {

737 if (!T::decrement(Value, &Result) || !CanOverflow) {

738 if (BitWidth)

740 else

742 return true;

743 }

744 }

745 assert(CanOverflow);

746

747

748

749 unsigned Bits = Value.bitWidth() + 1;

752 APResult = ++Value.toAPSInt(Bits);

753 else

754 APResult = --Value.toAPSInt(Bits);

755

756

761 APResult.trunc(Result.bitWidth())

762 .toString(Trunc, 10, Result.isSigned(), false,

763 true, true);

764 S.report(E->getExprLoc(), diag::warn_integer_constant_overflow)

766 return true;

767 }

769}

770

771

772

773

774

775template <PrimType Name, class T = typename PrimConv::T>

779 return false;

780

782 CanOverflow);

783}

784

785template <PrimType Name, class T = typename PrimConv::T>

787 unsigned BitWidth) {

790 return false;

791

793 BitWidth);

794}

795

796

797

798

799template <PrimType Name, class T = typename PrimConv::T>

803 return false;

804

806}

807

808template <PrimType Name, class T = typename PrimConv::T>

810 uint32_t BitWidth) {

813 return false;

814

816 BitWidth);

817}

818

819template <PrimType Name, class T = typename PrimConv::T>

823 return false;

824

826}

827

828template <PrimType Name, class T = typename PrimConv::T>

830 uint32_t BitWidth) {

833 return false;

834

836 BitWidth);

837}

838

839

840

841

842

843template <PrimType Name, class T = typename PrimConv::T>

847 return false;

848

850 CanOverflow);

851}

852template <PrimType Name, class T = typename PrimConv::T>

854 uint32_t BitWidth) {

857 return false;

858

860 BitWidth);

861}

862

863

864

865

866template <PrimType Name, class T = typename PrimConv::T>

870 return false;

871

873}

874

875template <PrimType Name, class T = typename PrimConv::T>

877 uint32_t BitWidth) {

880 return false;

881

883 BitWidth);

884}

885

886template <PrimType Name, class T = typename PrimConv::T>

893

894template <PrimType Name, class T = typename PrimConv::T>

896 uint32_t BitWidth) {

899 return false;

901 BitWidth);

902}

903

904template <IncDecOp Op, PushVal DoPush>

906 uint32_t FPOI) {

909

912

914 llvm::APFloat::opStatus Status;

917 else

919

921

923}

924

928 return false;

929

931}

932

936 return false;

937

939}

940

944 return false;

945

947}

948

952 return false;

953

955}

956

957

958

959template <PrimType Name, class T = typename PrimConv::T>

961 const T &Val = S.Stk.pop<T>();

962

966

967 if (!T::comp(Val, &Result)) {

969 return true;

970 }

971 return false;

972}

973

974

975

976

977

979

980template

982 assert((!std::is_same_v<T, MemberPointer>) &&

983 "Non-equality comparisons on member pointer types should already be "

984 "rejected in Sema.");

986 const T &RHS = S.Stk.pop<T>();

987 const T &LHS = S.Stk.pop<T>();

988 S.Stk.push(BoolT::from(Fn(LHS.compare(RHS))));

989 return true;

990}

991

992template

996

997template <>

1002

1003

1007 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified)

1010 return false;

1011 }

1012

1015 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified)

1018 return false;

1019 }

1020

1021

1022 if (std::optional<std::pair<Pointer, Pointer>> Split =

1024 const FieldDecl *LF = Split->first.getField();

1025 const FieldDecl *RF = Split->second.getField();

1029 diag::note_constexpr_pointer_comparison_differing_access)

1031 }

1032 }

1033

1037 return true;

1038}

1039

1042 return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||

1043 Builtin == Builtin::BI__builtin___NSStringMakeConstantString ||

1044 Builtin == Builtin::BI__builtin_ptrauth_sign_constant ||

1045 Builtin == Builtin::BI__builtin_function_start);

1046}

1047

1050

1051template <>

1056

1057 if (LHS.isZero() && RHS.isZero()) {

1059 return true;

1060 }

1061

1062

1063 for (const auto &P : {LHS, RHS}) {

1064 if (P.isZero())

1065 continue;

1066 if (P.isWeak()) {

1068 S.FFDiag(Loc, diag::note_constexpr_pointer_weak_comparison)

1070 return false;

1071 }

1072 }

1073

1076 return false;

1077 }

1078

1080 S.Stk.push(BoolT::from(Fn(Compare(LHS.getIntegerRepresentation(),

1082 return true;

1083 }

1084

1085

1090 S.FFDiag(Loc, diag::note_constexpr_literal_comparison)

1093 return false;

1094 }

1095 }

1096

1098 size_t A = LHS.computeOffsetForComparison();

1101 return true;

1102 }

1103

1104

1108 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_past_end)

1110 return false;

1111 }

1112 if (RHS.isOnePastEnd() && !LHS.isOnePastEnd() && !LHS.isZero() &&

1113 LHS.getOffset() == 0) {

1115 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_past_end)

1117 return false;

1118 }

1119

1120 bool BothNonNull = !LHS.isZero() && !RHS.isZero();

1121

1122 for (const auto &P : {LHS, RHS}) {

1123 if (P.isZero())

1124 continue;

1125 if (BothNonNull && P.pointsToLiteral()) {

1126 const Expr *E = P.getDeclDesc()->asExpr();

1129 S.FFDiag(Loc, diag::note_constexpr_literal_comparison);

1130 return false;

1131 }

1132 if (const auto *CE = dyn_cast(E);

1135 S.FFDiag(Loc, diag::note_constexpr_opaque_call_comparison)

1137 return false;

1138 }

1139 } else if (BothNonNull && P.isIntegralPointer()) {

1141 S.FFDiag(Loc, diag::note_constexpr_pointer_constant_comparison)

1144 return false;

1145 }

1146 }

1147

1150 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_zero_sized)

1153 return false;

1154 }

1155

1157 return true;

1158}

1159

1160template <>

1165

1166

1167

1168 for (const auto &MP : {LHS, RHS}) {

1169 if (MP.isWeak()) {

1171 S.FFDiag(Loc, diag::note_constexpr_mem_pointer_weak_comparison)

1172 << MP.getMemberFunction();

1173 return false;

1174 }

1175 }

1176

1177

1178

1179

1180 if (LHS.isZero() && RHS.isZero()) {

1182 return true;

1183 }

1184 if (LHS.isZero() || RHS.isZero()) {

1186 return true;

1187 }

1188

1189

1190 for (const auto &MP : {LHS, RHS}) {

1191 if (const CXXMethodDecl *MD = MP.getMemberFunction();

1194 S.CCEDiag(Loc, diag::note_constexpr_compare_virtual_mem_ptr) << MD;

1195 }

1196 }

1197

1199 return true;

1200}

1201

1202template <PrimType Name, class T = typename PrimConv::T>

1208

1209template <PrimType Name, class T = typename PrimConv::T>

1211 const T &RHS = S.Stk.pop<T>();

1212 const T &LHS = S.Stk.pop<T>();

1214

1216 if constexpr (std::is_same_v<T, Pointer>) {

1219 S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified)

1222 return false;

1223 }

1224 }

1225

1226 assert(CmpInfo);

1227 const auto *CmpValueInfo =

1229 assert(CmpValueInfo);

1230 assert(CmpValueInfo->hasValidIntValue());

1232}

1233

1234template <PrimType Name, class T = typename PrimConv::T>

1240

1241template <PrimType Name, class T = typename PrimConv::T>

1247

1248template <PrimType Name, class T = typename PrimConv::T>

1255

1256template <PrimType Name, class T = typename PrimConv::T>

1262

1263template <PrimType Name, class T = typename PrimConv::T>

1270

1271

1272

1273

1274

1275template <PrimType Name, class T = typename PrimConv::T>

1280

1281template <PrimType Name, class T = typename PrimConv::T>

1286

1287

1288template <PrimType TopName, PrimType BottomName>

1292

1293 const auto &Top = S.Stk.pop();

1294 const auto &Bottom = S.Stk.pop();

1295

1297 S.Stk.push(Bottom);

1298

1299 return true;

1300}

1301

1302

1303

1304

1305

1306template <PrimType Name, class T = typename PrimConv::T>

1310 Result.copy(Arg.toAPSInt());

1312 return true;

1313 }

1315 return true;

1316}

1317

1324

1325

1326

1327

1328

1329template <PrimType Name, class T = typename PrimConv::T>

1333 return false;

1335 return true;

1336}

1337

1338bool EndLifetime(InterpState &S, CodePtr OpPC);

1340bool StartLifetime(InterpState &S, CodePtr OpPC);

1341

1342

1343

1344

1345template <PrimType Name, class T = typename PrimConv::T>

1350

1351template <PrimType Name, class T = typename PrimConv::T>

1354 return false;

1355 }

1357 return true;

1358}

1359

1360template <PrimType Name, class T = typename PrimConv::T>

1365

1366

1367

1368template <PrimType Name, class T = typename PrimConv::T>

1372 return false;

1374 return false;

1377 return false;

1378 S.Stk.push<T>(Field.deref<T>());

1379 return true;

1380}

1381

1382template <PrimType Name, class T = typename PrimConv::T>

1387 return false;

1389 return false;

1392 return false;

1394 Field.deref<T>() = Value;

1395 return true;

1396}

1397

1398

1399

1400template <PrimType Name, class T = typename PrimConv::T>

1404 return false;

1406 return false;

1409 return false;

1410 S.Stk.push<T>(Field.deref<T>());

1411 return true;

1412}

1413

1414template <PrimType Name, class T = typename PrimConv::T>

1417 return false;

1419 return false;

1423 return false;

1424 S.Stk.push<T>(Field.deref<T>());

1425 return true;

1426}

1427

1428template <PrimType Name, class T = typename PrimConv::T>

1431 return false;

1433 return false;

1438 return false;

1439 Field.deref<T>() = Value;

1440 return true;

1441}

1442

1443template <PrimType Name, class T = typename PrimConv::T>

1446

1448 return false;

1449

1451 return true;

1452}

1453

1454

1455template <PrimType Name, class T = typename PrimConv::T>

1458 const auto &Desc =

1463

1465 return true;

1466}

1467

1468template <PrimType Name, class T = typename PrimConv::T>

1470

1471 return false;

1472}

1473

1474template <PrimType Name, class T = typename PrimConv::T>

1477

1479

1480 if constexpr (std::is_same_v<T, Floating>) {

1482 if (!Val.singleWord()) {

1483 uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()];

1484 Val.take(NewMemory);

1485 }

1486

1488 auto &Val = P.deref<T>();

1489 if (!Val.singleWord()) {

1490 uint64_t *NewMemory = new (S.P) uint64_t[Val.numWords()];

1491 Val.take(NewMemory);

1492 }

1493 }

1494

1496 return true;

1497}

1498

1499

1500

1501

1502template <PrimType Name, class T = typename PrimConv::T>

1506 return false;

1507 assert(Temp);

1508

1513

1516 return true;

1517}

1518

1519

1520

1521

1525 return false;

1526 assert(Temp);

1527

1531 return true;

1532}

1533

1534template <PrimType Name, class T = typename PrimConv::T>

1537 return false;

1539 return false;

1542 assert(Field.canBeInitialized());

1543 Field.deref<T>() = S.Stk.pop<T>();

1544 Field.initialize();

1545 return true;

1546}

1547

1548template <PrimType Name, class T = typename PrimConv::T>

1551 return false;

1553 return false;

1556 assert(Field.canBeInitialized());

1557 Field.deref<T>() = S.Stk.pop<T>();

1558 Field.activate();

1559 Field.initialize();

1560 return true;

1561}

1562

1563

1564

1565template <PrimType Name, class T = typename PrimConv::T>

1567 uint32_t FieldOffset) {

1568 assert(F->isBitField());

1570 return false;

1572 return false;

1574 const Pointer &Field = This.atField(FieldOffset);

1575 assert(Field.canBeInitialized());

1577 Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue());

1578 Field.initialize();

1579 return true;

1580}

1581

1582template <PrimType Name, class T = typename PrimConv::T>

1584 const Record::Field *F, uint32_t FieldOffset) {

1585 assert(F->isBitField());

1587 return false;

1589 return false;

1591 const Pointer &Field = This.atField(FieldOffset);

1592 assert(Field.canBeInitialized());

1594 Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue());

1595 Field.initialize();

1596 Field.activate();

1597 return true;

1598}

1599

1600

1601

1602

1603template <PrimType Name, class T = typename PrimConv::T>

1608 return false;

1610 return false;

1611

1614 Field.initialize();

1615 return true;

1616}

1617

1618template <PrimType Name, class T = typename PrimConv::T>

1623 return false;

1625 return false;

1626

1629 Field.activate();

1630 Field.initialize();

1631 return true;

1632}

1633

1634template <PrimType Name, class T = typename PrimConv::T>

1636 assert(F->isBitField());

1640 return false;

1642 return false;

1643

1645

1648 if (T::isSigned())

1650 .trunc(F->Decl->getBitWidthValue())

1651 .sextOrTrunc(Value.bitWidth()));

1652 else

1654 .trunc(F->Decl->getBitWidthValue())

1655 .zextOrTrunc(Value.bitWidth()));

1656

1657 Field.deref<T>() = Result;

1658 } else {

1659 Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue());

1660 }

1662 return true;

1663}

1664

1665template <PrimType Name, class T = typename PrimConv::T>

1667 const Record::Field *F) {

1668 assert(F->isBitField());

1672 return false;

1674 return false;

1675

1677

1680 if (T::isSigned())

1682 .trunc(F->Decl->getBitWidthValue())

1683 .sextOrTrunc(Value.bitWidth()));

1684 else

1686 .trunc(F->Decl->getBitWidthValue())

1687 .zextOrTrunc(Value.bitWidth()));

1688

1689 Field.deref<T>() = Result;

1690 } else {

1691 Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue());

1692 }

1694 Field.initialize();

1695 return true;

1696}

1697

1698

1699

1700

1701

1706

1709 return false;

1711 return true;

1712}

1713

1718

1719

1720

1721bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off);

1722bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off);

1723

1726 return false;

1728 return false;

1731 return true;

1732}

1733

1735 bool NullOK, const Type *TargetType) {

1738 return false;

1739

1741

1742

1743

1745 return true;

1746 }

1747

1749 return false;

1751 return false;

1752

1754 assert(TargetRecord);

1755

1760 << MostDerivedType << QualType(TargetType, 0);

1761 return false;

1762 }

1763

1765 return true;

1766}

1767

1771 return false;

1772

1775 return false;

1777 return true;

1778 }

1779

1781 return false;

1783 if (Result.isPastEnd() || Result.isBaseClass())

1784 return false;

1786 return true;

1787}

1788

1790 bool NullOK) {

1792

1794 return false;

1795

1798 return false;

1800 return true;

1801 }

1802

1804 return false;

1806 if (Result.isPastEnd() || Result.isBaseClass())

1807 return false;

1809 return true;

1810}

1811

1817

1820 return false;

1822 return false;

1825 return true;

1826}

1827

1834

1841

1847 }

1848 return true;

1849}

1850

1856 }

1857 return true;

1858}

1859

1861

1866

1869 if (Ptr.isZero()) {

1871 diag::note_constexpr_dereferencing_null);

1873 }

1874 return true;

1875}

1876

1880 while (Base.isBaseClass())

1882

1883 const Record::Base *VirtBase = Base.getRecord()->getVirtualBase(Decl);

1885 return true;

1886}

1887

1890 assert(D);

1893 return false;

1895}

1896

1899 assert(D);

1901 return false;

1903 return false;

1906}

1907

1908

1909

1910

1911

1912template <PrimType Name, class T = typename PrimConv::T>

1916 return false;

1918 return false;

1920 !(D->isPrimitive() || D->isPrimitiveArray()) || D->getPrimType() != Name)

1921 return false;

1923 return true;

1924}

1925

1926template <PrimType Name, class T = typename PrimConv::T>

1930 return false;

1932 return false;

1934 !(D->isPrimitive() || D->isPrimitiveArray()) || D->getPrimType() != Name)

1935 return false;

1937 return true;

1938}

1939

1940template <PrimType Name, class T = typename PrimConv::T>

1945 return false;

1946 if (Ptr.canBeInitialized())

1948 Ptr.deref<T>() = Value;

1949 return true;

1950}

1951

1952template <PrimType Name, class T = typename PrimConv::T>

1957 return false;

1958 if (Ptr.canBeInitialized())

1960 Ptr.deref<T>() = Value;

1961 return true;

1962}

1963

1970

1973 return false;

1975 return false;

1976

1980 return true;

1981}

1982

1983template <PrimType Name, class T = typename PrimConv::T>

1987

1988 if (CheckStore(S, OpPC, Ptr, true))

1989 return false;

1990 if (Ptr.canBeInitialized()) {

1991 Ptr.initialize();

1992 Ptr.activate();

1993 }

1995 return true;

1996}

1997

1998template <PrimType Name, class T = typename PrimConv::T>

2002

2003 if (CheckStore(S, OpPC, Ptr, true))

2004 return false;

2005 if (Ptr.canBeInitialized()) {

2006 Ptr.initialize();

2007 Ptr.activate();

2008 }

2010 return true;

2011}

2012

2013template <PrimType Name, class T = typename PrimConv::T>

2017

2018 if (CheckStore(S, OpPC, Ptr, true))

2019 return false;

2020 if (Ptr.canBeInitialized())

2022 if (const auto *FD = Ptr.getField())

2023 Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());

2024 else

2025 Ptr.deref<T>() = Value;

2026 return true;

2027}

2028

2029template <PrimType Name, class T = typename PrimConv::T>

2034 return false;

2035 if (Ptr.canBeInitialized())

2037 if (const auto *FD = Ptr.getField())

2038 Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());

2039 else

2040 Ptr.deref<T>() = Value;

2041 return true;

2042}

2043

2044template <PrimType Name, class T = typename PrimConv::T>

2048

2049 if (CheckStore(S, OpPC, Ptr, true))

2050 return false;

2051 if (Ptr.canBeInitialized()) {

2052 Ptr.initialize();

2053 Ptr.activate();

2054 }

2055 if (const auto *FD = Ptr.getField())

2056 Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());

2057 else

2058 Ptr.deref<T>() = Value;

2059 return true;

2060}

2061

2062template <PrimType Name, class T = typename PrimConv::T>

2066

2067 if (CheckStore(S, OpPC, Ptr, true))

2068 return false;

2069 if (Ptr.canBeInitialized()) {

2070 Ptr.initialize();

2071 Ptr.activate();

2072 }

2073 if (const auto *FD = Ptr.getField())

2074 Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());

2075 else

2076 Ptr.deref<T>() = Value;

2077 return true;

2078}

2079

2080template <PrimType Name, class T = typename PrimConv::T>

2085 return false;

2087 new (&Ptr.deref<T>()) T(Value);

2088 return true;

2089}

2090

2091template <PrimType Name, class T = typename PrimConv::T>

2096 return false;

2098 new (&Ptr.deref<T>()) T(Value);

2099 return true;

2100}

2101

2102

2103

2104

2105template <PrimType Name, class T = typename PrimConv::T>

2109

2110 const Descriptor *Desc = Ptr.getFieldDesc();

2111 if (Desc->isUnknownSizeArray())

2112 return false;

2113

2114

2115

2116 if (Idx == 0 && !Desc->isArray()) {

2117 Ptr.initialize();

2118 new (&Ptr.deref<T>()) T(Value);

2119 return true;

2120 }

2121

2123 return false;

2124 if (Idx >= Desc->getNumElems()) {

2125

2128 S.FFDiag(Loc, diag::note_constexpr_access_past_end)

2130 }

2131 return false;

2132 }

2133 Ptr.initializeElement(Idx);

2134 new (&Ptr.elem<T>(Idx)) T(Value);

2135 return true;

2136}

2137

2138

2139template <PrimType Name, class T = typename PrimConv::T>

2143

2144 const Descriptor *Desc = Ptr.getFieldDesc();

2145 if (Desc->isUnknownSizeArray())

2146 return false;

2147

2148

2149

2150 if (Idx == 0 && !Desc->isArray()) {

2151 Ptr.initialize();

2152 new (&Ptr.deref<T>()) T(Value);

2153 return true;

2154 }

2155

2157 return false;

2158 if (Idx >= Desc->getNumElems()) {

2159

2162 S.FFDiag(Loc, diag::note_constexpr_access_past_end)

2164 }

2165 return false;

2166 }

2167 Ptr.initializeElement(Idx);

2168 new (&Ptr.elem<T>(Idx)) T(Value);

2169 return true;

2170}

2171

2175

2177 return false;

2178

2179 return DoMemcpy(S, OpPC, Src, Dest);

2180}

2181

2185

2187 return true;

2188}

2189

2192

2193 if (std::optional Ptr = MP.toPointer(S.Ctx)) {

2195 return true;

2196 }

2197 return Invalid(S, OpPC);

2198}

2199

2200

2201

2202

2203

2204template <class T, ArithOp Op>

2206 const T &Offset, const Pointer &Ptr,

2207 bool IsPointerArith = false) {

2208

2209 if (Offset.isZero())

2210 return Ptr;

2211

2213

2214

2216 return std::nullopt;

2217 }

2218

2219

2221 return std::nullopt;

2222

2223

2226 uint64_t O = static_cast<uint64_t>(Offset) * Ptr.elemSize();

2229 else

2232 uint64_t O = static_cast<uint64_t>(Offset);

2233 uint64_t N;

2236 else

2238

2239 if (N > 1)

2241 << N << true << 0;

2244 return std::nullopt;

2245 }

2246

2248

2249 uint64_t MaxIndex = static_cast<uint64_t>(Ptr.getNumElems());

2250 uint64_t Index;

2252 Index = MaxIndex;

2253 else

2255

2257

2258 auto DiagInvalidOffset = [&]() -> void {

2259 const unsigned Bits = Offset.bitWidth();

2260 APSInt APOffset(Offset.toAPSInt().extend(Bits + 2), false);

2261 APSInt APIndex(APInt(Bits + 2, Index, true),

2262 false);

2264 (Op == ArithOp::Add) ? (APIndex + APOffset) : (APIndex - APOffset);

2266 << NewIndex << static_cast<int>(!Ptr.inArray()) << MaxIndex;

2268 };

2269

2271 uint64_t IOffset = static_cast<uint64_t>(Offset);

2272 uint64_t MaxOffset = MaxIndex - Index;

2273

2275

2276 if (Offset.isNegative() && (Offset.isMin() || -IOffset > Index))

2277 DiagInvalidOffset();

2278

2279

2280 if (Offset.isPositive() && IOffset > MaxOffset)

2281 DiagInvalidOffset();

2282 } else {

2283

2284 if (Offset.isPositive() && Index < IOffset)

2285 DiagInvalidOffset();

2286

2287

2288 if (Offset.isNegative() && (Offset.isMin() || -IOffset > MaxOffset))

2289 DiagInvalidOffset();

2290 }

2291 }

2292

2294 return std::nullopt;

2295

2296

2297 int64_t WideIndex = static_cast<int64_t>(Index);

2298 int64_t WideOffset = static_cast<int64_t>(Offset);

2301 Result = WideIndex + WideOffset;

2302 else

2303 Result = WideIndex - WideOffset;

2304

2305

2306

2307

2312 }

2313

2314 return Ptr.atIndex(static_cast<uint64_t>(Result));

2315}

2316

2317template <PrimType Name, class T = typename PrimConv::T>

2319 const T &Offset = S.Stk.pop<T>();

2321

2323 S, OpPC, Offset, Ptr, true)) {

2325 return true;

2326 }

2327 return false;

2328}

2329

2330template <PrimType Name, class T = typename PrimConv::T>

2332 const T &Offset = S.Stk.pop<T>();

2334

2336 S, OpPC, Offset, Ptr, true)) {

2338 return true;

2339 }

2340 return false;

2341}

2342

2343template

2347 return false;

2348

2350

2353 return false;

2354

2355

2357

2358

2359 OneT One = OneT::from(1);

2360 if (std::optional Result =

2362

2364 return true;

2365 }

2366 return false;

2367}

2368

2377

2386

2387

2388

2389

2390template <PrimType Name, class T = typename PrimConv::T>

2394

2397 diag::note_constexpr_pointer_arith_unspecified)

2400 return false;

2401 }

2402

2403 if (ElemSizeIsZero) {

2405 while (auto *AT = dyn_cast(PtrT))

2406 PtrT = AT->getElementType();

2407

2411 diag::note_constexpr_pointer_subtraction_zero_size)

2412 << ArrayTy;

2413

2414 return false;

2415 }

2416

2417 if (LHS == RHS) {

2419 return true;

2420 }

2421

2422 int64_t A64 =

2426

2427 int64_t B64 =

2431

2432 int64_t R64 = A64 - B64;

2433 if (static_cast<int64_t>(T::from(R64)) != R64)

2435

2436 S.Stk.push<T>(T::from(R64));

2437 return true;

2438}

2439

2440

2441

2442

2443

2446

2447

2448

2451

2453

2456 S.FFDiag(ND->getLocation(),

2457 diag::note_constexpr_destroy_out_of_lifetime)

2458 << ND->getNameAsString();

2459 } else {

2461 diag::note_constexpr_destroy_out_of_lifetime)

2463 }

2464 return false;

2465 }

2466 }

2467

2469 return true;

2470}

2471

2476

2482

2488

2489

2490

2491

2492

2499

2500

2501

2503 llvm::RoundingMode RM) {

2508 return true;

2509}

2510

2513 FixedPointSemantics::getFromOpaqueInt(FPS);

2515

2516 bool Overflow;

2517 FixedPoint Result = Source.toSemantics(TargetSemantics, &Overflow);

2518

2520 return false;

2521

2523 return true;

2524}

2525

2526

2527

2528template <PrimType Name, class T = typename PrimConv::T>

2531

2532 {

2533 APInt Source = S.Stk.pop<T>().toAPSInt().extOrTrunc(BitWidth);

2534 Result.copy(Source);

2535 }

2537 return true;

2538}

2539

2540template <PrimType Name, class T = typename PrimConv::T>

2543

2544 {

2545 APInt Source = S.Stk.pop<T>().toAPSInt().extOrTrunc(BitWidth);

2546 Result.copy(Source);

2547 }

2549 return true;

2550}

2551

2552template <PrimType Name, class T = typename PrimConv::T>

2554 const llvm::fltSemantics *Sem, uint32_t FPOI) {

2555 const T &From = S.Stk.pop<T>();

2556 APSInt FromAP = From.toAPSInt();

2557

2560 auto Status =

2563

2565}

2566

2567template <PrimType Name, class T = typename PrimConv::T>

2570

2571 if constexpr (std::is_same_v<T, Boolean>) {

2573 return true;

2574 } else {

2576 !T::isSigned());

2578

2579

2580 if ((Status & APFloat::opStatus::opInvalidOp)) {

2583

2587 return true;

2588 }

2589 return false;

2590 }

2591

2595 }

2596}

2597

2599 uint32_t BitWidth, uint32_t FPOI) {

2601

2602 APSInt Result(BitWidth, true);

2604

2605

2606 if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite())

2608

2610

2613

2615

2617}

2618

2620 uint32_t BitWidth, uint32_t FPOI) {

2622

2623 APSInt Result(BitWidth, false);

2625

2626

2627 if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite())

2629

2631

2634

2636

2638}

2639

2641 const Pointer &Ptr, unsigned BitWidth);

2644

2645template <PrimType Name, class T = typename PrimConv::T>

2648

2650 return Invalid(S, OpPC);

2651

2653 return true;

2654}

2655

2656template <PrimType Name, class T = typename PrimConv::T>

2658 uint32_t FPS) {

2660

2662

2663 bool Overflow;

2665

2667 return false;

2668

2670 return true;

2671}

2672

2674 uint32_t FPS) {

2676

2678

2679 bool Overflow;

2681

2683 return false;

2684

2686 return true;

2687}

2688

2690 const llvm::fltSemantics *Sem) {

2693 Result.copy(Fixed.toFloat(Sem));

2695 return true;

2696}

2697

2698template <PrimType Name, class T = typename PrimConv::T>

2701

2702 bool Overflow;

2703 APSInt Int = Fixed.toInt(T::bitWidth(), T::isSigned(), &Overflow);

2704

2706 return false;

2707

2709 return true;

2710}

2711

2714 S.CCEDiag(E, diag::note_constexpr_invalid_cast)

2715 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret

2717 return true;

2718}

2719

2722

2723 if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {

2724 bool HasValidResult = !Ptr.isZero();

2725

2726 if (HasValidResult) {

2728 return true;

2729

2733 E->getType()->getPointeeType()))

2734 return true;

2735

2736 S.CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)

2737 << E->getSubExpr()->getType() << S.getLangOpts().CPlusPlus26

2738 << Ptr.getType().getCanonicalType() << E->getType()->getPointeeType();

2739 } else if (!S.getLangOpts().CPlusPlus26) {

2741 S.CCEDiag(E, diag::note_constexpr_invalid_cast)

2742 << diag::ConstexprInvalidCastKind::CastFrom << "'void *'"

2744 }

2745 } else {

2747 S.CCEDiag(E, diag::note_constexpr_invalid_cast)

2748 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret

2750 }

2751

2752 return true;

2753}

2754

2755

2756

2757

2758

2759template <PrimType Name, class T = typename PrimConv::T>

2764

2767 if (Result.singleWord())

2768 std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t));

2770 return true;

2771}

2772

2775 if (Result.singleWord())

2776 std::memset(Result.Memory, 0, Result.numWords() * sizeof(uint64_t));

2778 return true;

2779}

2780

2781template <PrimType Name, class T = typename PrimConv::T>

2784

2785

2787 return true;

2788}

2789

2790template <PrimType Name, class T = typename PrimConv::T>

2792 const auto &P = S.Stk.pop<T>();

2793 if (P.isWeak())

2794 return false;

2796 return true;

2797}

2798

2799

2800

2801

2802

2804

2806 return false;

2808 return false;

2810

2811

2812 if (This.isDummy()) {

2814 if (This.isTypeidPointer()) {

2815 [[maybe_unused]] const Record *R = This.getRecord();

2816 if (!R)

2817 R = This.narrow().getRecord();

2818 assert(R);

2821 ->getParent());

2822 }

2823 }

2824

2826 return true;

2827}

2828

2832 return false;

2834 return true;

2835}

2836

2837

2838

2839

2840

2841template <class LT, class RT, ShiftDir Dir>

2845 const unsigned Bits = LHS.bitWidth();

2846

2847

2849 RT::bitAnd(RHS, RT::from(LHS.bitWidth() - 1, RHS.bitWidth()),

2850 RHS.bitWidth(), &RHS);

2851

2852 if (RHS.isNegative()) {

2853

2854

2856 S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt();

2858 return false;

2859 RHS = -RHS;

2862 S, OpPC, LHS, RHS, Result);

2863 }

2864

2866 return false;

2867

2868

2869

2870

2871

2872

2873

2874 typename LT::AsUnsigned R;

2875 unsigned MaxShiftAmount = LHS.bitWidth() - 1;

2877 if (Compare(RHS, RT::from(MaxShiftAmount, RHS.bitWidth())) ==

2879 if (LHS.isNegative())

2880 R = LT::AsUnsigned::zero(LHS.bitWidth());

2881 else {

2882 RHS = RT::from(LHS.countLeadingZeros(), RHS.bitWidth());

2883 LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS),

2884 LT::AsUnsigned::from(RHS, Bits), Bits, &R);

2885 }

2886 } else if (LHS.isNegative()) {

2887 if (LHS.isMin()) {

2888 R = LT::AsUnsigned::zero(LHS.bitWidth());

2889 } else {

2890

2891 typename LT::AsUnsigned LHSU = LT::AsUnsigned::from(-LHS);

2892 LT::AsUnsigned::shiftLeft(LHSU, LT::AsUnsigned::from(RHS, Bits), Bits,

2893 &R);

2894 R = -R;

2895 }

2896 } else {

2897

2898 LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS),

2899 LT::AsUnsigned::from(RHS, Bits), Bits, &R);

2900 }

2902 return true;

2903 }

2904

2905

2906 if (Compare(RHS, RT::from(MaxShiftAmount, RHS.bitWidth())) ==

2908 R = LT::AsUnsigned::from(-1);

2909 } else {

2910

2911 LT A;

2912 LT::shiftRight(LHS, LT::from(RHS, Bits), Bits, &A);

2913 R = LT::AsUnsigned::from(A);

2914 }

2915

2917 return true;

2918}

2919

2920

2921template <class LT, class RT, ShiftDir Dir>

2924 const unsigned Bits = LHS.getBitWidth();

2925

2926

2928 RHS &=

2929 APSInt(llvm::APInt(RHS.getBitWidth(), static_cast<uint64_t>(Bits - 1)),

2930 RHS.isUnsigned());

2931

2932 if (RHS.isNegative()) {

2933

2934

2936 S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS;

2938 return false;

2941 S, OpPC, LHS, -RHS, Result);

2942 }

2943

2944 if (CheckShift<Dir>(S, OpPC, static_cast<LT>(LHS), static_cast<RT>(RHS),

2946 return false;

2947

2948 unsigned SA = (unsigned)RHS.getLimitedValue(Bits - 1);

2951 Result->copy(LHS << SA);

2952 else

2954 } else {

2956 Result->copy(LHS >> SA);

2957 else

2959 }

2960

2962 return true;

2963}

2964

2965template <PrimType NameL, PrimType NameR>

2969 auto RHS = S.Stk.pop();

2971

2977 RHS.toAPSInt(), &Result);

2978 } else {

2981 }

2982}

2983

2984template <PrimType NameL, PrimType NameR>

2988 auto RHS = S.Stk.pop();

2990

2996 RHS.toAPSInt(), &Result);

2997 } else {

3000 }

3001}

3002

3006 llvm::FixedPointSemantics LHSSema = LHS.getSemantics();

3007

3008 unsigned ShiftBitWidth =

3009 LHSSema.getWidth() - (unsigned)LHSSema.hasUnsignedPadding() - 1;

3010

3011

3012

3013

3014 if (RHS.isNegative()) {

3016 << RHS.toAPSInt();

3017 } else if (static_cast<unsigned>(RHS.toAPSInt().getLimitedValue(

3018 ShiftBitWidth)) != RHS.toAPSInt()) {

3020 S.CCEDiag(E, diag::note_constexpr_large_shift)

3021 << RHS.toAPSInt() << E->getType() << ShiftBitWidth;

3022 }

3023

3028 return false;

3029 } else {

3032 return false;

3033 }

3034

3036 return true;

3037}

3038

3039

3040

3041

3042

3045 S.FFDiag(EndLoc, diag::note_constexpr_no_return);

3046 return false;

3047}

3048

3049

3050

3051

3052

3058

3063 else

3065 return true;

3066}

3067

3068

3069

3070

3071

3072

3073

3074

3075

3076template <PrimType Name, class T = typename PrimConv::T>

3078 const T &Offset = S.Stk.pop<T>();

3080

3081 if (!Ptr.isZero() && !Offset.isZero()) {

3083 return false;

3084 }

3085

3086 if (Offset.isZero()) {

3087 if (const Descriptor *Desc = Ptr.getFieldDesc();

3088 Desc && Desc->isArray() && Ptr.getIndex() == 0) {

3090 return true;

3091 }

3093 return true;

3094 }

3095

3096 assert(!Offset.isZero());

3097

3098 if (std::optional Result =

3101 return true;

3102 }

3103

3104 return false;

3105}

3106

3107template <PrimType Name, class T = typename PrimConv::T>

3109 const T &Offset = S.Stk.pop<T>();

3111

3112 if (!Ptr.isZero() && !Offset.isZero()) {

3114 return false;

3115 }

3116

3117 if (Offset.isZero()) {

3118 if (const Descriptor *Desc = Ptr.getFieldDesc();

3119 Desc && Desc->isArray() && Ptr.getIndex() == 0) {

3121 return true;

3122 }

3124 return true;

3125 }

3126

3127 assert(!Offset.isZero());

3128

3129 if (std::optional Result =

3132 return true;

3133 }

3134 return false;

3135}

3136

3137template <PrimType Name, class T = typename PrimConv::T>

3140

3142 return false;

3143

3146 return true;

3147}

3148

3149template <PrimType Name, class T = typename PrimConv::T>

3152

3154 return false;

3155

3158 return true;

3159}

3160

3161template <PrimType Name, class T = typename PrimConv::T>

3163 uint32_t DestIndex, uint32_t Size) {

3166

3167 if (SrcPtr.isDummy() || DestPtr.isDummy())

3168 return false;

3169

3170 for (uint32_t I = 0; I != Size; ++I) {

3172

3174 return false;

3175

3176 DestPtr.elem<T>(DestIndex + I) = SrcPtr.elem<T>(SrcIndex + I);

3178 }

3179 return true;

3180}

3181

3182

3183

3186

3189 return true;

3190 }

3191

3194 return false;

3195 }

3196

3199 return true;

3200 }

3201

3203 S.FFDiag(E, diag::note_constexpr_unsupported_unsized_array);

3204

3205 return false;

3206}

3207

3209 assert(Func);

3211 return true;

3212}

3213

3214template <PrimType Name, class T = typename PrimConv::T>

3216 const T &IntVal = S.Stk.pop<T>();

3217

3219 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret

3221

3222 S.Stk.push<Pointer>(static_cast<uint64_t>(IntVal), Desc);

3223 return true;

3224}

3225

3230

3233

3234 if (!MP.isBaseCastPossible())

3235 return false;

3236

3238 return true;

3239}

3240

3243

3246

3248 return true;

3249}

3250

3251

3252

3253

3256 S.FFDiag(Loc, diag::note_constexpr_stmt_expr_unsupported)

3258 return false;

3259}

3260

3264 return true;

3265

3269 return true;

3270}

3277 }

3278 return true;

3279}

3280

3289

3290

3292

3296

3298 bool SrcIsVoidPtr) {

3300 if (Ptr.isZero())

3301 return true;

3302 if (!Ptr.isBlockPointer())

3303 return true;

3304

3306 return true;

3307

3308 if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {

3309 bool HasValidResult = !Ptr.isZero();

3310

3311 if (HasValidResult) {

3313 return true;

3314

3319 return true;

3320

3321 S.CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)

3322 << E->getSubExpr()->getType() << S.getLangOpts().CPlusPlus26

3323 << Ptr.getType().getCanonicalType() << E->getType()->getPointeeType();

3324 } else if (!S.getLangOpts().CPlusPlus26) {

3326 S.CCEDiag(E, diag::note_constexpr_invalid_cast)

3327 << diag::ConstexprInvalidCastKind::CastFrom << "'void *'"

3329 }

3330 }

3331

3332 QualType PtrType = Ptr.getType();

3336 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret

3338 return false;

3339 }

3340 return true;

3341}

3342

3343

3345 bool Fatal) {

3347

3348 switch (Kind) {

3350 S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)

3351 << diag::ConstexprInvalidCastKind::Reinterpret

3353 return !Fatal;

3355 S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)

3356 << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret

3358 return !Fatal;

3363 S.FFDiag(E, diag::note_constexpr_access_volatile_type)

3364 << AK_Read << E->getSubExpr()->getType();

3365 else

3367 }

3368

3369 return false;

3372 S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)

3373 << diag::ConstexprInvalidCastKind::Dynamic;

3374 return true;

3375 }

3376 llvm_unreachable("Unhandled CastKind");

3377 return false;

3378}

3379

3384 diag::note_constexpr_access_volatile_type)

3386 } else {

3388 }

3389 return false;

3390}

3391

3394 assert(DR);

3395

3399 S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;

3400 S.Note(VD->getLocation(), diag::note_declared_at);

3401 return false;

3402 }

3403

3405}

3406

3411 S.CCEDiag(E, diag::note_constexpr_non_const_vectorelements) << ArgRange;

3412 }

3413 return false;

3414}

3415

3419 diag::note_constexpr_pseudo_destructor);

3420 return true;

3421}

3422

3425

3426 if (Val)

3427 return true;

3428

3429

3431 S.CCEDiag(Loc, diag::note_constexpr_assumption_failed);

3432 return false;

3433}

3434

3435template <PrimType Name, class T = typename PrimConv::T>

3439 ArrayIndices.emplace_back(S.Stk.pop<int64_t>());

3440

3443 return false;

3444

3446

3447 return true;

3448}

3449

3450template <PrimType Name, class T = typename PrimConv::T>

3453 if (!Arg.isZero())

3454 return true;

3455

3457 S.CCEDiag(Loc, diag::note_non_null_attribute_failed);

3458

3459 return false;

3460}

3461

3463 const APSInt &Value);

3464

3465template <PrimType Name, class T = typename PrimConv::T>

3467 assert(ED);

3469

3473 }

3474 return true;

3475}

3476

3477

3478template <PrimType TIn, PrimType TOut>

3483

3484 const FromT &OldPtr = S.Stk.pop();

3485

3486 if constexpr (std::is_same_v<FromT, FunctionPointer> &&

3487 std::is_same_v<ToT, Pointer>) {

3488 S.Stk.push<Pointer>(OldPtr.getFunction(), OldPtr.getOffset());

3489 return true;

3490 } else if constexpr (std::is_same_v<FromT, Pointer> &&

3491 std::is_same_v<ToT, FunctionPointer>) {

3492 if (OldPtr.isFunctionPointer()) {

3494 OldPtr.getByteOffset());

3495 return true;

3496 }

3497 }

3498

3499 S.Stk.push(ToT(OldPtr.getIntegerRepresentation(), nullptr));

3500 return true;

3501}

3502

3504

3505

3506

3507

3509 VD->isStaticLocal());

3510

3512 return true;

3513

3517 return false;

3518 }

3519 return true;

3520}

3521

3523 assert(Desc);

3524

3526 return false;

3527

3531 assert(B);

3533 return true;

3534}

3535

3536template <PrimType Name, class SizeT = typename PrimConv::T>

3538 bool IsNoThrow) {

3540 return false;

3541

3544 if (!IsNoThrow)

3545 return false;

3546

3547

3549 return true;

3550 }

3551 if (NumElements.isNegative()) {

3552 if (!IsNoThrow) {

3554 << NumElements.toDiagnosticString(S.getASTContext());

3555 return false;

3556 }

3558 return true;

3559 }

3560

3561 if (CheckArraySize(S, OpPC, static_cast<uint64_t>(NumElements)))

3562 return false;

3563

3566 Allocator.allocate(Source, T, static_cast<size_t>(NumElements),

3568 assert(B);

3569 if (NumElements.isZero())

3571 else

3573 return true;

3574}

3575

3576template <PrimType Name, class SizeT = typename PrimConv::T>

3578 bool IsNoThrow) {

3580 return false;

3581

3582 if (!ElementDesc)

3583 return false;

3584

3587 IsNoThrow)) {

3588 if (!IsNoThrow)

3589 return false;

3590

3591

3593 return true;

3594 }

3595 assert(NumElements.isPositive());

3596

3597 if (CheckArraySize(S, OpPC, static_cast<uint64_t>(NumElements)))

3598 return false;

3599

3602 Allocator.allocate(ElementDesc, static_cast<size_t>(NumElements),

3604 assert(B);

3605 if (NumElements.isZero())

3607 else

3609

3610 return true;

3611}

3612

3613bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm,

3614 bool IsGlobalDelete);

3615

3620

3624

3625

3626

3628 std::optional<uint64_t> ArraySize = std::nullopt);

3629

3630template <PrimType Name, class T = typename PrimConv::T>

3632 const auto &Size = S.Stk.pop<T>();

3634}

3636

3637template <PrimType Name, class T = typename PrimConv::T>

3639 uint32_t ResultBitWidth, const llvm::fltSemantics *Sem,

3640 const Type *TargetType) {

3642

3643 if (CheckLoad(S, OpPC, FromPtr))

3644 return false;

3645

3646 if constexpr (std::is_same_v<T, Pointer>) {

3649 diag::note_constexpr_bit_cast_invalid_type)

3650 << true << false << 1 ;

3651 return false;

3652 }

3653

3655 return true;

3656 } else if constexpr (std::is_same_v<T, MemberPointer>) {

3658 diag::note_constexpr_bit_cast_invalid_type)

3659 << true << false << 2 ;

3660 return false;

3661 } else {

3662

3663 size_t BuffSize = ResultBitWidth / 8;

3665 bool HasIndeterminateBits = false;

3666

3667 Bits FullBitWidth(ResultBitWidth);

3668 Bits BitWidth = FullBitWidth;

3669

3670 if constexpr (std::is_same_v<T, Floating>) {

3671 assert(Sem);

3672 BitWidth = Bits(llvm::APFloatBase::getSizeInBits(*Sem));

3673 }

3674

3675 if (DoBitCast(S, OpPC, FromPtr, Buff.data(), BitWidth, FullBitWidth,

3676 HasIndeterminateBits))

3677 return false;

3678

3679 if (CheckBitCast(S, OpPC, HasIndeterminateBits, TargetIsUCharOrByte))

3680 return false;

3681

3682 if constexpr (std::is_same_v<T, Floating>) {

3683 assert(Sem);

3689 T::bitcastFromMemory(Buff.data(), ResultBitWidth, &Result);

3691 } else if constexpr (std::is_same_v<T, Boolean>) {

3692

3693

3694 assert(FullBitWidth.getQuantity() == 8);

3695 auto Val = static_cast<unsigned int>(Buff[0]);

3696 if (Val > 1) {

3698 diag::note_constexpr_bit_cast_unrepresentable_value)

3700 return false;

3701 }

3702 S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth));

3703 } else {

3704 assert(!Sem);

3705 S.Stk.push<T>(T::bitcastFromMemory(Buff.data(), ResultBitWidth));

3706 }

3707 return true;

3708 }

3709}

3710

3714

3715 if (CheckLoad(S, OpPC, FromPtr))

3716 return false;

3717

3719 return false;

3720

3721 return true;

3722}

3723

3724

3725bool GetTypeid(InterpState &S, CodePtr OpPC, const Type *TypePtr,

3726 const Type *TypeInfoType);

3727bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType);

3728bool DiagTypeid(InterpState &S, CodePtr OpPC);

3729

3734

3735

3736

3737

3738

3740 if constexpr (std::is_pointer::value) {

3741 uint32_t ID = OpPC.read<uint32_t>();

3743 } else {

3744 return OpPC.read<T>();

3745 }

3746}

3747

3749 auto &Semantics =

3751

3754 OpPC += align(F.bytesToSerialize());

3755 return F;

3756}

3757

3758template <>

3760 CodePtr &OpPC) {

3762 auto Result = S.allocAP<IntegralAP>(BitWidth);

3763 assert(Result.bitWidth() == BitWidth);

3764

3766 OpPC += align(Result.bytesToSerialize());

3768}

3769

3770template <>

3772 CodePtr &OpPC) {

3774 auto Result = S.allocAP<IntegralAP>(BitWidth);

3775 assert(Result.bitWidth() == BitWidth);

3776

3778 OpPC += align(Result.bytesToSerialize());

3779 return Result;

3780}

3781

3782template <>

3788

3789}

3790}

3791

3792#endif

Defines the clang::ASTContext interface.

void HandleComplexComplexDiv(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)

void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D, APFloat &ResR, APFloat &ResI)

QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const

Return the unique reference to the type for a constant array of the specified element type.

bool hasSimilarType(QualType T1, QualType T2) const

Determine if two types are similar, according to the C++ rules.

Represents a static or instance method of a struct/union/class.

CXXRecordDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

unsigned getBuiltinCallee() const

getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.

const ValueInfo * getValueInfo(ComparisonCategoryResult ValueKind) const

ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const

Converts the specified result kind into the correct result kind for this category.

A reference to a declared variable, function, enum, etc.

Decl - This represents one declaration (or definition), e.g.

SourceLocation getEndLoc() const LLVM_READONLY

SourceLocation getLocation() const

AccessSpecifier getAccess() const

bool isFixed() const

Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...

This represents one expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

static FPOptions getFromOpaqueInt(storage_type Value)

Represents a member of a struct/union/class.

const RecordDecl * getParent() const

Returns the parent of this field declaration, which is the struct in which this field is defined.

Represents a function declaration or definition.

Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...

OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...

unsigned getNumExpressions() const

A (possibly-)qualified type.

QualType withVolatile() const

Represents a struct/union/class.

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

TagDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

bool isNullPtrType() const

bool isRecordType() const

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

bool isStaticLocal() const

Returns true if a variable with function scope is a static local variable.

ThreadStorageClassSpecifier getTSCSpec() const

bool isLocalVarDecl() const

Returns true for local variable declarations other than parameters.

bool isUsableInConstantExpressions(const ASTContext &C) const

Determine whether this variable's value can be used in a constant expression, according to the releva...

A memory block, either on the stack or in the heap.

bool isExtern() const

Checks if the block is extern.

const Descriptor * getDescriptor() const

Returns the block's descriptor.

std::byte * rawData()

Returns a pointer to the raw data, including metadata.

Wrapper around boolean types.

static Boolean from(T Value)

Pointer into the code segment.

std::enable_if_t<!std::is_pointer< T >::value, T > read()

Reads data and advances the pointer.

const Function * getOrCreateFunction(const FunctionDecl *FuncDecl)

unsigned getEvalID() const

Manages dynamic memory allocations done during bytecode interpretation.

Block * allocate(const Descriptor *D, unsigned EvalID, Form AllocForm)

Allocate ONE element of the given descriptor.

Wrapper around fixed point types.

llvm::FixedPointSemantics getSemantics() const

static bool shiftRight(const FixedPoint A, const FixedPoint B, unsigned OpBits, FixedPoint *R)

static FixedPoint deserialize(const std::byte *Buff)

static bool shiftLeft(const FixedPoint A, const FixedPoint B, unsigned OpBits, FixedPoint *R)

static FixedPoint from(const APSInt &I, llvm::FixedPointSemantics Sem, bool *Overflow)

size_t bytesToSerialize() const

If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.

static APFloat::opStatus div(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)

static llvm::APFloatBase::Semantics deserializeSemantics(const std::byte *Buff)

void copy(const APFloat &F)

static APFloat::opStatus fromIntegral(APSInt Val, const llvm::fltSemantics &Sem, llvm::RoundingMode RM, Floating *Result)

static APFloat::opStatus sub(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)

static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM, Floating *R)

static APFloat::opStatus add(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)

static void deserialize(const std::byte *Buff, Floating *Result)

static APFloat::opStatus mul(const Floating &A, const Floating &B, llvm::RoundingMode RM, Floating *R)

void toSemantics(const llvm::fltSemantics *Sem, llvm::RoundingMode RM, Floating *Result) const

const llvm::fltSemantics & getSemantics() const

static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM, Floating *R)

APFloat::opStatus convertToInteger(APSInt &Result) const

static void bitcastFromMemory(const std::byte *Buff, const llvm::fltSemantics &Sem, Floating *Result)

APFloat getAPFloat() const

const Function * getFunction() const

Scope & getScope(unsigned Idx)

Returns a specific scope.

const FunctionDecl * getDecl() const

Returns the original FunctionDecl.

bool hasRVO() const

Checks if the first argument is a RVO pointer.

If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.

static uint32_t deserializeSize(const std::byte *Buff)

static void deserialize(const std::byte *Buff, IntegralAP< Signed > *Result)

void copy(const APInt &V)

Wrapper around numeric types.

Frame storing local variables.

static void free(InterpFrame *F)

const Expr * getExpr(CodePtr PC) const

bool isLocalEnabled(unsigned Idx) const

InterpFrame * Caller

The frame of the previous function.

SourceInfo getSource(CodePtr PC) const

Map a location to a source.

CodePtr getRetPC() const

Returns the return address of the frame.

void enableLocal(unsigned Idx)

Block * getLocalBlock(unsigned Offset) const

SourceLocation getLocation(CodePtr PC) const

const Pointer & getThis() const

Returns the 'this' pointer.

const Function * getFunction() const

Returns the current function.

size_t getFrameOffset() const

Returns the offset on the stack at which the frame starts.

SourceRange getRange(CodePtr PC) const

void setLocal(unsigned Offset, const T &Value)

Mutates a local variable.

const T & getParam(unsigned Offset) const

Returns the value of an argument.

bool isBottomFrame() const

bool hasThisPointer() const

Pointer getLocalPointer(unsigned Offset) const

Returns a pointer to a local variables.

unsigned getDepth() const

void setParam(unsigned Offset, const T &Value)

Mutates a local copy of a parameter.

void destroy(unsigned Idx)

Invokes the destructors for a scope.

const Pointer & getRVOPtr() const

Returns the RVO pointer, if the Function has one.

Pointer getParamPointer(unsigned Offset)

Returns a pointer to an argument - lazily creates a block.

const FunctionDecl * getCallee() const override

Returns the caller.

void initScope(unsigned Idx)

T pop()

Returns the value from the top of the stack and removes it.

void push(Tys &&...Args)

Constructs a value in place on the top of the stack.

void dump() const

dump the stack contents to stderr.

size_t size() const

Returns the size of the stack in bytes.

void discard()

Discards the top value from the stack.

T & peek() const

Returns a reference to the value on the top of the stack.

SmallVectorImpl< PartialDiagnosticAt > * PrevDiags

Things needed to do speculative execution.

Expr::EvalStatus & getEvalStatus() const override

Context & getContext() const

bool noteUndefinedBehavior() override

DynamicAllocator & getAllocator()

Context & Ctx

Interpreter Context.

Floating allocFloat(const llvm::fltSemantics &Sem)

ASTContext & getASTContext() const override

llvm::SmallVector< std::pair< const Expr *, const LifetimeExtendedTemporaryDecl * > > SeenGlobalTemporaries

InterpStack & Stk

Temporary stack.

bool maybeDiagnoseDanglingAllocations()

Diagnose any dynamic allocations that haven't been freed yet.

bool noteSideEffect() override

const VarDecl * EvaluatingDecl

Declaration we're initializing/evaluting, if any.

InterpFrame * Current

The current frame.

std::optional< bool > ConstantContextOverride

T allocAP(unsigned BitWidth)

const LangOptions & getLangOpts() const

unsigned SpeculationDepth

StdAllocatorCaller getStdAllocatorCaller(StringRef Name) const

bool inConstantContext() const

Program & P

Reference to the module containing all bytecode.

ComparisonCategoryResult compare(const MemberPointer &RHS) const

A pointer to a memory block, live or dead.

static bool hasSameBase(const Pointer &A, const Pointer &B)

Checks if two pointers are comparable.

Pointer narrow() const

Restricts the scope of an array element pointer.

bool isInitialized() const

Checks if an object was initialized.

bool isZeroSizeArray() const

Checks if the pointer is pointing to a zero-size array.

Pointer atIndex(uint64_t Idx) const

Offsets a pointer inside an array.

bool isDummy() const

Checks if the pointer points to a dummy value.

Pointer atFieldSub(unsigned Off) const

Subtract the given offset from the current Base and Offset of the pointer.

int64_t getIndex() const

Returns the index into an array.

Pointer atField(unsigned Off) const

Creates a pointer to a field.

T & deref() const

Dereferences the pointer, if it's live.

unsigned getNumElems() const

Returns the number of elements.

bool isUnknownSizeArray() const

Checks if the structure is an array of unknown size.

void activate() const

Activats a field.

static std::optional< std::pair< Pointer, Pointer > > computeSplitPoint(const Pointer &A, const Pointer &B)

bool isIntegralPointer() const

QualType getType() const

Returns the type of the innermost field.

bool pointsToStringLiteral() const

bool inArray() const

Checks if the innermost field is an array.

T & elem(unsigned I) const

Dereferences the element at index I.

uint64_t getByteOffset() const

Returns the byte offset from the start.

bool isTypeidPointer() const

std::string toDiagnosticString(const ASTContext &Ctx) const

Converts the pointer to a string usable in diagnostics.

bool isZero() const

Checks if the pointer is null.

const IntPointer & asIntPointer() const

bool isRoot() const

Pointer points directly to a block.

const Descriptor * getDeclDesc() const

Accessor for information about the declaration site.

unsigned getOffset() const

Returns the offset into an array.

bool isOnePastEnd() const

Checks if the index is one past end.

uint64_t getIntegerRepresentation() const

Pointer expand() const

Expands a pointer to the containing array, undoing narrowing.

bool isElementPastEnd() const

Checks if the pointer is an out-of-bounds element pointer.

bool isBlockPointer() const

const FunctionPointer & asFunctionPointer() const

bool isFunctionPointer() const

const Descriptor * getFieldDesc() const

Accessors for information about the innermost field.

size_t elemSize() const

Returns the element size of the innermost field.

bool canBeInitialized() const

If this pointer has an InlineDescriptor we can use to initialize.

Lifetime getLifetime() const

size_t computeOffsetForComparison() const

Compute an integer that can be used to compare this pointer to another one.

const BlockPointer & asBlockPointer() const

void initialize() const

Initializes a field.

void initializeElement(unsigned Index) const

Initialized the given element of a primitive array.

const Record * getRecord() const

Returns the record descriptor of a class.

Block * getGlobal(unsigned Idx)

Returns the value of a global.

Pointer getPtrGlobal(unsigned Idx) const

Returns a pointer to a global.

const void * getNativePointer(unsigned Idx) const

Returns the value of a marshalled native pointer.

Structure/Class descriptor.

const RecordDecl * getDecl() const

Returns the underlying declaration.

llvm::iterator_range< LocalVectorTy::const_reverse_iterator > locals_reverse() const

Describes the statement/declaration an opcode was generated from.

bool checkingForUndefinedBehavior() const

Are we checking an expression for overflow?

OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId)

Add a note to a prior diagnostic.

DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId)

Directly reports a diagnostic message.

OptionalDiagnostic FFDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)

Diagnose that the evaluation could not be folded (FF => FoldFailure)

OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)

Diagnose that the evaluation does not produce a C++11 core constant expression.

bool checkingPotentialConstantExpression() const

Are we checking whether the expression is a potential constant expression?

bool arePotentiallyOverlappingStringLiterals(const Pointer &LHS, const Pointer &RHS)

bool EndSpeculation(InterpState &S, CodePtr OpPC)

Definition Interp.h:3271

static bool ShiftFixedPoint(InterpState &S, CodePtr OpPC, bool Left)

Definition Interp.h:3003

bool GetPtrFieldPop(InterpState &S, CodePtr OpPC, uint32_t Off)

bool InitPop(InterpState &S, CodePtr OpPC)

Definition Interp.h:2092

bool Shr(InterpState &S, CodePtr OpPC)

Definition Interp.h:2966

bool InitGlobalTemp(InterpState &S, CodePtr OpPC, uint32_t I, const LifetimeExtendedTemporaryDecl *Temp)

  1. Converts the value on top of the stack to an APValue 2) Sets that APValue on \Temp 3) Initializes ...

Definition Interp.h:1503

bool CheckDestruction(InterpState &S, CodePtr OpPC)

Definition Interp.h:3730

bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index)

Definition Interp.h:3150

bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth)

bool PopCC(InterpState &S, CodePtr OpPC)

Definition Interp.h:3285

bool ArrayElem(InterpState &S, CodePtr OpPC, uint32_t Index)

Definition Interp.h:3138

bool GT(InterpState &S, CodePtr OpPC)

Definition Interp.h:1257

bool CastPointerIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth)

bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr)

Checks if a value can be initialized.

static bool CastFloatingIntegralAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth, uint32_t FPOI)

Definition Interp.h:2598

bool GetMemberPtrBase(InterpState &S, CodePtr OpPC)

Definition Interp.h:3231

bool GetThisField(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1415

bool PreInc(InterpState &S, CodePtr OpPC, bool CanOverflow)

Definition Interp.h:820

bool NarrowPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:3053

bool CheckFunctionDecl(InterpState &S, CodePtr OpPC, const FunctionDecl *FD)

Opcode. Check if the function decl can be called at compile time.

bool GetMemberPtrBasePop(InterpState &S, CodePtr OpPC, int32_t Off)

Definition Interp.h:1812

bool InitThisField(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1535

bool BitCastPrim(InterpState &S, CodePtr OpPC, bool TargetIsUCharOrByte, uint32_t ResultBitWidth, const llvm::fltSemantics *Sem, const Type *TargetType)

Definition Interp.h:3638

Floating ReadArg< Floating >(InterpState &S, CodePtr &OpPC)

Definition Interp.h:3748

bool Incf(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:925

bool SideEffect(InterpState &S, CodePtr OpPC)

Definition Interp.h:3293

static bool ZeroIntAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth)

Definition Interp.h:2773

bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS, LT *Result)

Definition Interp.h:2842

bool GetParam(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1352

bool EndLifetimePop(InterpState &S, CodePtr OpPC)

Ends the lifetime of the pop'd pointer.

bool Sub(InterpState &S, CodePtr OpPC)

Definition Interp.h:330

bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType)

bool Mulf(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:358

bool InitElemPop(InterpState &S, CodePtr OpPC, uint32_t Idx)

The same as InitElem, but pops the pointer as well.

Definition Interp.h:2140

bool StoreBitField(InterpState &S, CodePtr OpPC)

Definition Interp.h:2014

bool LT(InterpState &S, CodePtr OpPC)

Definition Interp.h:1242

ArithOp

Definition Interp.h:214

@ Sub

Definition Interp.h:214

@ Add

Definition Interp.h:214

bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, uint32_t Offset)

Checks if the dowcast using the given offset is possible with the given pointer.

bool BitCast(InterpState &S, CodePtr OpPC)

Definition Interp.h:3711

bool LoadPop(InterpState &S, CodePtr OpPC)

Definition Interp.h:1927

bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Descriptor *Desc)

Definition Interp.h:2782

bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Block *B)

Checks a direct load of a primitive value from a global or local variable.

static llvm::RoundingMode getRoundingMode(FPOptions FPO)

static bool IncPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:2369

bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR)

We aleady know the given DeclRefExpr is invalid for some reason, now figure out why and print appropr...

bool EndLifetime(InterpState &S, CodePtr OpPC)

Ends the lifetime of the peek'd pointer.

bool GetTypeid(InterpState &S, CodePtr OpPC, const Type *TypePtr, const Type *TypeInfoType)

Typeid support.

bool Dup(InterpState &S, CodePtr OpPC)

Definition Interp.h:1276

bool SetField(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1383

bool CheckNonNullArg(InterpState &S, CodePtr OpPC)

Definition Interp.h:3451

bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const APSInt &IntValue)

Sets the given integral value to the pointer, which is of a std::{weak,partial,strong}...

static bool IncDecPtrHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr)

Definition Interp.h:2344

bool FinishInitActivate(InterpState &S, CodePtr OpPC)

Definition Interp.h:1842

bool GetPtrLocal(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1702

bool Addf(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:318

bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS)

Checks if Div/Rem operation on LHS and RHS is valid.

Definition Interp.h:178

bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc)

Checks if the Descriptor is of a constexpr or const global variable.

static bool IsOpaqueConstantCall(const CallExpr *E)

Definition Interp.h:1040

bool CheckDecl(InterpState &S, CodePtr OpPC, const VarDecl *VD)

Definition Interp.h:3503

bool CheckPointerToIntegralCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, unsigned BitWidth)

bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS, const T &RHS)

Definition Interp.h:269

bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off)

  1. Peeks a Pointer 2) Pushes Pointer.atField(Off) on the stack

bool StoreActivate(InterpState &S, CodePtr OpPC)

Definition Interp.h:1984

bool Div(InterpState &S, CodePtr OpPC)

  1. Pops the RHS from the stack.

Definition Interp.h:597

bool GetFnPtr(InterpState &S, CodePtr OpPC, const Function *Func)

Definition Interp.h:3208

bool FinishInitActivatePop(InterpState &S, CodePtr OpPC)

Definition Interp.h:1851

bool GetGlobalUnchecked(InterpState &S, CodePtr OpPC, uint32_t I)

Same as GetGlobal, but without the checks.

Definition Interp.h:1456

bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr, CheckSubobjectKind CSK)

Checks if Ptr is a one-past-the-end pointer.

bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1714

static bool Activate(InterpState &S, CodePtr OpPC)

Definition Interp.h:1964

bool handleFixedPointOverflow(InterpState &S, CodePtr OpPC, const FixedPoint &FP)

bool Mulc(InterpState &S, CodePtr OpPC)

Definition Interp.h:372

bool RetVoid(InterpState &S, CodePtr &PC)

Definition Interp.h:246

bool ArrayElemPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:3077

bool NE(InterpState &S, CodePtr OpPC)

Definition Interp.h:1235

bool NoRet(InterpState &S, CodePtr OpPC)

Definition Interp.h:3043

bool GetIntPtr(InterpState &S, CodePtr OpPC, const Descriptor *Desc)

Definition Interp.h:3215

llvm::FixedPointSemantics FixedPointSemantics

Definition Interp.h:42

bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)

Checks if a value can be loaded from a block.

static bool FnPtrCast(InterpState &S, CodePtr OpPC)

Definition Interp.h:2712

static bool ZeroIntAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth)

Definition Interp.h:2765

bool Shl(InterpState &S, CodePtr OpPC)

Definition Interp.h:2985

bool RVOPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:2829

IncDecOp

Definition Interp.h:700

@ Inc

Definition Interp.h:701

@ Dec

Definition Interp.h:702

bool CastPointerIntegral(InterpState &S, CodePtr OpPC)

Definition Interp.h:2646

constexpr bool isPtrType(PrimType T)

bool DecfPop(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:949

bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, ArrayRef< int64_t > ArrayIndices, int64_t &IntResult)

Interpret an offsetof operation.

bool SubOffset(InterpState &S, CodePtr OpPC)

Definition Interp.h:2331

constexpr size_t align(size_t Size)

Aligns a size to the pointer alignment.

bool BitXor(InterpState &S, CodePtr OpPC)

  1. Pops the RHS from the stack.

Definition Interp.h:553

bool CheckBCPResult(InterpState &S, const Pointer &Ptr)

bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)

Checks if a pointer is in range.

bool CastAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth)

Definition Interp.h:2541

bool ExpandPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:3059

bool Store(InterpState &S, CodePtr OpPC)

Definition Interp.h:1941

bool Divc(InterpState &S, CodePtr OpPC)

Definition Interp.h:429

bool DoBitCastPtr(InterpState &S, CodePtr OpPC, const Pointer &FromPtr, Pointer &ToPtr)

bool GetField(InterpState &S, CodePtr OpPC, uint32_t I)

  1. Peeks a pointer on the stack 2) Pushes the value of the pointer's field on the stack

Definition Interp.h:1369

bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC)

Definition Interp.h:3108

bool This(InterpState &S, CodePtr OpPC)

Definition Interp.h:2803

bool InitScope(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:2472

PushVal

Definition Interp.h:696

@ Yes

Definition Interp.h:698

@ No

Definition Interp.h:697

bool CheckDynamicMemoryAllocation(InterpState &S, CodePtr OpPC)

Checks if dynamic memory allocation is available in the current language mode.

bool InitField(InterpState &S, CodePtr OpPC, uint32_t I)

  1. Pops the value from the stack 2) Peeks a pointer from the stack 3) Pushes the value to field I of ...

Definition Interp.h:1604

bool CmpHelperEQ(InterpState &S, CodePtr OpPC, CompareFn Fn)

Definition Interp.h:993

T ReadArg(InterpState &S, CodePtr &OpPC)

Definition Interp.h:3739

bool PreDecBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, uint32_t BitWidth)

Definition Interp.h:895

bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)

Checks if a pointer is live and accessible.

bool CastFloatingIntegral(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:2568

bool ArrayDecay(InterpState &S, CodePtr OpPC)

Just takes a pointer and checks if it's an incomplete array type.

Definition Interp.h:3184

bool PushCC(InterpState &S, CodePtr OpPC, bool Value)

Definition Interp.h:3281

bool GetPtrDerivedPop(InterpState &S, CodePtr OpPC, uint32_t Off, bool NullOK, const Type *TargetType)

Definition Interp.h:1734

bool DiagTypeid(InterpState &S, CodePtr OpPC)

bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr)

This is not used by any of the opcodes directly.

bool InitGlobalTempComp(InterpState &S, CodePtr OpPC, const LifetimeExtendedTemporaryDecl *Temp)

  1. Converts the value on top of the stack to an APValue 2) Sets that APValue on \Temp 3) Initialized ...

Definition Interp.h:1522

bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits, bool TargetIsUCharOrByte)

bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1330

bool OffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E)

Definition Interp.h:3436

bool BitAnd(InterpState &S, CodePtr OpPC)

  1. Pops the RHS from the stack.

Definition Interp.h:513

bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS, unsigned Bits)

Checks if the shift operation is legal.

Definition Interp.h:131

static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue)

FixedPoint ReadArg< FixedPoint >(InterpState &S, CodePtr &OpPC)

Definition Interp.h:3783

static bool CastFloatingFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS)

Definition Interp.h:2673

void diagnoseEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED, const APSInt &Value)

bool StartLifetime(InterpState &S, CodePtr OpPC)

bool LE(InterpState &S, CodePtr OpPC)

Definition Interp.h:1249

bool CheckNewTypeMismatchArray(InterpState &S, CodePtr OpPC, const Expr *E)

Definition Interp.h:3631

bool Zero(InterpState &S, CodePtr OpPC)

Definition Interp.h:2760

bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F, uint32_t FieldOffset)

Definition Interp.h:1566

bool Unsupported(InterpState &S, CodePtr OpPC)

Just emit a diagnostic.

Definition Interp.h:3254

bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR, bool InitializerFailed)

Definition Interp.h:3392

bool DecPop(InterpState &S, CodePtr OpPC, bool CanOverflow)

  1. Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value decreased by ...

Definition Interp.h:867

bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr, CheckSubobjectKind CSK)

Checks if a pointer is null.

bool CheckDeleteSource(InterpState &S, CodePtr OpPC, const Expr *Source, const Pointer &Ptr)

Check the source of the pointer passed to delete/delete[] has actually been heap allocated by us.

bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result, APFloat::opStatus Status, FPOptions FPO)

Checks if the result of a floating-point operation is valid in the current context.

bool CastFP(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem, llvm::RoundingMode RM)

  1. Pops a Floating from the stack.

Definition Interp.h:2502

ComparisonCategoryResult Compare(const T &X, const T &Y)

Helper to compare two comparable types.

PrimType

Enumeration of the primitive types of the VM.

bool DecPopBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, uint32_t BitWidth)

Definition Interp.h:876

bool InitThisBitFieldActivate(InterpState &S, CodePtr OpPC, const Record::Field *F, uint32_t FieldOffset)

Definition Interp.h:1583

bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1429

bool StoreBitFieldPop(InterpState &S, CodePtr OpPC)

Definition Interp.h:2030

bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, bool CanOverflow, UnsignedOrNone BitWidth=std::nullopt)

Definition Interp.h:706

bool CallVar(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)

static bool DecPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:2378

constexpr bool needsAlloc()

static bool CheckAllocations(InterpState &S, CodePtr OpPC)

Definition Interp.h:3621

bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)

Definition Interp.h:3522

bool InvalidShuffleVectorIndex(InterpState &S, CodePtr OpPC, uint32_t Index)

bool ToMemberPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:2182

static bool CastIntegralFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS)

Definition Interp.h:2657

bool Rem(InterpState &S, CodePtr OpPC)

  1. Pops the RHS from the stack.

Definition Interp.h:574

bool VirtBaseHelper(InterpState &S, CodePtr OpPC, const RecordDecl *Decl, const Pointer &Ptr)

Definition Interp.h:1877

bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E, std::optional< uint64_t > ArraySize)

Check if the initializer and storage types of a placement-new expression match.

bool GetMemberPtr(InterpState &S, CodePtr OpPC, const ValueDecl *D)

Definition Interp.h:3226

bool Dump(InterpState &S, CodePtr OpPC)

Definition Interp.h:1862

bool SizelessVectorElementSize(InterpState &S, CodePtr OpPC)

Definition Interp.h:3407

static bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr)

Definition Interp.h:2720

bool CheckLiteralType(InterpState &S, CodePtr OpPC, const Type *T)

bool IsNonNull(InterpState &S, CodePtr OpPC)

Definition Interp.h:2791

bool GetPtrThisField(InterpState &S, CodePtr OpPC, uint32_t Off)

Definition Interp.h:1724

bool ConstFloat(InterpState &S, CodePtr OpPC, const Floating &F)

Definition Interp.h:1318

bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)

Checks if the array is offsetable.

bool InitThisFieldActivate(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1549

bool IncBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, unsigned BitWidth)

Definition Interp.h:786

bool SubPtr(InterpState &S, CodePtr OpPC, bool ElemSizeIsZero)

  1. Pops a Pointer from the stack.

Definition Interp.h:2391

bool GetPtrBase(InterpState &S, CodePtr OpPC, uint32_t Off)

Definition Interp.h:1768

bool SetParam(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1361

bool StoreActivatePop(InterpState &S, CodePtr OpPC)

Definition Interp.h:1999

bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC)

Definition Interp.h:3241

bool Comp(InterpState &S, CodePtr OpPC)

  1. Pops the value from the stack.

Definition Interp.h:960

static bool CastFixedPointFloating(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem)

Definition Interp.h:2689

bool Divf(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:623

bool CheckThis(InterpState &S, CodePtr OpPC)

Checks the 'this' pointer.

bool FinishInitGlobal(InterpState &S, CodePtr OpPC)

bool DecayPtr(InterpState &S, CodePtr OpPC)

OldPtr -> Integer -> NewPtr.

Definition Interp.h:3479

static bool ActivateThisField(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1971

bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)

bool GetPtrVirtBasePop(InterpState &S, CodePtr OpPC, const RecordDecl *D)

Definition Interp.h:1888

bool StorePop(InterpState &S, CodePtr OpPC)

Definition Interp.h:1953

void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC, const Function *Func)

bool SetLocal(InterpState &S, CodePtr OpPC, uint32_t I)

  1. Pops the value from the stack.

Definition Interp.h:1346

bool FinishInit(InterpState &S, CodePtr OpPC)

Definition Interp.h:1835

bool InvalidStore(InterpState &S, CodePtr OpPC, const Type *T)

Definition Interp.h:3380

static bool CastFloatingIntegralAPS(InterpState &S, CodePtr OpPC, uint32_t BitWidth, uint32_t FPOI)

Definition Interp.h:2619

bool Mul(InterpState &S, CodePtr OpPC)

Definition Interp.h:350

bool InitElem(InterpState &S, CodePtr OpPC, uint32_t Idx)

  1. Pops the value from the stack 2) Peeks a pointer and gets its index \Idx 3) Sets the value on the ...

Definition Interp.h:2106

bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:2444

bool Pop(InterpState &S, CodePtr OpPC)

Definition Interp.h:1282

bool DecBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, uint32_t BitWidth)

Definition Interp.h:853

size_t primSize(PrimType Type)

Returns the size of a primitive type in bytes.

bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F)

Definition Interp.h:1635

bool PreIncBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, uint32_t BitWidth)

Definition Interp.h:829

bool Dec(InterpState &S, CodePtr OpPC, bool CanOverflow)

  1. Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value decreased by ...

Definition Interp.h:844

bool StoreBitFieldActivate(InterpState &S, CodePtr OpPC)

Definition Interp.h:2045

bool CheckPseudoDtor(InterpState &S, CodePtr OpPC)

Definition Interp.h:3416

bool Free(InterpState &S, CodePtr OpPC, bool DeleteIsArrayForm, bool IsGlobalDelete)

bool PreDec(InterpState &S, CodePtr OpPC, bool CanOverflow)

Definition Interp.h:887

bool InvalidNewDeleteExpr(InterpState &S, CodePtr OpPC, const Expr *E)

bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems)

bool CallBI(InterpState &S, CodePtr OpPC, const CallExpr *CE, uint32_t BuiltinID)

bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B)

bool FinishInitPop(InterpState &S, CodePtr OpPC)

Definition Interp.h:1828

bool Neg(InterpState &S, CodePtr OpPC)

Definition Interp.h:654

bool StartSpeculation(InterpState &S, CodePtr OpPC)

Definition Interp.h:3261

bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr)

Checks if the variable has externally defined storage.

std::optional< Pointer > OffsetHelper(InterpState &S, CodePtr OpPC, const T &Offset, const Pointer &Ptr, bool IsPointerArith=false)

Definition Interp.h:2205

bool BitOr(InterpState &S, CodePtr OpPC)

  1. Pops the RHS from the stack.

Definition Interp.h:533

llvm::function_ref< bool(ComparisonCategoryResult)> CompareFn

Definition Interp.h:978

bool Inv(InterpState &S, CodePtr OpPC)

Definition Interp.h:643

bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr, bool WillBeActivated)

Checks if a value can be stored in a block.

bool Load(InterpState &S, CodePtr OpPC)

Definition Interp.h:1913

bool isConstexprUnknown(const Pointer &P)

bool SetGlobal(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1469

bool Cast(InterpState &S, CodePtr OpPC)

Definition Interp.h:2493

bool StoreBitFieldActivatePop(InterpState &S, CodePtr OpPC)

Definition Interp.h:2063

bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)

  1. Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...

Definition Interp.h:776

bool EQ(InterpState &S, CodePtr OpPC)

Definition Interp.h:1203

bool IncfPop(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:933

bool GetPtrBasePop(InterpState &S, CodePtr OpPC, uint32_t Off, bool NullOK)

Definition Interp.h:1789

bool GetFieldPop(InterpState &S, CodePtr OpPC, uint32_t I)

  1. Pops a pointer from the stack 2) Pushes the value of the pointer's field on the stack

Definition Interp.h:1401

bool Add(InterpState &S, CodePtr OpPC)

Definition Interp.h:310

bool CmpHelperEQ< MemberPointer >(InterpState &S, CodePtr OpPC, CompareFn Fn)

Definition Interp.h:1161

bool AddOffset(InterpState &S, CodePtr OpPC)

Definition Interp.h:2318

ShiftDir

Definition Interp.h:127

@ Right

Definition Interp.h:127

@ Left

Definition Interp.h:127

bool Const(InterpState &S, CodePtr OpPC, const T &Arg)

Definition Interp.h:1307

bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)

Copy the contents of Src into Dest.

bool DiagnoseUninitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)

bool IncPop(InterpState &S, CodePtr OpPC, bool CanOverflow)

  1. Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...

Definition Interp.h:800

bool Memcpy(InterpState &S, CodePtr OpPC)

Definition Interp.h:2172

bool GE(InterpState &S, CodePtr OpPC)

Definition Interp.h:1264

bool DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, std::byte *Buff, Bits BitWidth, Bits FullBitWidth, bool &HasIndeterminateBits)

bool CallPtr(InterpState &S, CodePtr OpPC, uint32_t ArgSize, const CallExpr *CE)

bool CmpHelperEQ< Pointer >(InterpState &S, CodePtr OpPC, CompareFn Fn)

Definition Interp.h:1052

static bool CastFixedPointIntegral(InterpState &S, CodePtr OpPC)

Definition Interp.h:2699

constexpr bool isIntegralType(PrimType T)

bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)

bool CastIntegralFloating(InterpState &S, CodePtr OpPC, const llvm::fltSemantics *Sem, uint32_t FPOI)

Definition Interp.h:2553

bool CmpHelper(InterpState &S, CodePtr OpPC, CompareFn Fn)

Definition Interp.h:981

bool CheckConst(InterpState &S, CodePtr OpPC, const Pointer &Ptr)

Checks if a pointer points to const storage.

bool CastFixedPoint(InterpState &S, CodePtr OpPC, uint32_t FPS)

Definition Interp.h:2511

bool GetPtrParam(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1707

bool EnableLocal(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:2477

bool AllocCN(InterpState &S, CodePtr OpPC, const Descriptor *ElementDesc, bool IsNoThrow)

Definition Interp.h:3577

bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1444

bool Subf(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:338

bool GetPtrThisVirtBase(InterpState &S, CodePtr OpPC, const RecordDecl *D)

Definition Interp.h:1897

bool GetLocalEnabled(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:2483

bool InitGlobal(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1475

bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind, bool Fatal)

Same here, but only for casts.

Definition Interp.h:3344

bool DoShiftAP(InterpState &S, CodePtr OpPC, const APSInt &LHS, APSInt RHS, LT *Result)

A version of DoShift that works on IntegralAP.

Definition Interp.h:2922

bool CastMemberPtrPtr(InterpState &S, CodePtr OpPC)

Definition Interp.h:2190

bool Ret(InterpState &S, CodePtr &PC)

Definition Interp.h:224

bool InitFieldActivate(InterpState &S, CodePtr OpPC, uint32_t I)

Definition Interp.h:1619

bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr)

bool IncPopBitfield(InterpState &S, CodePtr OpPC, bool CanOverflow, uint32_t BitWidth)

Definition Interp.h:809

bool Flip(InterpState &S, CodePtr OpPC)

[Value1, Value2] -> [Value2, Value1]

Definition Interp.h:1289

bool CMP3(InterpState &S, CodePtr OpPC, const ComparisonCategoryInfo *CmpInfo)

Definition Interp.h:1210

bool InitBitFieldActivate(InterpState &S, CodePtr OpPC, const Record::Field *F)

Definition Interp.h:1666

bool CastAP(InterpState &S, CodePtr OpPC, uint32_t BitWidth)

Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need to know what bitwidth the resu...

Definition Interp.h:2529

bool Invalid(InterpState &S, CodePtr OpPC)

bool CmpHelper< Pointer >(InterpState &S, CodePtr OpPC, CompareFn Fn)

Definition Interp.h:998

bool Decf(InterpState &S, CodePtr OpPC, uint32_t FPOI)

Definition Interp.h:941

bool Assume(InterpState &S, CodePtr OpPC)

Definition Interp.h:3423

bool GetPtrThisBase(InterpState &S, CodePtr OpPC, uint32_t Off)

Definition Interp.h:1818

bool IncDecFloatHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, uint32_t FPOI)

Definition Interp.h:905

static bool IsConstantContext(InterpState &S, CodePtr OpPC)

Definition Interp.h:3616

bool AllocN(InterpState &S, CodePtr OpPC, PrimType T, const Expr *Source, bool IsNoThrow)

Definition Interp.h:3537

bool CheckEnumValue(InterpState &S, CodePtr OpPC, const EnumDecl *ED)

Definition Interp.h:3466

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

ComparisonCategoryResult

An enumeration representing the possible results of a three-way comparison.

CheckSubobjectKind

The order of this enum is important for diagnostics.

@ Result

The result type of a method or function.

AccessKinds

Kinds of access we can perform on an object, for diagnostics.

const FunctionProtoType * T

@ ConstantFold

Fold the expression to a constant.

U cast(CodeGen::Address addr)

SmallVectorImpl< PartialDiagnosticAt > * Diag

Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...

size_t getQuantity() const

unsigned Base

Start of the current subfield.

Block * Pointee

The block the pointer is pointing to.

Describes a memory block created by an allocation site.

unsigned getSize() const

Returns the size of the object without metadata.

const Decl * asDecl() const

SourceLocation getLocation() const

PrimType getPrimType() const

const Expr * asExpr() const

bool isArray() const

Checks if the descriptor is of an array.

Descriptor used for global variables.

Mapping from primitive types to their representation.