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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

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

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

29

30using namespace clang;

32

34

35

36 llvm::FunctionType *FTy =

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

38

40}

41

43 llvm::FunctionType *FTy =

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

46}

47

49 llvm::FunctionType *FTy =

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

52}

53

55

56

57 llvm::FunctionType *FTy =

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

59

61}

62

64

65

66 llvm::FunctionType *FTy =

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

68

69 StringRef name;

70

71

74 name = "_ZSt9terminatev";

78 name = "__std_terminate";

79 else

80 name = "?terminate@@YAXXZ";

83 name = "objc_terminate";

84 else

85 name = "abort";

87}

88

90 StringRef Name) {

91 llvm::FunctionType *FTy =

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

93

95}

96

129 nullptr};

131 nullptr};

132

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

136 if (T.isWindowsMSVCEnvironment())

145}

146

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

151 if (T.isWindowsMSVCEnvironment())

153

162 if (T.isOSCygMing())

166 [[fallthrough]];

174 }

175 llvm_unreachable("bad runtime kind");

176}

177

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

181 if (T.isWindowsMSVCEnvironment())

183 if (T.isOSAIX())

193 if (T.isOSzOS())

196}

197

198

199

203 if (Target.getTriple().isWindowsMSVCEnvironment())

205

207

208

211

212

213

214

219

223

224

225

229 }

230 llvm_unreachable("bad runtime kind");

231}

232

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

237}

238

245

246

249

250 if (L.ObjC)

255}

256

259

260

261

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

264}

265

270 llvm::AttributeList(), true);

271}

272

278

279

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

282

283

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

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

286

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

288

289

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

291 return false;

292 } else {

293

295 for (llvm::User::op_iterator

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

297 if (llvm::GlobalVariable *GV =

299

300

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

302 return false;

303 }

304 }

305 }

306 return true;

307}

308

309

310

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

313

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

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

317 return false;

318 continue;

319 }

320

321

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

323 if (!F) return false;

324

325 for (llvm::BasicBlock &BB : *F) {

326 if (BB.isLandingPad())

328 return false;

329 }

330 }

331

332 return true;

333}

334

335

336

337

338

339void CodeGenModule::SimplifyPersonality() {

340

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

342 return;

343

344

345

346 if (!LangOpts.ObjCRuntime.isNeXTFamily())

347 return;

348

352 return;

353

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

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

356

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

358

359

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

361

362

364

365

366

368

369

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

371 return;

372

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

374 Fn->eraseFromParent();

375}

376

377

378

380

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

382}

383

384namespace {

385

386

387 struct FreeException final : EHScopeStack::Cleanup {

388 llvm::Value *exn;

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

390 void Emit(CodeGenFunction &CGF, Flags flags) override {

392 }

393 };

394}

395

396

397

398

399

401

402

405

406

407

410

411

412

413

414

415

416

417

419 true);

420

421

424}

425

431

437

441

445

447 bool KeepInsertionPoint) {

448

449

450

451

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

453 if (CGM.getLangOpts().OpenMPIsTargetDevice && T.isGPU()) {

455 return;

456 }

458 QualType ThrowType = SubExpr->getType();

462 CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);

463 } else {

464 CGM.getCXXABI().emitThrow(*this, E);

465 }

466 } else {

467 CGM.getCXXABI().emitRethrow(*this, true);

468 }

469

470

471

472 if (KeepInsertionPoint)

474}

475

477 if (CGM.getLangOpts().CXXExceptions)

478 return;

479

480 const FunctionDecl* FD = dyn_cast_or_null(D);

481 if (!FD) {

482

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

484 if (CD->isNothrow())

486 }

487 return;

488 }

490 if (!Proto)

491 return;

492

494

495

496

499

500

501 if (getTarget().getCXXABI().isMicrosoft())

502 return;

503

504

505

506 if (CGM.getCodeGenOpts().hasWasmExceptions()) {

509 else

511 diag::warn_wasm_dynamic_exception_spec_ignored)

513 return;

514 }

515

516

517

518

519

520 if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&

521 CGM.getCodeGenOpts().getExceptionHandling() ==

525 diag::warn_wasm_dynamic_exception_spec_ignored)

527

530

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

534 llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,

535 true);

536 Filter->setFilter(I, EHType);

537 }

539

540 if (getLangOpts().EHAsynch)

542 }

543}

544

545

549 if (!dispatchBlock) return;

550 if (dispatchBlock->use_empty()) {

551 delete dispatchBlock;

552 return;

553 }

554

556

