clang: lib/CodeGen/CGException.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

24#include "llvm/IR/IntrinsicInst.h"

25#include "llvm/IR/Intrinsics.h"

26#include "llvm/IR/IntrinsicsWebAssembly.h"

27#include "llvm/Support/SaveAndRestore.h"

28

29using namespace clang;

30using namespace CodeGen;

31

33

34

35 llvm::FunctionType *FTy =

36 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, false);

37

39}

40

42 llvm::FunctionType *FTy =

43 llvm::FunctionType::get(CGM.VoidTy, false);

45}

46

48 llvm::FunctionType *FTy =

49 llvm::FunctionType::get(CGM.VoidTy, false);

51}

52

54

55

56 llvm::FunctionType *FTy =

57 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, false);

58

60}

61

63

64

65 llvm::FunctionType *FTy =

66 llvm::FunctionType::get(VoidTy, false);

67

68 StringRef name;

69

70

73 name = "_ZSt9terminatev";

77 name = "__std_terminate";

78 else

79 name = "?terminate@@YAXXZ";

82 name = "objc_terminate";

83 else

84 name = "abort";

86}

87

89 StringRef Name) {

90 llvm::FunctionType *FTy =

91 llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, false);

92

94}

95

128 nullptr};

130 nullptr};

131

134 const llvm::Triple &T = Target.getTriple();

135 if (T.isWindowsMSVCEnvironment())

144}

145

148 const llvm::Triple &T = Target.getTriple();

149 if (T.isWindowsMSVCEnvironment())

151

160 if (T.isOSCygMing())

164 [[fallthrough]];

172 }

173 llvm_unreachable("bad runtime kind");

174}

175

178 const llvm::Triple &T = Target.getTriple();

179 if (T.isWindowsMSVCEnvironment())

181 if (T.isOSAIX())

191 if (T.isOSzOS())

194}

195

196

197

200 if (Target.getTriple().isWindowsMSVCEnvironment())

202

204

205

208

209

210

211

216

220

221

222

226 }

227 llvm_unreachable("bad runtime kind");

228}

229

231 if (T.getArch() == llvm::Triple::x86)

234}

235

241

242

245

246 if (L.ObjC)

251}

252

255

256

257

259 return get(CGF.CGM, dyn_cast_or_null(FD));

260}

261

266 llvm::AttributeList(), true);

267}

268

271 llvm::FunctionCallee Fn = getPersonalityFn(CGM, Personality);

272 return castllvm::Constant(Fn.getCallee());

273}

274

275

277 for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {

278

279

280 llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();

281 if (LPI->isCatch(I)) {

282

283 if (llvm::GlobalVariable *GV = dyn_castllvm::GlobalVariable(Val))

284

285

286 if (GV->getName().starts_with("OBJC_EHTYPE"))

287 return false;

288 } else {

289

290 llvm::Constant *CVal = castllvm::Constant(Val);

291 for (llvm::User::op_iterator

292 II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {

293 if (llvm::GlobalVariable *GV =

294 castllvm::GlobalVariable((*II)->stripPointerCasts()))

295

296

297 if (GV->getName().starts_with("OBJC_EHTYPE"))

298 return false;

299 }

300 }

301 }

302 return true;

303}

304

305

306

308 for (llvm::User *U : Fn->users()) {

309

310 if (llvm::ConstantExpr *CE = dyn_castllvm::ConstantExpr(U)) {

311 if (CE->getOpcode() != llvm::Instruction::BitCast) return false;

313 return false;

314 continue;

315 }

316

317

318 llvm::Function *F = dyn_castllvm::Function(U);

319 if (!F) return false;

320

321 for (auto BB = F->begin(), E = F->end(); BB != E; ++BB) {

322 if (BB->isLandingPad())

324 return false;

325 }

326 }

327

328 return true;

329}

330

331

332

333

334

335void CodeGenModule::SimplifyPersonality() {

336

337 if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)

338 return;

339

340

341

343 return;

344

348 return;

349

350 assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&

351 "Different EHPersonalities using the same personality function.");

352

353 llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);

354

355

356 if (!Fn || Fn->use_empty()) return;

357

358

360

361

362

364

365

366 if (Fn->getType() != CXXFn.getCallee()->getType())

367 return;

368

369 Fn->replaceAllUsesWith(CXXFn.getCallee());

370 Fn->eraseFromParent();

371}

372

373

374

376

377 return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);

378}

379

380namespace {

381

382

384 llvm::Value *exn;

385 FreeException(llvm::Value *exn) : exn(exn) {}

388 }

389 };

390}

391

392

393

394

395

397

398

401

402

403

406

407

408

409

410

411

412

413

415 true);

416

417

419 cleanup, castllvm::Instruction(typedAddr.emitRawPointer(*this)));

420}

421

426}

427

432}

433

436}

437

440}

441

443 bool KeepInsertionPoint) {

444

445

446

447

448 const llvm::Triple &T = Target.getTriple();

449 if (CGM.getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) {

451 return;

452 }

453 if (const Expr *SubExpr = E->getSubExpr()) {

454 QualType ThrowType = SubExpr->getType();

456 const Stmt *ThrowStmt = E->getSubExpr();

459 } else {

461 }

462 } else {

464 }

465

466

467

468 if (KeepInsertionPoint)

470}

471

474 return;

475

476 const FunctionDecl* FD = dyn_cast_or_null(D);

477 if (!FD) {

478

479 if (const CapturedDecl* CD = dyn_cast_or_null(D)) {

480 if (CD->isNothrow())

482 }

483 return;

484 }

486 if (!Proto)

487 return;

488

490

491

492

495

496

498 return;

499

500

501

505 else

507 diag::warn_wasm_dynamic_exception_spec_ignored)

509 return;

510 }

511

512

513

514

515

521 diag::warn_wasm_dynamic_exception_spec_ignored)

523

526

527 for (unsigned I = 0; I != NumExceptions; ++I) {

531 true);

532 Filter->setFilter(I, EHType);

533 }

535

536 if (getLangOpts().EHAsynch)

538 }

539}

540

541

545 if (!dispatchBlock) return;

546 if (dispatchBlock->use_empty()) {

547 delete dispatchBlock;

548 return;

549 }

550

552

553

554

556

558 llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");

559

560 llvm::Value *zero = CGF.Builder.getInt32(0);

561 llvm::Value *failsFilter =

562 CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");

563 CGF.Builder.CreateCondBr(failsFilter, unexpectedBB,

565

567 }

568

