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 (.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 (().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 (.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() && .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(.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 (->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(.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 (->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 .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(.empty() && "emitting EH code outside of __except");
2145}
2146
2148
2149
2151 return llvm::PoisonValue::get(Int8PtrTy);
2154}
2155
2157 assert(.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