557

558

560

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

563

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

565 llvm::Value *failsFilter =

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

567 CGF.Builder.CreateCondBr(failsFilter, unexpectedBB,

569

571 }

572

573

574

575

576

579 ->setDoesNotReturn();

580 CGF.Builder.CreateUnreachable();

581}

582

584 if (CGM.getLangOpts().CXXExceptions)

585 return;

586

587 const FunctionDecl* FD = dyn_cast_or_null(D);

588 if (!FD) {

589

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

591 if (CD->isNothrow() && EHStack.empty())

593 }

594 return;

595 }

597 if (!Proto)

598 return;

599

603

604

605 if (getTarget().getCXXABI().isMicrosoft())

606 return;

607

608

609

610 if (CGM.getCodeGenOpts().hasWasmExceptions()) {

613 return;

614 }

619

622 }

623}

624

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

627

628

629 const bool IsTargetDevice =

630 (CGM.getLangOpts().OpenMPIsTargetDevice && T.isGPU());

631 if (!IsTargetDevice)

634 if (!IsTargetDevice)

636}

637

641

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

644

646 if (C->getExceptionDecl()) {

647

648

649

650

651

652

654 QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(

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

656

659 TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);

660 else

661 TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(

662 CaughtType, C->getCaughtType());

664 } else {

665

666 CatchScope->setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);

667

668

671 }

672 }

673}

674

675llvm::BasicBlock *

679

680

681

682 if (si == EHStack.stable_end())

684

685

687

689 if (!dispatchBlock) {

690 switch (scope.getKind()) {

692

697

698

699 } else {

701 }

702 break;

703 }

704

707 break;

708

711 break;

712

715 break;

716 }

718 }

719 return dispatchBlock;

720}

721

722llvm::BasicBlock *

724

725

726 if (SI == EHStack.stable_end())

727 return nullptr;

728

729

731

733 if (DispatchBlock)

734 return DispatchBlock;

735

738 else

741

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

745 break;

746

748 DispatchBlock->setName("ehcleanup");

749 break;

750

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

753

755 DispatchBlock->setName("terminate");

756 break;

757 }

759 return DispatchBlock;

760}

761

762

763

764

772 return false;

773 }

774

775 llvm_unreachable("Invalid EHScope Kind!");

776}

777

779 assert(EHStack.requiresLandingPad());

780 assert(EHStack.empty());

781

782

783

784

785

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

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

789 return nullptr;

791 return nullptr;

792 }

793

794

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

796 return nullptr;

797

798

799

800 llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();

801 if (LP) return LP;

802

804

805 if (CurFn->hasPersonalityFn())

807

809

811 } else {

812

814 }

815

816 assert(LP);

817

818

819

821 ir->setCachedLandingPad(LP);

823 }

824

825 return LP;

826}

827

829 assert(EHStack.requiresLandingPad());

830 assert(CGM.getLangOpts().IgnoreExceptions &&

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

832 "effect.");

834 switch (innermostEHScope.getKind()) {

837

842 return lpad;

843 }

844

845

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

848

849

852

853 llvm::LandingPadInst *LPadInst =

855

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

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

860

861

862

863

864

865

866

867 bool hasCatchAll = false;

868 bool hasCleanup = false;

869 bool hasFilter = false;

873 ++I) {

874

875 switch (I->getKind()) {

877

879 continue;

880

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

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

884

885

887 hasFilter = true;

888

889

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

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

892 goto done;

893 }

894

896

897 assert(!hasCatchAll);

898 hasCatchAll = true;

899 goto done;

900

902 break;

903 }

904

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

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

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

910

911

913 assert(!hasCatchAll);

914 hasCatchAll = true;

915 goto done;

916 }

917

918

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

920

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

922 }

923 }

924

925 done:

926

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

928 if (hasCatchAll) {

930

931

932

933 } else if (hasFilter) {

934

935

936

938 llvm::ArrayType *AType =

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

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

941 filterTypes.size());

942

943 for (llvm::Value *filterType : filterTypes)

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

946 LPadInst->addClause(FilterArray);

947

948

949 if (hasCleanup)

950 LPadInst->setCleanup(true);

951

952

953 } else if (hasCleanup) {

954 LPadInst->setCleanup(true);

955 }

956

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

958 "landingpad instruction has no clauses!");

959

960

962

963

964 Builder.restoreIP(savedIP);

965

966 return lpad;

967}

968

971 assert(DispatchBlock);

972

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

975

977 if (!ParentPad)

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