569

570

571

572

575 ->setDoesNotReturn();

576 CGF.Builder.CreateUnreachable();

577}

578

581 return;

582

583 const FunctionDecl* FD = dyn_cast_or_null(D);

584 if (!FD) {

585

586 if (const CapturedDecl* CD = dyn_cast_or_null(D)) {

589 }

590 return;

591 }

593 if (!Proto)

594 return;

595

599

600

602 return;

603

604

605

609 return;

610 }

615

618 }

619}

620

622 const llvm::Triple &T = Target.getTriple();

623

624

625 const bool IsTargetDevice =

626 (CGM.getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN()));

627 if (!IsTargetDevice)

630 if (!IsTargetDevice)

632}

633

635 unsigned NumHandlers = S.getNumHandlers();

637

638 for (unsigned I = 0; I != NumHandlers; ++I) {

640

642 if (C->getExceptionDecl()) {

643

644

645

646

647

648

651 C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);

652

656 else

658 CaughtType, C->getCaughtType());

660 } else {

661

663

664

667 }

668 }

669}

670

671llvm::BasicBlock *

675

676

677

680

681

683

685 if (!dispatchBlock) {

686 switch (scope.getKind()) {

688

689 EHCatchScope &catchScope = cast(scope);

693

694

695 } else {

697 }

698 break;

699 }

700

703 break;

704

707 break;

708

711 break;

712 }

714 }

715 return dispatchBlock;

716}

717

718llvm::BasicBlock *

720

721

723 return nullptr;

724

725

727

729 if (DispatchBlock)

730 return DispatchBlock;

731

734 else

737

740 DispatchBlock->setName("catch.dispatch");

741 break;

742

744 DispatchBlock->setName("ehcleanup");

745 break;

746

748 llvm_unreachable("exception specifications not handled yet!");

749

751 DispatchBlock->setName("terminate");

752 break;

753 }

755 return DispatchBlock;

756}

757

758

759

760

762 switch (S.getKind()) {

764 return !cast(S).isEHCleanup();

768 return false;

769 }

770

771 llvm_unreachable("Invalid EHScope Kind!");

772}

773

777

778

779

780

781

783 if (!LO.Exceptions || LO.IgnoreExceptions) {

784 if (!LO.Borland && !LO.MicrosoftExt)

785 return nullptr;

787 return nullptr;

788 }

789

790

791 if (LO.CUDA && LO.CUDAIsDevice)

792 return nullptr;

793

794

795

797 if (LP) return LP;

798

800

801 if (CurFn->hasPersonalityFn())

803

805

807 } else {

808

810 }

811

812 assert(LP);

813

814

815

817 ir->setCachedLandingPad(LP);

819 }

820

821 return LP;

822}

823

827 "LandingPad should not be emitted when -fignore-exceptions are in "

828 "effect.");

830 switch (innermostEHScope.getKind()) {

833

838 return lpad;

839 }

840

841

842 CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();

844

845

848

849 llvm::LandingPadInst *LPadInst =

851

852 llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);

854 llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);

856

857

858

859

860

861

862

863 bool hasCatchAll = false;

864 bool hasCleanup = false;

865 bool hasFilter = false;

869 ++I) {

870

871 switch (I->getKind()) {

873

874 hasCleanup = (hasCleanup || cast(*I).isEHCleanup());

875 continue;

876

878 assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");

879 assert(!hasCatchAll && "EH filter reached after catch-all");

880

881

883 hasFilter = true;

884

885

886 for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)

887 filterTypes.push_back(filter.getFilter(i));

888 goto done;

889 }

890

892

893 assert(!hasCatchAll);

894 hasCatchAll = true;

895 goto done;

896

898 break;

899 }

900

901 EHCatchScope &catchScope = cast(*I);

902 for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {

904 assert(handler.Type.Flags == 0 &&

905 "landingpads do not support catch handler flags");

906

907

909 assert(!hasCatchAll);

910 hasCatchAll = true;

911 goto done;

912 }

913

914

915 if (catchTypes.insert(handler.Type.RTTI).second)

916

917 LPadInst->addClause(handler.Type.RTTI);

918 }

919 }

920

921 done:

922

923 assert(!(hasCatchAll && hasFilter));

924 if (hasCatchAll) {

926

927

928

929 } else if (hasFilter) {

930

931

932

934 llvm::ArrayType *AType =

935 llvm::ArrayType::get(!filterTypes.empty() ?

936 filterTypes[0]->getType() : Int8PtrTy,

937 filterTypes.size());

938

939 for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)

940 Filters.push_back(castllvm::Constant(filterTypes[i]));

941 llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);

942 LPadInst->addClause(FilterArray);

943

944

945 if (hasCleanup)

946 LPadInst->setCleanup(true);

947

948

949 } else if (hasCleanup) {

950 LPadInst->setCleanup(true);

951 }

952

953 assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&

954 "landingpad instruction has no clauses!");

955

956

958

959

960 Builder.restoreIP(savedIP);

961

962 return lpad;

963}

964

967 assert(DispatchBlock);

968

969 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();

971

973 if (!ParentPad)

974 ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());

975 llvm::BasicBlock *UnwindBB =

977

979 llvm::CatchSwitchInst *CatchSwitch =

980 CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);

981

982

983 for (unsigned I = 0; I < NumHandlers; ++I) {

985

989

991

993 CGF.Builder.CreateCatchPad(

995 llvm::Constant::getNullValue(CGF.VoidPtrTy)});

996 } else {

997 CGF.Builder.CreateCatchPad(CatchSwitch, {TypeInfo.RTTI});

998 }

999

1000 CatchSwitch->addHandler(Handler.Block);

1001 }

1002 CGF.Builder.restoreIP(SavedIP);

1003}

1004

1005

1006

1007

1011 assert(DispatchBlock);

1012

1013 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();

1015

1017 if (!ParentPad)

1018 ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());

1019 llvm::BasicBlock *UnwindBB =

1021

1023 llvm::CatchSwitchInst *CatchSwitch =

1024 CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);

1025

1026

1027

1028 llvm::BasicBlock *WasmCatchStartBlock = CGF.createBasicBlock("catch.start");

1029 CatchSwitch->addHandler(WasmCatchStartBlock);

1031

1032

1034 for (unsigned I = 0, E = NumHandlers; I < E; ++I) {

1039 CatchTypes.push_back(TypeInfo.RTTI);

1040 }

1041 auto *CPI = CGF.Builder.CreateCatchPad(CatchSwitch, CatchTypes);

1042

1043

1044

1045

1046 llvm::Function *GetExnFn =

1047 CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);

1048 llvm::Function *GetSelectorFn =

1049 CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_ehselector);

1050 llvm::CallInst *Exn = CGF.Builder.CreateCall(GetExnFn, CPI);

1052 llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);

1053

1054 llvm::Function *TypeIDFn =

1056

1057

1061 CGF.Builder.restoreIP(SavedIP);

1062 return;

1063 }

1064

1065

1066 for (unsigned I = 0, E = NumHandlers;; ++I) {

1067 assert(I < E && "ran off end of handlers!");

1072

1073

1074 llvm::BasicBlock *NextBlock;

1075

1076 bool EmitNextBlock = false, NextIsEnd = false;

1077

1078

1079

1080

1081 if (I + 1 == E) {

1083 EmitNextBlock = true;

1084 NextIsEnd = true;

1085

1086

1087

1090 NextIsEnd = true;

1091

1092

1093 } else {

1095 EmitNextBlock = true;

1096 }

1097

1098

1099 llvm::CallInst *TypeIndex = CGF.Builder.CreateCall(TypeIDFn, TypeInfo.RTTI);

1100 TypeIndex->setDoesNotThrow();

1101

1102 llvm::Value *MatchesTypeIndex =

1103 CGF.Builder.CreateICmpEQ(Selector, TypeIndex, "matches");

1104 CGF.Builder.CreateCondBr(MatchesTypeIndex, Handler.Block, NextBlock);

1105

1106 if (EmitNextBlock)

1108 if (NextIsEnd)

1109 break;

1110 }

1111

1112 CGF.Builder.restoreIP(SavedIP);

1113}

1114

1115

1116

1123

1125 assert(dispatchBlock);

1126

1127

1128

1131 assert(dispatchBlock == catchScope.getHandler(0).Block);

1132 return;

1133 }

1134

1135 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();

1137

1138

1139 llvm::Function *llvm_eh_typeid_for =

1141 llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();

1143

1144

1146

1147

1148 for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {

1149 assert(i < e && "ran off end of handlers!");

1151

1152 llvm::Value *typeValue = handler.Type.RTTI;

1153 assert(handler.Type.Flags == 0 &&

1154 "landingpads do not support catch handler flags");

1155 assert(typeValue && "fell into catch-all case!");

1156

1157 if (typeValue->getType() != argTy)

1158 typeValue =

1161

1162

1163 bool nextIsEnd;

1164 llvm::BasicBlock *nextBlock;

1165

1166

1167

1168 if (i + 1 == e) {

1170 nextIsEnd = true;

1171

1172

1173

1176 nextIsEnd = true;

1177

1178

1179 } else {

1181 nextIsEnd = false;

1182 }

1183

1184

1185 llvm::CallInst *typeIndex =

1186 CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);

1187 typeIndex->setDoesNotThrow();

1188

1189 llvm::Value *matchesTypeIndex =

1190 CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");

1191 CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);

1192

1193

1194 if (nextIsEnd) {

1195 CGF.Builder.restoreIP(savedIP);

1196 return;

1197 }

1198

1200 }

1201}

1202

1208}

1209

1211 unsigned NumHandlers = S.getNumHandlers();

1215

1216

1220 return;

1221 }

1222

1223

1225

1226

1227

1229 CatchScope.begin(), CatchScope.begin() + NumHandlers);

1230

1232

1233

1235

1236

1238 Builder.CreateBr(ContBB);

1239

1240

1241

1242 bool doImplicitRethrow = false;

1243 if (IsFnTryBlock)

1244 doImplicitRethrow = isa(CurCodeDecl) ||

1246

1247

1248

1249

1251 llvm::BasicBlock *WasmCatchStartBlock = nullptr;

1253 auto *CatchSwitch =

1254 castllvm::CatchSwitchInst(DispatchBlock->getFirstNonPHI());

1255 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()

1256 ? CatchSwitch->getSuccessor(1)

1257 : CatchSwitch->getSuccessor(0);

1258 auto *CPI = castllvm::CatchPadInst(WasmCatchStartBlock->getFirstNonPHI());

1260 }

1261

1262

1263

1264

1265

1266

1267

1268

1269 bool HasCatchAll = false;

1270 for (unsigned I = NumHandlers; I != 0; --I) {

1271 HasCatchAll |= Handlers[I - 1].isCatchAll();

1272 llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;

1274

1275

1277

1278

1279

1280 RunCleanupsScope CatchScope(*this);

1281

1282

1285

1286

1288

1289

1291

1292

1293

1294

1295

1296

1297

1298

1299

1300

1303 Builder.CreateUnreachable();

1304 Builder.ClearInsertionPoint();

1305 }

1306

1307

1308 CatchScope.ForceCleanup();

1309

1310

1312 Builder.CreateBr(ContBB);

1313 }

1314

1315

1316

1317

1318

1320 assert(WasmCatchStartBlock);

1321

1322

1323

1324

1325 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;

1326 while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {

1327 auto *BI = castllvm::BranchInst(TI);

1328 assert(BI->isConditional());

1329 RethrowBlock = BI->getSuccessor(1);

1330 }

1331 assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());

1332 Builder.SetInsertPoint(RethrowBlock);

1333 llvm::Function *RethrowInCatchFn =

1336 }

1337

1340}

1341

1342namespace {

1344 llvm::Value *ForEHVar;

1345 llvm::FunctionCallee EndCatchFn;

1346 CallEndCatchForFinally(llvm::Value *ForEHVar,

1347 llvm::FunctionCallee EndCatchFn)

1348 : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}

1349

1351 llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");

1352 llvm::BasicBlock *CleanupContBB =

1354

1355 llvm::Value *ShouldEndCatch =

1357 CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);

1361 }

1362 };

1363

1365 const Stmt *Body;

1366 llvm::Value *ForEHVar;

1367 llvm::FunctionCallee EndCatchFn;

1368 llvm::FunctionCallee RethrowFn;

1369 llvm::Value *SavedExnVar;

1370

1371 PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,

1372 llvm::FunctionCallee EndCatchFn,

1373 llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)

1374 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),

1375 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}

1376

1378

1379 if (EndCatchFn)

1381 ForEHVar, EndCatchFn);

1382

1383

1384

1385 llvm::Value *SavedCleanupDest =

1387 "cleanup.dest.saved");

1388

1389

1391

1392

1393

1395 llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");

1396 llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");

1397