979 llvm::BasicBlock *UnwindBB =

981

983 llvm::CatchSwitchInst *CatchSwitch =

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

985

986

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

989

993

995

997 CGF.Builder.CreateCatchPad(

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

1000 } else {

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

1002 }

1003

1004 CatchSwitch->addHandler(Handler.Block);

1005 }

1006 CGF.Builder.restoreIP(SavedIP);

1007}

1008

1009

1010

1011

1015 assert(DispatchBlock);

1016

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

1019

1021 if (!ParentPad)

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

1023 llvm::BasicBlock *UnwindBB =

1025

1027 llvm::CatchSwitchInst *CatchSwitch =

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

1029

1030

1031

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

1033 CatchSwitch->addHandler(WasmCatchStartBlock);

1035

1036

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

1043 CatchTypes.push_back(TypeInfo.RTTI);

1044 }

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

1046

1047

1048

1049

1050 llvm::Function *GetExnFn =

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

1052 llvm::Function *GetSelectorFn =

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

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

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

1057

1058 llvm::Function *TypeIDFn =

1060

1061

1065 CGF.Builder.restoreIP(SavedIP);

1066 return;

1067 }

1068

1069

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

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

1076

1077

1078 llvm::BasicBlock *NextBlock;

1079

1080 bool EmitNextBlock = false, NextIsEnd = false;

1081

1082

1083

1084

1085 if (I + 1 == E) {

1087 EmitNextBlock = true;

1088 NextIsEnd = true;

1089

1090

1091

1094 NextIsEnd = true;

1095

1096

1097 } else {

1099 EmitNextBlock = true;

1100 }

1101

1102

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

1104 TypeIndex->setDoesNotThrow();

1105

1106 llvm::Value *MatchesTypeIndex =

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

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

1109

1110 if (EmitNextBlock)

1112 if (NextIsEnd)

1113 break;

1114 }

1115

1116 CGF.Builder.restoreIP(SavedIP);

1117}

1118

1119

1120

1127

1129 assert(dispatchBlock);

1130

1131

1132

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

1136 return;

1137 }

1138

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

1141

1142

1143 llvm::Function *llvm_eh_typeid_for =

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

1147

1148

1150

1151

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

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

1155

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

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

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

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

1160

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

1163 globAS, argTy);

1164

1165

1166 bool nextIsEnd;

1167 llvm::BasicBlock *nextBlock;

1168

1169

1170

1171 if (i + 1 == e) {

1173 nextIsEnd = true;

1174

1175

1176

1179 nextIsEnd = true;

1180

1181

1182 } else {

1184 nextIsEnd = false;

1185 }

1186

1187

1188 llvm::CallInst *typeIndex =

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

1190 typeIndex->setDoesNotThrow();

1191

1192 llvm::Value *matchesTypeIndex =

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

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

1195

1196

1197 if (nextIsEnd) {

1198 CGF.Builder.restoreIP(savedIP);

1199 return;

1200 }

1201

1203 }

1204}

1205

1212

1218

1219

1223 return;

1224 }

1225

1226

1228

1229

1230

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

1233

1235

1236

1238

1239

1241 Builder.CreateBr(ContBB);

1242

1243

1244

1245 bool doImplicitRethrow = false;

1246 if (IsFnTryBlock)

1249

1250

1251

1252

1254 llvm::BasicBlock *WasmCatchStartBlock = nullptr;

1256 auto *CatchSwitch =

1258 WasmCatchStartBlock = CatchSwitch->hasUnwindDest()

1259 ? CatchSwitch->getSuccessor(1)

1260 : CatchSwitch->getSuccessor(0);

1261 auto *CPI =

1264 }

1265

1266

1267

1268

1269

1270

1271

1272

1273 bool HasCatchAll = false;

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

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

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

1278

1279

1281

1282

1283

1285

1286

1288 CGM.getCXXABI().emitBeginCatch(*this, C);

1289

1290

1292

1293

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304

1306 CGM.getCXXABI().emitRethrow(*this, false);

1307 Builder.CreateUnreachable();

1308 Builder.ClearInsertionPoint();

1309 }

1310

1311

1313

1314

1316 Builder.CreateBr(ContBB);

1317 }

1318

1319

1320

1321

1322

1323 if (EHPersonality::get(*this).isWasmPersonality() && !HasCatchAll) {

1324 assert(WasmCatchStartBlock);

1325

1326

1327

1328

1329 llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;

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

1332 assert(BI->isConditional());

1333 RethrowBlock = BI->getSuccessor(1);

1334 }

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