1398 llvm::Value *ShouldRethrow =

1400 CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);

1401

1403 if (SavedExnVar) {

1407 } else {

1409 }

1410 CGF.Builder.CreateUnreachable();

1411

1413

1414

1417 }

1418

1419

1420

1421

1422 if (EndCatchFn) {

1423 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();

1425 CGF.Builder.restoreIP(SavedIP);

1426 }

1427

1428

1429

1431 }

1432 };

1433}

1434

1435

1436

1437

1439 llvm::FunctionCallee beginCatchFn,

1440 llvm::FunctionCallee endCatchFn,

1441 llvm::FunctionCallee rethrowFn) {

1442 assert((!!beginCatchFn) == (!!endCatchFn) &&

1443 "begin/end catch functions not paired");

1444 assert(rethrowFn && "rethrow function is required");

1445

1446 BeginCatchFn = beginCatchFn;

1447

1448

1449

1450

1451

1452

1453

1454 llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();

1455 SavedExnVar = nullptr;

1456 if (rethrowFnTy->getNumParams())

1458

1459

1460

1461

1462

1463

1464

1465

1466

1467

1468

1469

1470

1471

1472

1473

1475

1476

1479

1480

1482 ForEHVar, endCatchFn,

1483 rethrowFn, SavedExnVar);

1484

1485

1486 llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");

1489}

1490

1492

1494 llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;

1495

1497

1498

1499 if (catchBB->use_empty()) {

1500 delete catchBB;

1501 } else {

1502 CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();

1504

1505 llvm::Value *exn = nullptr;

1506

1507

1508 if (BeginCatchFn) {

1511 }

1512

1513

1514 if (SavedExnVar) {

1517 }

1518

1519

1521

1522

1524

1525 CGF.Builder.restoreIP(savedIP);

1526 }

1527

1528

1530}

1531

1533 if (TerminateLandingPad)

1534 return TerminateLandingPad;

1535

1536 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();

1537

1538

1540 Builder.SetInsertPoint(TerminateLandingPad);

1541

1542

1544

1545 if (CurFn->hasPersonalityFn())

1547

1548 llvm::LandingPadInst *LPadInst =

1551

1552 llvm::Value *Exn = nullptr;

1554 Exn = Builder.CreateExtractValue(LPadInst, 0);

1555 llvm::CallInst *terminateCall =

1557 terminateCall->setDoesNotReturn();

1558 Builder.CreateUnreachable();

1559

1560

1561 Builder.restoreIP(SavedIP);

1562

1563 return TerminateLandingPad;

1564}

1565

1567 if (TerminateHandler)

1568 return TerminateHandler;

1569

1570

1571

1573 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();

1574 Builder.SetInsertPoint(TerminateHandler);

1575

1576 llvm::Value *Exn = nullptr;

1579 llvm::CallInst *terminateCall =

1581 terminateCall->setDoesNotReturn();

1582 Builder.CreateUnreachable();

1583

1584

1585 Builder.restoreIP(SavedIP);

1586

1587 return TerminateHandler;

1588}

1589

1592 "use getTerminateLandingPad for non-funclet EH");

1593

1594 llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];

1595 if (TerminateFunclet)

1596 return TerminateFunclet;

1597

1598 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();

1599

1600

1601

1603 Builder.SetInsertPoint(TerminateFunclet);

1604

1605

1606

1609 if (!ParentPad)

1612

1613

1614 llvm::CallInst *terminateCall =

1616 terminateCall->setDoesNotReturn();

1617 Builder.CreateUnreachable();

1618

1619

1620 Builder.restoreIP(SavedIP);

1621

1622 return TerminateFunclet;

1623}

1624

1627

1628 CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();

1629

1630

1633

1635

1636

1637

1639 if (RethrowName != nullptr && !isCleanup) {

1642 Builder.CreateUnreachable();

1643 Builder.restoreIP(SavedIP);

1645 }

1646

1647

1650

1651 llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());

1652 llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);

1653 LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");

1654 LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");

1655

1656 Builder.CreateResume(LPadVal);

1657 Builder.restoreIP(SavedIP);

1659}

1660

1663 {

1665

1667

1668 llvm::BasicBlock *TryBB = nullptr;

1669

1673 TryBB = Builder.GetInsertBlock();

1674 }

1675

1677

1678

1679 if (TryBB) {

1682 }

1683

1685

1686 if (!TryExit.getBlock()->use_empty())

1687 EmitBlock(TryExit.getBlock(), true);

1688 else

1689 delete TryExit.getBlock();

1690 }

1692}

1693

1694

1695

1699 V.insert(BB).second ||

1700 !BB->getParent() || BB->empty())

1701 return;

1702

1703 if (!BB->isEHPad()) {

1704 for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;

1705 ++J) {

1706 if (auto LI = dyn_castllvm::LoadInst(J)) {

1707 LI->setVolatile(true);

1708 } else if (auto SI = dyn_castllvm::StoreInst(J)) {

1709 SI->setVolatile(true);

1710 } else if (auto* MCI = dyn_castllvm::MemIntrinsic(J)) {

1711 MCI->setVolatile(llvm::ConstantInt::get(Builder.getInt1Ty(), 1));

1712 }

1713 }

1714 }

1715 const llvm::Instruction *TI = BB->getTerminator();

1716 if (TI) {

1717 unsigned N = TI->getNumSuccessors();

1718 for (unsigned I = 0; I < N; I++)

1720 }

1721}

1722

1723namespace {

1725 llvm::Function *OutlinedFinally;

1726 PerformSEHFinally(llvm::Function *OutlinedFinally)

1727 : OutlinedFinally(OutlinedFinally) {}

1728

1732

1734

1735

1737 llvm::Value *FP = nullptr;

1738

1740 FP = &CGF.CurFn->arg_begin()[1];

1741 } else {

1742 llvm::Function *LocalAddrFn =

1743 CGM.getIntrinsic(llvm::Intrinsic::localaddress);

1744 FP = CGF.Builder.CreateCall(LocalAddrFn);

1745 }

1746

1747 llvm::Value *IsForEH =

1748 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());

1749

1750

1751

1752

1753

1754

1755 if (!F.isForEHCleanup() && F.hasExitSwitch()) {

1758 llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);

1759 IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);

1760 }

1761

1764

1765

1768

1771 }

1772};

1773}

1774