1336 Builder.SetInsertPoint(RethrowBlock);

1337 llvm::Function *RethrowInCatchFn =

1338 CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);

1340 }

1341

1344}

1345

1346namespace {

1347 struct CallEndCatchForFinally final : EHScopeStack::Cleanup {

1348 llvm::Value *ForEHVar;

1349 llvm::FunctionCallee EndCatchFn;

1350 CallEndCatchForFinally(llvm::Value *ForEHVar,

1351 llvm::FunctionCallee EndCatchFn)

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

1353

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

1356 llvm::BasicBlock *CleanupContBB =

1358

1359 llvm::Value *ShouldEndCatch =

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

1365 }

1366 };

1367

1368 struct PerformFinally final : EHScopeStack::Cleanup {

1369 const Stmt *Body;

1370 llvm::Value *ForEHVar;

1371 llvm::FunctionCallee EndCatchFn;

1372 llvm::FunctionCallee RethrowFn;

1373 llvm::Value *SavedExnVar;

1374

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

1376 llvm::FunctionCallee EndCatchFn,

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

1378 : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),

1379 RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}

1380

1381 void Emit(CodeGenFunction &CGF, Flags flags) override {

1382

1383 if (EndCatchFn)

1385 ForEHVar, EndCatchFn);

1386

1387

1388

1389 llvm::Value *SavedCleanupDest =

1391 "cleanup.dest.saved");

1392

1393

1395

1396

1397

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

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

1401

1402 llvm::Value *ShouldRethrow =

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

1405

1407 if (SavedExnVar) {

1411 } else {

1413 }

1414 CGF.Builder.CreateUnreachable();

1415

1417

1418

1421 }

1422

1423

1424

1425

1426 if (EndCatchFn) {

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

1429 CGF.Builder.restoreIP(SavedIP);

1430 }

1431

1432

1433

1435 }

1436 };

1437}

1438

1439

1440

1441

1443 llvm::FunctionCallee beginCatchFn,

1444 llvm::FunctionCallee endCatchFn,

1445 llvm::FunctionCallee rethrowFn) {

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

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

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

1449

1450 BeginCatchFn = beginCatchFn;

1451

1452

1453

1454

1455

1456

1457

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

1459 SavedExnVar = nullptr;

1460 if (rethrowFnTy->getNumParams())

1462

1463

1464

1465

1466

1467

1468

1469

1470

1471

1472

1473

1474

1475

1476

1477

1479

1480

1483

1484

1486 ForEHVar, endCatchFn,

1487 rethrowFn, SavedExnVar);

1488

1489

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

1493}

1494

1496

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

1499

1501

1502

1503 if (catchBB->use_empty()) {

1504 delete catchBB;

1505 } else {

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

1508

1509 llvm::Value *exn = nullptr;

1510

1511

1512 if (BeginCatchFn) {

1515 }

1516

1517

1518 if (SavedExnVar) {

1521 }

1522

1523

1525

1526

1528

1529 CGF.Builder.restoreIP(savedIP);

1530 }

1531

1532

1534}

1535

1537 if (TerminateLandingPad)

1538 return TerminateLandingPad;

1539

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

1541

1542

1544 Builder.SetInsertPoint(TerminateLandingPad);

1545

1546

1548

1549 if (CurFn->hasPersonalityFn())

1551

1552 llvm::LandingPadInst *LPadInst =

1555

1556 llvm::Value *Exn = nullptr;

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

1559 llvm::CallInst *terminateCall =

1560 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);

1561 terminateCall->setDoesNotReturn();

1562 Builder.CreateUnreachable();

1563

1564

1565 Builder.restoreIP(SavedIP);

1566

1567 return TerminateLandingPad;

1568}

1569

1571 if (TerminateHandler)

1572 return TerminateHandler;

1573

1574

1575

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

1578 Builder.SetInsertPoint(TerminateHandler);

1579

1580 llvm::Value *Exn = nullptr;

1583 llvm::CallInst *terminateCall =

1584 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);

1585 terminateCall->setDoesNotReturn();

1586 Builder.CreateUnreachable();

1587

1588

1589 Builder.restoreIP(SavedIP);

1590

1591 return TerminateHandler;

1592}

1593

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

1597

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

1599 if (TerminateFunclet)

1600 return TerminateFunclet;

1601

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

1603

1604

1605

1607 Builder.SetInsertPoint(TerminateFunclet);

1608

1609

1610

1613 if (!ParentPad)

1614 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());

1616

1617

1618 llvm::CallInst *terminateCall =