1775namespace {

1776

1779 const VarDecl *ParentThis;

1783 : ParentCGF(ParentCGF), ParentThis(ParentThis) {}

1784

1785

1786 bool foundCaptures() {

1787 return !Captures.empty() || SEHCodeSlot.isValid();

1788 }

1789

1790 void Visit(const Stmt *S) {

1791

1793 for (const Stmt *Child : S->children())

1794 if (Child)

1795 Visit(Child);

1796 }

1797

1798 void VisitDeclRefExpr(const DeclRefExpr *E) {

1799

1800 if (E->refersToEnclosingVariableOrCapture())

1801 Captures.insert(ParentThis);

1802

1803 const auto *D = dyn_cast(E->getDecl());

1804 if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())

1805 Captures.insert(D);

1806 }

1807

1808 void VisitCXXThisExpr(const CXXThisExpr *E) {

1809 Captures.insert(ParentThis);

1810 }

1811

1812 void VisitCallExpr(const CallExpr *E) {

1813

1814 if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)

1815 return;

1816

1817 unsigned ID = E->getBuiltinCallee();

1818 switch (ID) {

1819 case Builtin::BI__exception_code:

1820 case Builtin::BI_exception_code:

1821

1822

1823

1824 if (!SEHCodeSlot.isValid())

1826 break;

1827 }

1828 }

1829};

1830}

1831

1834 llvm::Value *ParentFP) {

1835 llvm::CallInst *RecoverCall = nullptr;

1837 if (auto *ParentAlloca =

1838 dyn_cast_or_nullllvm::AllocaInst(ParentVar.getBasePointer())) {

1839

1840

1841 auto InsertPair = ParentCGF.EscapedLocals.insert(

1842 std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));

1843 int FrameEscapeIdx = InsertPair.first->second;

1844

1845 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(

1846 &CGM.getModule(), llvm::Intrinsic::localrecover);

1847 RecoverCall = Builder.CreateCall(

1849 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});

1850

1851 } else {

1852

1853

1854

1855 auto *ParentRecover = castllvm::IntrinsicInst(

1856 ParentVar.emitRawPointer(*this)->stripPointerCasts());

1857 assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&

1858 "expected alloca or localrecover in parent LocalDeclMap");

1859 RecoverCall = castllvm::CallInst(ParentRecover->clone());

1860 RecoverCall->setArgOperand(1, ParentFP);

1862 }

1863

1864

1865 llvm::Value *ChildVar =

1866 Builder.CreateBitCast(RecoverCall, ParentVar.getType());

1867 ChildVar->setName(ParentVar.getName());

1869}

1870

1872 const Stmt *OutlinedStmt,

1873 bool IsFilter) {

1874

1876 Finder.Visit(OutlinedStmt);

1877

1878

1879

1880 if (!Finder.foundCaptures() &&

1882 if (IsFilter)

1884 return;

1885 }

1886

1887 llvm::Value *EntryFP = nullptr;

1890

1891

1892

1893 EntryFP = Builder.CreateCall(

1895 {Builder.getInt32(1)});

1896 } else {

1897

1898

1899 auto AI = CurFn->arg_begin();

1900 ++AI;

1901 EntryFP = &*AI;

1902 }

1903

1904 llvm::Value *ParentFP = EntryFP;

1905 if (IsFilter) {

1906

1907

1908

1909 llvm::Function *RecoverFPIntrin =

1912

1913

1914

1915

1916

1917

1918

1920

1921

1922

1923 llvm::AllocaInst *FramePtrAddrAlloca = nullptr;

1924 for (auto &I : ParentCGF.LocalDeclMap) {

1925 const VarDecl *D = cast(I.first);

1926 if (isa(D) &&

1928 assert(D->getName().starts_with("frame_pointer"));

1929 FramePtrAddrAlloca =

1930 castllvm::AllocaInst(I.second.getBasePointer());

1931 break;

1932 }

1933 }

1934 assert(FramePtrAddrAlloca);

1935 auto InsertPair = ParentCGF.EscapedLocals.insert(

1936 std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));

1937 int FrameEscapeIdx = InsertPair.first->second;

1938

1939

1940

1941

1942

1943

1944 llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(

1945 &CGM.getModule(), llvm::Intrinsic::localrecover);

1946 ParentFP = Builder.CreateCall(

1948 llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});

1951 }

1952 }

1953

1954

1955 for (const VarDecl *VD : Finder.Captures) {

1958 continue;

1959 }

1961 "captured non-local variable");

1962

1966 continue;

1967 }

1968

1969

1970

1971 auto I = ParentCGF.LocalDeclMap.find(VD);

1972 if (I == ParentCGF.LocalDeclMap.end())

1973 continue;

1974

1975 Address ParentVar = I->second;

1978 setAddrOfLocalVar(VD, Recovered);

1979

1980 if (isa(VD)) {

1981 CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;

1982 CXXThisAlignment = ParentCGF.CXXThisAlignment;

1986

1987

1988 LValue ThisFieldLValue =

1992 } else {

1995 }

1996 } else {

1997 CXXThisValue = CXXABIThisValue;

1998 }

1999 }

2000 }

2001

2002 if (Finder.SEHCodeSlot.isValid()) {

2005 }

2006

2007 if (IsFilter)

2009}

2010

2011

2012

2013

2015 bool IsFilter,

2016 const Stmt *OutlinedStmt) {

2018

2019

2021 {

2022 llvm::raw_svector_ostream OS(Name);

2024 assert(ParentSEHFn && "No CurSEHParent!");

2026 if (IsFilter)

2028 else

2030 }

2031

2034

2035

2036 if (IsFilter) {

2038 getContext(), nullptr, StartLoc,

2039 &getContext().Idents.get("exception_pointers"),

2041 } else {

2043 getContext(), nullptr, StartLoc,

2044 &getContext().Idents.get("abnormal_termination"),

2046 }

2048 getContext(), nullptr, StartLoc,

2051 }

2052

2054

2057

2059 llvm::Function *Fn = llvm::Function::Create(

2060 FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());

2061

2063

2067

2070}

2071

2072

2073

2074

2075llvm::Function *

2080

2081

2086

2088

2090}

2091

2092llvm::Function *

2095 const Stmt *FinallyBlock = Finally.getBlock();

2097

2098

2100

2102

2104}

2105

2107 llvm::Value *ParentFP,

2108 llvm::Value *EntryFP) {

2109

2110

2112

2116 } else {

2117

2118

2119

2120

2125 }

2126

2127

2128

2129

2130

2131

2132

2133

2134 llvm::Type *RecordTy = llvm::PointerType::getUnqual(getLLVMContext());

2135 llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);

2139 assert(SEHCodeSlotStack.empty() && "emitting EH code outside of __except");

2141}

2142

2144

2145

2147 return llvm::UndefValue::get(Int8PtrTy);

2150}

2151

2153 assert(SEHCodeSlotStack.empty() && "emitting EH code outside of __except");

2155}

2156

2158

2159

2160 auto AI = CurFn->arg_begin();

2162}

2163

2165 llvm::Function *FinallyFunc) {

2166 EHStack.pushCleanup(Kind, FinallyFunc);

2167}

2168

2171 HelperCGF.ParentCGF = this;

2172 if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {

2173

2174 llvm::Function *FinallyFunc =

2175 HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);

2176

2177

2179 return;

2180 }

2181

2182

2183 const SEHExceptStmt *Except = S.getExceptHandler();

2184 assert(Except);

2188

2189

2190

2191

2192 llvm::Constant *C =

2196 C->isOneValue()) {

2198 return;

2199 }

2200

2201

2202

2203 llvm::Function *FilterFunc =

2204 HelperCGF.GenerateSEHFilterFunction(*this, *Except);

2206}

2207

2209

2210 if (S.getFinallyHandler()) {

2212 return;

2213 }

2214

2215

2219 }

2220

2221

2222 const SEHExceptStmt *Except = S.getExceptHandler();

2223 assert(Except && "__try must have __finally xor __except");

2225

2226

2227

2228

2233 return;

2234 }

2235

2236

2238

2239

2241 Builder.CreateBr(ContBB);

2242

2243

2245

2246

2247 llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;

2249

2251

2252

2253

2254 llvm::CatchPadInst *CPI =

2255 castllvm::CatchPadInst(CatchPadBB->getFirstNonPHI());

2257 Builder.CreateCatchRet(CPI, ExceptBB);

2259

2260

2262 llvm::Function *SEHCodeIntrin =

2264 llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});

2266 }

2267

2268

2270

2271

2273

2275 Builder.CreateBr(ContBB);

2276

2278}

2279

2281

2282

2283

2286

2287

2288

2290 Builder.CreateUnreachable();

2291 Builder.ClearInsertionPoint();

2292 return;

2293 }

2294

2296}

static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)

static const EHPersonality & getObjCPersonality(const TargetInfo &Target, const LangOptions &L)

static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &T)

static const EHPersonality & getCXXPersonality(const TargetInfo &Target, const LangOptions &L)

static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)

static void emitFilterDispatchBlock(CodeGenFunction &CGF, EHFilterScope &filterScope)

Emit the dispatch block for a filter scope if necessary.

static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)

static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM)

static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM)

static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)

Check whether a landingpad instruction only uses C++ features.

static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)

Check whether a personality function could reasonably be swapped for a C++ personality function.

static void emitCatchDispatchBlock(CodeGenFunction &CGF, EHCatchScope &catchScope)

Emit the structure of the dispatch block for the given catch scope.

static llvm::Constant * getOpaquePersonalityFn(CodeGenModule &CGM, const EHPersonality &Personality)

static bool isNonEHScope(const EHScope &S)

Check whether this is a non-EH scope, i.e.

static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM, StringRef Name)

static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM)

static llvm::Constant * getCatchAllValue(CodeGenFunction &CGF)

Returns the value to inject into a selector to indicate the presence of a catch-all.

static const EHPersonality & getObjCXXPersonality(const TargetInfo &Target, const LangOptions &L)

Determines the personality function to use when both C++ and Objective-C exceptions are being caught.

static void emitWasmCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope)

static const EHPersonality & getCPersonality(const TargetInfo &Target, const LangOptions &L)

llvm::DenseSet< const void * > Visited

llvm::MachO::Target Target

Defines the Objective-C statement AST node classes.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

CanQualType UnsignedCharTy

QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const

Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.

CXXCatchStmt - This represents a C++ catch block.

Represents the this expression in C++.

A C++ throw-expression (C++ [except.throw]).

CXXTryStmt - A C++ try block, including all handlers.

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

Represents the body of a CapturedStmt, and serves as its DeclContext.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...

llvm::Value * getBasePointer() const

llvm::Value * emitRawPointer(CodeGenFunction &CGF) const

Return the pointer contained in this class after authenticating it and adding offset to it if necessa...

Address withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const

Return address with different pointer, but same element type and alignment.

Address withElementType(llvm::Type *ElemTy) const

Return address with different element type, but same pointer and alignment.

llvm::StringRef getName() const

Return the IR name of the pointer value.

llvm::PointerType * getType() const

Return the type of the pointer value.

static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)

Apply TemporaryLocation if it is valid.

llvm::StoreInst * CreateFlagStore(bool Value, llvm::Value *Addr)

Emit a store to an i1 flag variable.

llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)

llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)

Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")

llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")

llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")

Emit a load from an i1 flag variable.

llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")

virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0

virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0

virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)

virtual CatchTypeInfo getCatchAllTypeInfo()

virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0

virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0

MangleContext & getMangleContext()

Gets the mangle context.

static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())

CGFunctionInfo - Class to encapsulate the information about a function definition.

virtual llvm::Constant * GetEHType(QualType T)=0

Get the type constant to catch for the given ObjC pointer type.

virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S, bool ClearInsertionPoint=true)=0

CallArgList - Type for representing both the value and type of arguments in a call.

void add(RValue rvalue, QualType type)

void exit(CodeGenFunction &CGF)

void enter(CodeGenFunction &CGF, const Stmt *Finally, llvm::FunctionCallee beginCatchFn, llvm::FunctionCallee endCatchFn, llvm::FunctionCallee rethrowFn)

Enters a finally block for an implementation using zero-cost exceptions.

CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...

llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)

DeactivateCleanupBlock - Deactivates the given cleanup block.

void EnterSEHTryStmt(const SEHTryStmt &S)

Address getExceptionSlot()

Returns a pointer to the function's exception object and selector slot, which is assigned in every la...

void VolatilizeTryBlocks(llvm::BasicBlock *BB, llvm::SmallPtrSet< llvm::BasicBlock *, 10 > &V)

llvm::Function * GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF, const SEHFinallyStmt &Finally)

llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)

Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.

llvm::Function * GenerateSEHFilterFunction(CodeGenFunction &ParentCGF, const SEHExceptStmt &Except)

JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)

The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...

llvm::BasicBlock * getInvokeDestImpl()

bool IsOutlinedSEHHelper