1619 CGM.getCXXABI().emitTerminateForUnexpectedException(*this, nullptr);

1620 terminateCall->setDoesNotReturn();

1621 Builder.CreateUnreachable();

1622

1623

1624 Builder.restoreIP(SavedIP);

1625

1626 return TerminateFunclet;

1627}

1628

1631

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

1633

1634

1637

1639

1640

1641

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

1646 Builder.CreateUnreachable();

1647 Builder.restoreIP(SavedIP);

1649 }

1650

1651

1654

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

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

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

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

1659

1660 Builder.CreateResume(LPadVal);

1661 Builder.restoreIP(SavedIP);

1663}

1664

1667 {

1669

1671

1672 llvm::BasicBlock *TryBB = nullptr;

1673

1677 TryBB = Builder.GetInsertBlock();

1678 }

1679

1681

1682

1683 if (TryBB) {

1686 }

1687

1689

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

1692 else

1694 }

1696}

1697

1698

1699

1703 V.insert(BB).second ||

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

1705 return;

1706

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

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

1709 ++J) {

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

1711 LI->setVolatile(true);

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

1713 SI->setVolatile(true);

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

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

1716 }

1717 }

1718 }

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

1720 if (TI) {

1721 unsigned N = TI->getNumSuccessors();

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

1724 }

1725}

1726

1727namespace {

1728struct PerformSEHFinally final : EHScopeStack::Cleanup {

1729 llvm::Function *OutlinedFinally;

1730 PerformSEHFinally(llvm::Function *OutlinedFinally)

1731 : OutlinedFinally(OutlinedFinally) {}

1732

1736

1738

1739

1740 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};

1741 llvm::Value *FP = nullptr;

1742

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

1745 } else {

1746 llvm::Function *LocalAddrFn =

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

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

1749 }

1750

1751 llvm::Value *IsForEH =

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

1753

1754

1755

1756

1757

1758

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

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

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

1764 }

1765

1768

1769

1770 const CGFunctionInfo &FnInfo =

1772

1774 CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);

1775 }

1776};

1777}

1778

1779namespace {

1780

1781struct CaptureFinder : ConstStmtVisitor {

1782 CodeGenFunction &ParentCGF;

1783 const VarDecl *ParentThis;

1784 llvm::SmallSetVector<const VarDecl *, 4> Captures;

1786 CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)

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

1788

1789

1790 bool foundCaptures() {

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

1792 }

1793

1794 void Visit(const Stmt *S) {

1795

1796 ConstStmtVisitor::Visit(S);

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

1798 if (Child)

1799 Visit(Child);

1800 }

1801

1802 void VisitDeclRefExpr(const DeclRefExpr *E) {

1803

1805 Captures.insert(ParentThis);

1806

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

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

1809 Captures.insert(D);

1810 }

1811

1812 void VisitCXXThisExpr(const CXXThisExpr *E) {

1813 Captures.insert(ParentThis);

1814 }

1815

1816 void VisitCallExpr(const CallExpr *E) {

1817

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

1819 return;

1820

1822 switch (ID) {

1823 case Builtin::BI__exception_code:

1824 case Builtin::BI_exception_code:

1825

1826

1827

1828 if (!SEHCodeSlot.isValid())

1830 break;

1831 }

1832 }

1833};

1834}

1835

1838 llvm::Value *ParentFP) {

1839 llvm::CallInst *RecoverCall = nullptr;

1841 if (auto *ParentAlloca =

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

1843

1844

1845 auto InsertPair = ParentCGF.EscapedLocals.insert(

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

1847 int FrameEscapeIdx = InsertPair.first->second;

1848

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

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

1851 RecoverCall = Builder.CreateCall(

1852 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,

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

1854

1855 } else {

1856

1857

1858

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

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

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

1864 RecoverCall->setArgOperand(1, ParentFP);

1865 RecoverCall->insertBefore(AllocaInsertPt->getIterator());

1866 }

1867

1868

1869 llvm::Value *ChildVar =

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

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

1873}

1874

1876 const Stmt *OutlinedStmt,

1877 bool IsFilter) {

1878

1880 Finder.Visit(OutlinedStmt);

1881

1882

1883

1884 if (!Finder.foundCaptures() &&

1885 CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {

1886 if (IsFilter)

1888 return;

1889 }

1890

1891 llvm::Value *EntryFP = nullptr;

1893 if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {

1894

1895

1896

1897 EntryFP = Builder.CreateCall(

1899 {Builder.getInt32(1)});

1900 } else {

1901

1902

1903 auto AI = CurFn->arg_begin();

1904 ++AI;

1905 EntryFP = &*AI;

1906 }

1907

1908 llvm::Value *ParentFP = EntryFP;

1909 if (IsFilter) {

1910

1911

1912

1913 llvm::Function *RecoverFPIntrin =

1914 CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);

1915 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentCGF.CurFn, EntryFP});

1916

1917

1918

1919

1920

1921

1922

1923 if (ParentCGF.ParentCGF != nullptr) {

1924

1925

1926

1927 llvm::AllocaInst *FramePtrAddrAlloca = nullptr;

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

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

1933 FramePtrAddrAlloca =

1935 break;

1936 }

1937 }