True if the current function is an outlined SEH helper.

void startOutlinedSEHHelper(CodeGenFunction &ParentCGF, bool IsFilter, const Stmt *OutlinedStmt)

SmallVector< Address, 1 > SEHCodeSlotStack

A stack of exception code slots.

FieldDecl * LambdaThisCaptureField

void EmitCXXTryStmt(const CXXTryStmt &S)

void popCatchScope()

popCatchScope - Pops the catch scope at the top of the EHScope stack, emitting any required code (oth...

void EmitEndEHSpec(const Decl *D)

EmitEndEHSpec - Emit the end of the exception spec.

void EmitAnyExprToExn(const Expr *E, Address Addr)

bool isSEHTryScope() const

Returns true inside SEH __try blocks.

void EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF, llvm::Value *ParentFP, llvm::Value *EntryEBP)

llvm::BasicBlock * getEHResumeBlock(bool isCleanup)

llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)

createBasicBlock - Create an LLVM basic block.

llvm::Value * EmitSEHExceptionInfo()

const LangOptions & getLangOpts() const

llvm::BasicBlock * EHResumeBlock

EHResumeBlock - Unified block containing a call to llvm.eh.resume.

void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)

EmitBlock - Emit the given block.

llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)

CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...

llvm::AllocaInst * EHSelectorSlot

The selector slot.

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...

void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)

EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...

void EmitBlockAfterUses(llvm::BasicBlock *BB)

EmitBlockAfterUses - Emit the given block somewhere hopefully near its uses, and leave the insertion ...

RawAddress getNormalCleanupDestSlot()

llvm::BasicBlock * getTerminateFunclet()

getTerminateLandingPad - Return a cleanup funclet that just calls terminate.

llvm::Type * ConvertTypeForMem(QualType T)

const Decl * CurCodeDecl

CurCodeDecl - This is the inner-most code context, which includes blocks.

llvm::BasicBlock * getUnreachableBlock()

llvm::AssertingVH< llvm::Instruction > AllocaInsertPt

AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...

bool currentFunctionUsesSEHTry() const

llvm::SmallVector< const JumpDest *, 2 > SEHTryEpilogueStack

CodeGenFunction * ParentCGF

llvm::Value * ExceptionSlot

The exception slot.

RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)

CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...

void EmitSEHLeaveStmt(const SEHLeaveStmt &S)

const TargetInfo & getTarget() const

llvm::Value * EmitSEHExceptionCode()

void pushSEHCleanup(CleanupKind kind, llvm::Function *FinallyFunc)

void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())

Emit code for the start of a function.

void EmitSehTryScopeBegin()

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

Address recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF, Address ParentVar, llvm::Value *ParentFP)

Recovers the address of a local in a parent function.

void EmitSEHTryStmt(const SEHTryStmt &S)

void ExitSEHTryStmt(const SEHTryStmt &S)

llvm::BasicBlock * getTerminateLandingPad()

getTerminateLandingPad - Return a landing pad that just calls terminate.

llvm::BasicBlock * getTerminateHandler()

getTerminateHandler - Return a handler (not a landing pad, just a catch handler) that just calls term...

const TargetCodeGenInfo & getTargetHooks() const

void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)

void EmitStartEHSpec(const Decl *D)

EmitStartEHSpec - Emit the start of the exception spec.

RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)

EmitCall - Generate a call of the given function, expecting the given result type,...

llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

ASTContext & getContext() const

void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)

void EmitBranchThroughCleanup(JumpDest Dest)

EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...

llvm::Value * SEHInfo

Value returned by __exception_info intrinsic.

void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})

EmitStmt - Emit the code for the statement.

void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)

PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.

llvm::BasicBlock * EmitLandingPad()

Emits a landing pad for the current EH stack.

llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields

llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")

llvm::Type * ConvertType(QualType T)

void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)

llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")

void EmitCapturedLocals(CodeGenFunction &ParentCGF, const Stmt *OutlinedStmt, bool IsFilter)

Scan the outlined statement for captures from the parent function.

llvm::BasicBlock * getFuncletEHDispatchBlock(EHScopeStack::stable_iterator scope)

llvm::Value * EmitSEHAbnormalTermination()

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

void EmitStopPoint(const Stmt *S)

EmitStopPoint - Emit a debug stoppoint if we are emitting debug info.

void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)

llvm::Instruction * CurrentFuncletPad

void EnsureInsertPoint()

EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.

llvm::LLVMContext & getLLVMContext()

llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)

EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...

void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)

Increment the profiler's counter for the given statement by StepV.

llvm::Value * getSelectorFromSlot()

llvm::Value * getExceptionFromSlot()

Returns the contents of the function's exception object and selector slots.

Address getEHSelectorSlot()

LValue EmitLValueForLambdaField(const FieldDecl *Field)

This class organizes the cross-function state that is used while generating LLVM code.

void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)

Set the attributes on the LLVM function for the given decl and function info.

llvm::Module & getModule() const

llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)

Create or return a runtime function declaration with the specified type and name.

llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)

Get the address of the RTTI descriptor for the given type.

DiagnosticsEngine & getDiags() const

void ErrorUnsupported(const Stmt *S, const char *Type)

Print out an error that codegen doesn't support the specified stmt yet.

const LangOptions & getLangOpts() const

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

CGCXXABI & getCXXABI() const

ASTContext & getContext() const

llvm::FunctionCallee getTerminateFn()

Get the declaration of std::terminate for the platform.

llvm::LLVMContext & getLLVMContext()

llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})

CGObjCRuntime & getObjCRuntime()

Return a reference to the configured Objective-C runtime.

LangAS GetGlobalVarAddressSpace(const VarDecl *D)

Return the AST address space of the underlying global variable for D, as determined by its declaratio...

llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)

GetFunctionType - Get the LLVM function type for.

const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)

A builtin function is a freestanding function using the default C conventions.

const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)

llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)

Try to emit the result of the given expression as an abstract constant.

A scope which attempts to handle some, possibly all, types of exceptions.

const Handler & getHandler(unsigned I) const

void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)

void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)

void clearHandlerBlocks()

unsigned getNumHandlers() const

An exceptions scope which filters exceptions thrown through it.

llvm::Value * getFilter(unsigned i) const

unsigned getNumFilters() const

Information for lazily generating a cleanup.

A non-stable pointer into the scope stack.

A saved depth on the scope stack.

class EHFilterScope * pushFilter(unsigned NumFilters)