1938 assert(FramePtrAddrAlloca);

1939 auto InsertPair = ParentCGF.EscapedLocals.insert(

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

1941 int FrameEscapeIdx = InsertPair.first->second;

1942

1943

1944

1945

1946

1947

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

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

1950 ParentFP = Builder.CreateCall(

1951 FrameRecoverFn, {ParentCGF.CurFn, ParentFP,

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

1953 ParentFP = Builder.CreateLoad(

1955 }

1956 }

1957

1958

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

1961 CGM.ErrorUnsupported(VD, "VLA captured by SEH");

1962 continue;

1963 }

1965 "captured non-local variable");

1966

1967 auto L = ParentCGF.LambdaCaptureFields.find(VD);

1968 if (L != ParentCGF.LambdaCaptureFields.end()) {

1970 continue;

1971 }

1972

1973

1974

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

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

1977 continue;

1978

1979 Address ParentVar = I->second;

1982 setAddrOfLocalVar(VD, Recovered);

1983

1985 CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;

1986 CXXThisAlignment = ParentCGF.CXXThisAlignment;

1987 CXXABIThisValue = Builder.CreateLoad(Recovered, "this");

1988 if (ParentCGF.LambdaThisCaptureField) {

1990

1991

1992 LValue ThisFieldLValue =

1996 } else {

1999 }

2000 } else {

2001 CXXThisValue = CXXABIThisValue;

2002 }

2003 }

2004 }

2005

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

2009 }

2010

2011 if (IsFilter)

2013}

2014

2015

2016

2017

2019 bool IsFilter,

2020 const Stmt *OutlinedStmt) {

2022

2023

2025 {

2026 llvm::raw_svector_ostream OS(Name);

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

2029 MangleContext &Mangler = CGM.getCXXABI().getMangleContext();

2030 if (IsFilter)

2032 else

2034 }

2035

2037 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {

2038

2039

2040 if (IsFilter) {

2042 getContext(), nullptr, StartLoc,

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

2045 } else {

2047 getContext(), nullptr, StartLoc,

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

2050 }

2052 getContext(), nullptr, StartLoc,

2055 }

2056

2058

2060 CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);

2061

2062 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);

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

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

2065

2067

2071

2074}

2075

2076

2077

2078

2079llvm::Function *

2084

2085

2090

2092

2094}

2095

2096llvm::Function *

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

2101

2102

2104

2106

2108}

2109

2111 llvm::Value *ParentFP,

2112 llvm::Value *EntryFP) {

2113

2114

2115 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {

2116

2120 } else {

2121

2122

2123

2124

2129 }

2130

2131

2132

2133

2134

2135

2136

2137

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

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

2140 llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, SEHInfo, 0);

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

2145}

2146

2148

2149

2151 return llvm::PoisonValue::get(Int8PtrTy);

2154}

2155

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

2159}

2160

2162

2163

2164 auto AI = CurFn->arg_begin();

2166}

2167

2169 llvm::Function *FinallyFunc) {

2170 EHStack.pushCleanup(Kind, FinallyFunc);

2171}

2172

2174 CodeGenFunction HelperCGF(CGM, true);

2177

2178 llvm::Function *FinallyFunc =

2180

2181

2183 return;

2184 }

2185

2186

2188 assert(Except);

2192

2193

2194

2195

2196 llvm::Constant *C =

2199 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&

2200 C->isOneValue()) {

2202 return;

2203 }

2204

2205

2206

2207 llvm::Function *FilterFunc =

2210}

2211

2213

2216 return;

2217 }

2218

2219

2223 }

2224

2225

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

2229

2230

2231

2232

2237 return;

2238 }

2239

2240

2242

2243

2245 Builder.CreateBr(ContBB);

2246

2247

2249

2250

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

2253

2255

2256

2257

2258 llvm::CatchPadInst *CPI =

2261 Builder.CreateCatchRet(CPI, ExceptBB);

2263

2264

2265 if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {

2266 llvm::Function *SEHCodeIntrin =

2267 CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);

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

2270 }

2271

2272

2274

2275

2277

2279 Builder.CreateBr(ContBB);

2280

2282}

2283

2285

2286

2287

2290

2291

2292

2294 Builder.CreateUnreachable();

2295 Builder.ClearInsertionPoint();

2296 return;

2297 }

2298

2300}

static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM)

Definition CGException.cpp:54

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

Emit the dispatch block for a filter scope if necessary.

Definition CGException.cpp:546

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

Definition CGException.cpp:969

static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM)

Definition CGException.cpp:33

static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM)

Definition CGException.cpp:48

static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI)

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

Definition CGException.cpp:280

static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn)

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

Definition CGException.cpp:311

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

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

Definition CGException.cpp:1121

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

Definition CGException.cpp:273

static bool isNonEHScope(const EHScope &S)

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

Definition CGException.cpp:765

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

Definition CGException.cpp:89

static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM)

Definition CGException.cpp:42

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

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

Definition CGException.cpp:379

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

Definition CGException.cpp:1012

static const EHPersonality & getCXXPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)

static const EHPersonality & getCPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)

static const EHPersonality & getObjCPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)

static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality)

static const EHPersonality & getObjCXXPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)

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

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

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.

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

CXXCatchStmt - This represents a C++ catch block.

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

const Expr * getSubExpr() const

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

CXXCatchStmt * getHandler(unsigned i)

unsigned getNumHandlers() const

CompoundStmt * getTryBlock()

unsigned getBuiltinCallee() const

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

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.

CodeGenOptions - Track various options which control how the code is optimized and passed to the back...

bool hasDWARFExceptions() const

bool hasWasmExceptions() const

bool hasSjLjExceptions() const

bool hasSEHExceptions() const

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)

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="")

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

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

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

void add(RValue rvalue, QualType type)

void exit(CodeGenFunction &CGF)

Definition CGException.cpp:1495

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.

Definition CGException.cpp:1442

Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.

void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})

Force the emission of cleanups now, instead of waiting until this object is destroyed.

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

void EmitCXXTryStmt(const CXXTryStmt &S)

Definition CGException.cpp:625

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

Definition CGException.cpp:723

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

bool IsOutlinedSEHHelper

True if the current function is an outlined SEH helper.

llvm::Value * getSelectorFromSlot()

Definition CGException.cpp:442

llvm::Value * getExceptionFromSlot()

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

Definition CGException.cpp:438

SmallVector< Address, 1 > SEHCodeSlotStack

A stack of exception code slots.

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

Definition CGException.cpp:1700

llvm::BasicBlock * getInvokeDestImpl()

Definition CGException.cpp:778

llvm::Type * ConvertType(QualType T)

FieldDecl * LambdaThisCaptureField

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

Recovers the address of a local in a parent function.

Definition CGException.cpp:1836

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

Emits a call or invoke to the given noreturn runtime function.

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

Emits a call or invoke instruction to the given runtime function.

llvm::Value * EmitSEHAbnormalTermination()

Definition CGException.cpp:2161

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

Definition CGException.cpp:446

bool isSEHTryScope() const

Returns true inside SEH __try blocks.

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

createBasicBlock - Create an LLVM basic block.

const LangOptions & getLangOpts() const

llvm::BasicBlock * EHResumeBlock

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

llvm::AllocaInst * EHSelectorSlot

The selector slot.

llvm::BasicBlock * EmitLandingPad()

Emits a landing pad for the current EH stack.

Definition CGException.cpp:828

void EmitBlockAfterUses(llvm::BasicBlock *BB)

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

void EmitBranchThroughCleanup(JumpDest Dest)

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

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

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

Definition CGException.cpp:2110

llvm::Value * ExceptionSlot

The exception slot.

void EmitAnyExprToExn(const Expr *E, Address Addr)

Definition CGException.cpp:400

llvm::BasicBlock * getEHResumeBlock(bool isCleanup)

Definition CGException.cpp:1629

const TargetInfo & getTarget() const

llvm::BasicBlock * getTerminateHandler()

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

Definition CGException.cpp:1570

void EnterSEHTryStmt(const SEHTryStmt &S)

Definition CGException.cpp:2173

RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)

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

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

DeactivateCleanupBlock - Deactivates the given cleanup block.

void pushFullExprCleanup(CleanupKind kind, As... A)

pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.

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.

Address getExceptionSlot()

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

Definition CGException.cpp:426

bool HaveInsertPoint() const

HaveInsertPoint - True if an insertion point is defined.

llvm::BasicBlock * getTerminateFunclet()

getTerminateLandingPad - Return a cleanup funclet that just calls terminate.

Definition CGException.cpp:1594

llvm::BasicBlock * getTerminateLandingPad()

getTerminateLandingPad - Return a landing pad that just calls terminate.

Definition CGException.cpp:1536

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

Definition CGException.cpp:2097

void EmitStartEHSpec(const Decl *D)

EmitStartEHSpec - Emit the start of the exception spec.

Definition CGException.cpp:476

void popCatchScope()

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

Definition CGException.cpp:1206

llvm::Value * EmitSEHExceptionCode()

Definition CGException.cpp:2156

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

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

Arrange a function prototype that can be called by Windows exception handling personalities.

Definition CGException.cpp:2018

void EmitSehTryScopeBegin()

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

const TargetCodeGenInfo & getTargetHooks() const

void EmitSEHLeaveStmt(const SEHLeaveStmt &S)

Definition CGException.cpp:2284

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

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

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

Scan the outlined statement for captures from the parent function.

Definition CGException.cpp:1875

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

Definition CGException.cpp:2168

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

ASTContext & getContext() const

void EmitStopPoint(const Stmt *S)

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

llvm::Value * SEHInfo

Value returned by __exception_info intrinsic.

RawAddress getNormalCleanupDestSlot()

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 EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})

EmitStmt - Emit the code for the statement.

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

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

llvm::Type * ConvertTypeForMem(QualType T)

void EmitEndEHSpec(const Decl *D)

EmitEndEHSpec - Emit the end of the exception spec.

Definition CGException.cpp:583

void ExitSEHTryStmt(const SEHTryStmt &S)

Definition CGException.cpp:2212

LValue EmitLValueForLambdaField(const FieldDecl *Field)

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

Definition CGException.cpp:1213

const TargetInfo & Target

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

Definition CGException.cpp:676

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

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

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

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

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

void FinishFunction(SourceLocation EndLoc=SourceLocation())

FinishFunction - Complete IR generation of the current function.

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

Definition CGException.cpp:638

Address ReturnValue

ReturnValue - The temporary alloca to hold the return value.

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 * EmitSEHExceptionInfo()

Definition CGException.cpp:2147

void EmitSEHTryStmt(const SEHTryStmt &S)

Definition CGException.cpp:1665

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

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

Address getEHSelectorSlot()

Definition CGException.cpp:432

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

Create a stub filter function that will ultimately hold the code of the filter expression.

Definition CGException.cpp:2080

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

EmitBlock - Emit the given block.

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

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.

const LangOptions & getLangOpts() const

CodeGenTypes & getTypes()

const TargetInfo & getTarget() const

CGCXXABI & getCXXABI() const

const CodeGenOptions & getCodeGenOpts() const

llvm::FunctionCallee getTerminateFn()

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

Definition CGException.cpp:63

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

LangAS GetGlobalVarAddressSpace(const VarDecl *D)

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

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

A non-stable pointer into the scope stack.

A saved depth on the scope stack.

iterator begin() const

Returns an iterator pointing to the innermost EH scope.

class EHCatchScope * pushCatch(unsigned NumHandlers)

Push a set of catch handlers 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.

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

bool refersToEnclosingVariableOrCapture() const

Does this DeclRefExpr refer to an enclosing local or a captured variable?

SourceLocation getLocation() const

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

clang::ObjCRuntime ObjCRuntime

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

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

Represents Objective-C's @throw statement.

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.

CompoundStmt * getTryBlock() const

SEHFinallyStmt * getFinallyHandler() const

SEHExceptStmt * getExceptHandler() const

Returns 0 if not defined.

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

Exposes information about the current target.

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

bool isSignedIntegerType() const

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

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.

@ Decl

The l-value was an access to a declared entity or something equivalently strong, like the address of ...

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

bool Load(InterpState &S, CodePtr OpPC)

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

bool isa(CodeGen::Address addr)

const FunctionProtoType * T

LangAS

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

U cast(CodeGen::Address addr)

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

A jump destination is an abstract label, branching to which may require a jump out through normal cle...

llvm::BasicBlock * getBlock() const

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)

Definition CGException.cpp:239

static const EHPersonality XL_CPlusPlus

static const EHPersonality GNU_ObjC_SJLJ

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