Push an exceptions filter on the stack.

stable_iterator stable_begin() const

Create a stable reference to the top of the EH stack.

stable_iterator getInnermostEHScope() const

bool requiresLandingPad() const

bool empty() const

Determines whether the exception-scopes stack is empty.

iterator end() const

Returns an iterator pointing to the outermost EH scope.

void popFilter()

Pops an exceptions filter off the stack.

iterator begin() const

Returns an iterator pointing to the innermost EH scope.

void popCatch()

Pops a catch scope off the stack. This is private to CGException.cpp.

class EHCatchScope * pushCatch(unsigned NumHandlers)

Push a set of catch handlers on the stack.

iterator find(stable_iterator save) const

Turn a stable reference to a scope depth into a unstable pointer to the EH stack.

static stable_iterator stable_end()

Create a stable reference to the bottom of the EH stack.

void popTerminate()

Pops a terminate handler off the stack.

void pushTerminate()

Push a terminate handler on the stack.

A protected scope for zero-cost EH handling.

llvm::BasicBlock * getCachedLandingPad() const

EHScopeStack::stable_iterator getEnclosingEHScope() const

llvm::BasicBlock * getCachedEHDispatchBlock() const

void setCachedEHDispatchBlock(llvm::BasicBlock *block)

bool hasEHBranches() const

FunctionArgList - Type for representing both the decl and type of parameters to a function.

LValue - This represents an lvalue references.

Address getAddress() const

static RValue get(llvm::Value *V)

llvm::Value * getScalarVal() const

getScalarVal() - Return the Value* of this scalar value.

ReturnValueSlot - Contains the address where the return value of a function can be stored,...

Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const

ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.

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

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

SourceLocation getLocation() const

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

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...

Represents a function declaration or definition.

bool usesSEHTry() const

Indicates the function uses __try.

SourceRange getExceptionSpecSourceRange() const

Attempt to compute an informative source range covering the function exception specification,...

Represents a prototype with parameter type info, e.g.

ExceptionSpecificationType getExceptionSpecType() const

Get the kind of exception specification on this function.

QualType getExceptionType(unsigned i) const

Return the ith exception type, where 0 <= i < getNumExceptions().

unsigned getNumExceptions() const

Return the number of types in the exception specification.

CanThrowResult canThrow() const

Determine whether this function type has a non-throwing exception specification.

GlobalDecl - represents a global declaration.

const Decl * getDecl() const

static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)

Create implicit parameter.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

bool hasWasmExceptions() const

clang::ObjCRuntime ObjCRuntime

bool hasSjLjExceptions() const

bool hasDWARFExceptions() const

bool hasSEHExceptions() const

MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...

virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl, raw_ostream &Out)=0

virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl, raw_ostream &Out)=0

Represents Objective-C's @throw statement.

The basic abstraction for the target Objective-C runtime.

bool hasTerminate() const

Does this runtime provide an objc_terminate function?

bool isNeXTFamily() const

Is this runtime basically of the NeXT family of runtimes?

const VersionTuple & getVersion() const

@ MacOSX

'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...

@ FragileMacOSX

'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...

@ GNUstep

'gnustep' is the modern non-fragile GNUstep runtime.

@ ObjFW

'objfw' is the Objective-C runtime included in ObjFW

@ iOS

'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...

@ GCC

'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI

@ WatchOS

'watchos' is a variant of iOS for Apple's watchOS.

A (possibly-)qualified type.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

QualType getNonReferenceType() const

If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

The collection of all-type qualifiers we support.

CompoundStmt * getBlock() const

Expr * getFilterExpr() const

CompoundStmt * getBlock() const

Represents a __leave statement.

Smart pointer class that efficiently represents Objective-C method names.

Encodes a location in the source.

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

SourceLocation getBeginLoc() const LLVM_READONLY

bool isMicrosoft() const

Is this ABI an MSVC-compatible ABI?

Exposes information about the current target.

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

bool isSignedIntegerType() const

Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...

bool isPointerType() const

bool isVariablyModifiedType() const

Whether this type is a variably-modified type (C99 6.7.5).

bool isObjCObjectPointerType() const

const T * getAs() const

Member-template getAs'.

Represents a variable declaration or definition.

bool isLocalVarDeclOrParm() const

Similar to isLocalVarDecl but also includes parameters.

@ NormalCleanup

Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...

@ EHCleanup

Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...

tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, ArrayRef< tooling::Range > Ranges, StringRef FileName="")

Clean up any erroneous/redundant code in the given Ranges in Code.

bool Zero(InterpState &S, CodePtr OpPC)

bool Load(InterpState &S, CodePtr OpPC)

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

LangAS

Defines the address space values used by the address space qualifier of QualType.

const FunctionProtoType * T

@ Other

Other implicit parameter.

ExceptionSpecificationType

The various types of exception specifications that exist in C++11.

@ EST_Dynamic

throw(T1, T2)

The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...

llvm::PointerType * VoidPtrTy

CharUnits getIntAlign() const

llvm::IntegerType * Int8Ty

i8, i16, i32, and i64

llvm::IntegerType * Int32Ty

llvm::IntegerType * IntTy

int

llvm::PointerType * Int8PtrTy

CharUnits getPointerAlign() const

llvm::PointerType * AllocaInt8PtrTy

CatchTypeInfo Type

A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.

llvm::BasicBlock * Block

The catch handler for this type.

The exceptions personality for a function.

static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)

static const EHPersonality XL_CPlusPlus

static const EHPersonality GNU_ObjC_SJLJ

bool isWasmPersonality() const

static const EHPersonality ZOS_CPlusPlus

static const EHPersonality GNUstep_ObjC

static const EHPersonality MSVC_CxxFrameHandler3

bool usesFuncletPads() const

Does this personality use landingpads or the family of pad instructions designed to form funclets?

static const EHPersonality MSVC_C_specific_handler

static const EHPersonality GNU_CPlusPlus_SEH

static const EHPersonality GNU_ObjC

static const EHPersonality GNU_CPlusPlus_SJLJ

static const EHPersonality GNU_C_SJLJ

static const EHPersonality GNU_C

static const EHPersonality NeXT_ObjC

const char * CatchallRethrowFn

static const EHPersonality GNU_CPlusPlus

static const EHPersonality GNU_ObjCXX

static const EHPersonality GNU_C_SEH

static const EHPersonality MSVC_except_handler

static const EHPersonality GNU_ObjC_SEH

const char * PersonalityFn

static const EHPersonality GNU_Wasm_CPlusPlus