clang: lib/CodeGen/CGCleanup.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
21#include "llvm/Support/SaveAndRestore.h"
22
23using namespace clang;
25
31 return true;
32}
33
40 : ScalarLiteral);
41 }
42
47 }
48
53 ? AggregateAddress
54 : AggregateLiteral);
55}
56
57
58
59
61 switch (K) {
62 case ScalarLiteral:
63 case ScalarAddress:
65 case AggregateLiteral:
66 case AggregateAddress:
69 case ComplexAddress: {
73 }
74 }
75
76 llvm_unreachable("bad saved r-value kind");
77}
78
79
80char *EHScopeStack::allocate(size_t Size) {
82 if (!StartOfBuffer) {
83 unsigned Capacity = 1024;
84 while (Capacity < Size) Capacity *= 2;
85 StartOfBuffer = new char[Capacity];
86 StartOfData = EndOfBuffer = StartOfBuffer + Capacity;
87 } else if (static_cast<size_t>(StartOfData - StartOfBuffer) < Size) {
88 unsigned CurrentCapacity = EndOfBuffer - StartOfBuffer;
89 unsigned UsedCapacity = CurrentCapacity - (StartOfData - StartOfBuffer);
90
91 unsigned NewCapacity = CurrentCapacity;
92 do {
93 NewCapacity *= 2;
94 } while (NewCapacity < UsedCapacity + Size);
95
96 char *NewStartOfBuffer = new char[NewCapacity];
97 char *NewEndOfBuffer = NewStartOfBuffer + NewCapacity;
98 char *NewStartOfData = NewEndOfBuffer - UsedCapacity;
99 memcpy(NewStartOfData, StartOfData, UsedCapacity);
100 delete [] StartOfBuffer;
101 StartOfBuffer = NewStartOfBuffer;
102 EndOfBuffer = NewEndOfBuffer;
103 StartOfData = NewStartOfData;
104 }
105
106 assert(StartOfBuffer + Size <= StartOfData);
107 StartOfData -= Size;
108 return StartOfData;
109}
110
111void EHScopeStack::deallocate(size_t Size) {
113}
114
117 for (EHScopeStack::iterator it = begin(); stabilize(it) != Old; it++) {
118 EHCleanupScope *cleanup = dyn_cast(&*it);
119
120
122 return false;
123 if (->isLifetimeMarker() &&
->isFakeUse())
124 return false;
125 }
126
127 return true;
128}
129
132
133 if (auto *cleanup = dyn_cast(&*find(si)))
134 if (cleanup->isLifetimeMarker()) {
135 si = cleanup->getEnclosingEHScope();
136 continue;
137 }
138 return true;
139 }
140
141 return false;
142}
143
147 si != se; ) {
149 if (cleanup.isActive()) return si;
150 si = cleanup.getEnclosingNormalCleanup();
151 }
153}
154
155
156void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) {
162
163
164
165
166
167 if (InnermostEHScope != stable_end() &&
169 IsEHCleanup = false;
170
171 EHCleanupScope *Scope =
172 new (Buffer) EHCleanupScope(IsNormalCleanup,
173 IsEHCleanup,
174 Size,
175 BranchFixups.size(),
176 InnermostNormalCleanup,
177 InnermostEHScope);
178 if (IsNormalCleanup)
180 if (IsEHCleanup)
182 if (IsLifetimeMarker)
184 if (IsFakeUse)
186
187
188
189
190
191
192
193 if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
194 CGF->getTarget().getCXXABI().isMicrosoft() && CGF->getInvokeDest())
195 CGF->EmitSehCppScopeBegin();
196
198}
199
201 assert(() && "popping exception stack when not empty");
202
208
209
211
212
213 if (!BranchFixups.empty()) {
214
215
217 BranchFixups.clear();
218
219
220 else
222 }
223}
224
228 EHFilterScope *filter = new (buffer) EHFilterScope(numFilters);
230 return filter;
231}
232
234 assert(() && "popping exception stack when not empty");
235
238
240}
241
244 EHCatchScope *scope =
245 new (buffer) EHCatchScope(numHandlers, InnermostEHScope);
247 return scope;
248}
249
252 new (Buffer) EHTerminateScope(InnermostEHScope);
254}
255
256
257
258
259
260
262
263
265
266 EHScopeStack::iterator it = find(InnermostNormalCleanup);
268 assert(BranchFixups.size() >= MinSize && "fixup stack out of order");
269
270 while (BranchFixups.size() > MinSize &&
271 BranchFixups.back().Destination == nullptr)
272 BranchFixups.pop_back();
273}
274
276
279
280
281
283
284
286
287 return active;
288}
289
291
293 assert(.hasActiveFlag() && "cleanup already has active flag?");
294 cleanup.setActiveFlag(ActiveFlag);
295
296 if (cleanup.isNormalCleanup()) cleanup.setTestFlagInNormalCleanup();
297 if (cleanup.isEHCleanup()) cleanup.setTestFlagInEHCleanup();
298}
299
300void EHScopeStack::Cleanup::anchor() {}
301
303 llvm::BasicBlock::iterator beforeInst,
305 auto store = new llvm::StoreInst(value, addr.emitRawPointer(CGF), beforeInst);
307}
308
309static llvm::LoadInst *
311 llvm::BasicBlock::iterator beforeInst,
315 beforeInst);
316}
317
323
324
325
326
328 llvm::SwitchInst *Switch,
329 llvm::BasicBlock *CleanupEntry) {
331
333
335 if (Fixup.Destination == nullptr) continue;
336
337
338
339
340
341
342
343
344
349 Fixup.InitialBranch->setSuccessor(0, CleanupEntry);
350 }
351
352
353 if (!CasesAdded.insert(Fixup.Destination).second)
354 continue;
355
358 }
359
361}
362
363
364
366 llvm::BasicBlock *Block) {
367
368
369 llvm::Instruction *Term = Block->getTerminator();
370 assert(Term && "can't transition block without terminator");
371
372 if (llvm::BranchInst *Br = dyn_castllvm::BranchInst(Term)) {
373 assert(Br->isUnconditional());
375 "cleanup.dest", Term->getIterator(), CGF);
376 llvm::SwitchInst *Switch =
377 llvm::SwitchInst::Create(Load, Br->getSuccessor(0), 4, Block);
378 Br->eraseFromParent();
380 } else {
382 }
383}
384
386 assert(Block && "resolving a null target block");
387 if (.getNumBranchFixups()) return;
388
389 assert(EHStack.hasNormalCleanups() &&
390 "branch fixups exist with no normal cleanups on stack");
391
393 bool ResolvedAny = false;
394
395 for (unsigned I = 0, E = EHStack.getNumBranchFixups(); I != E; ++I) {
396
399
401 ResolvedAny = true;
402
403
404
406 if (!BranchBB)
407 continue;
408
409
410 if (!ModifiedOptimisticBlocks.insert(BranchBB).second)
411 continue;
412
414
415
417 }
418
419 if (ResolvedAny)
421}
422
423
426 std::initializer_list<llvm::Value **> ValuesToReload) {
428
429 bool HadBranches = false;
430 while (EHStack.stable_begin() != Old) {
432 HadBranches |= Scope.hasBranches();
433
434
435
436
437 bool FallThroughIsBranchThrough =
439
441 }
442
443
444
445
446 if (!HadBranches)
447 return;
448
449
450
451 for (llvm::Value **ReloadedValue : ValuesToReload) {
452 auto *Inst = dyn_cast_or_nullllvm::Instruction(*ReloadedValue);
453 if (!Inst)
454 continue;
455
456
457
458 auto *AI = dyn_castllvm::AllocaInst(Inst);
459 if (AI && AI->isStaticAlloca())
460 continue;
461
464
465
466 llvm::BasicBlock::iterator InsertBefore;
467 if (auto *Invoke = dyn_castllvm::InvokeInst(Inst))
468 InsertBefore = Invoke->getNormalDest()->getFirstInsertionPt();
469 else
470 InsertBefore = std::next(Inst->getIterator());
472
473
474 *ReloadedValue = Builder.CreateLoad(Tmp);
475 }
476}
477
478
479
482 std::initializer_list<llvm::Value **> ValuesToReload) {
484
485
486 for (size_t I = OldLifetimeExtendedSize,
488
490 "misaligned cleanup stack entry");
491
495 I += sizeof(Header);
496
501
506 I += sizeof(ActiveFlag);
507 }
508 }
510}
511
514 assert(Scope.isNormalCleanup());
515 llvm::BasicBlock *Entry = Scope.getNormalBlock();
516 if (!Entry) {
518 Scope.setNormalBlock(Entry);
519 }
520 return Entry;
521}
522
523
524
525
526
527
529 llvm::BasicBlock *Entry) {
530 llvm::BasicBlock *Pred = Entry->getSinglePredecessor();
531 if (!Pred) return Entry;
532
533 llvm::BranchInst *Br = dyn_castllvm::BranchInst(Pred->getTerminator());
534 if (!Br || Br->isConditional()) return Entry;
535 assert(Br->getSuccessor(0) == Entry);
536
537
538
539
540 bool WasInsertBlock = CGF.Builder.GetInsertBlock() == Entry;
541 assert(!WasInsertBlock || CGF.Builder.GetInsertPoint() == Entry->end());
542
543
544 Br->eraseFromParent();
545
546
547
548 Entry->replaceAllUsesWith(Pred);
549
550
551 Pred->splice(Pred->end(), Entry);
552
553
554 Entry->eraseFromParent();
555
556 if (WasInsertBlock)
557 CGF.Builder.SetInsertPoint(Pred);
558
559 return Pred;
560}
561
563 EHScopeStack::Cleanup *Fn,
564 EHScopeStack::Cleanup::Flags flags,
566
567
568 llvm::BasicBlock *ContBB = nullptr;
569 if (ActiveFlag.isValid()) {
571 llvm::BasicBlock *CleanupBB = CGF.createBasicBlock("cleanup.action");
572 llvm::Value *IsActive
574 CGF.Builder.CreateCondBr(IsActive, CleanupBB, ContBB);
576 }
577
578
579 Fn->Emit(CGF, flags);
580 assert(CGF.HaveInsertPoint() && "cleanup ended with no insertion point?");
581
582
583 if (ActiveFlag.isValid())
585}
586
588 llvm::BasicBlock *From,
589 llvm::BasicBlock *To) {
590
591
592 llvm::Instruction *Term = Exit->getTerminator();
593
594 if (llvm::BranchInst *Br = dyn_castllvm::BranchInst(Term)) {
595 assert(Br->isUnconditional() && Br->getSuccessor(0) == From);
596 Br->setSuccessor(0, To);
597 } else {
599 for (unsigned I = 0, E = Switch->getNumSuccessors(); I != E; ++I)
600 if (Switch->getSuccessor(I) == From)
601 Switch->setSuccessor(I, To);
602 }
603}
604
605
606
607
608
609
610
614 if (!entry) return;
615
616
618 for (llvm::BasicBlock::use_iterator
619 i = entry->use_begin(), e = entry->use_end(); i != e; ) {
620 llvm::Use &use = *i;
621 ++i;
622
623 use.set(unreachableBB);
624
625
627 if (si->getNumCases() == 1 && si->getDefaultDest() == unreachableBB) {
628
629 llvm::BranchInst::Create(si->case_begin()->getCaseSuccessor(),
630 si->getIterator());
631
632
634
635
636 si->eraseFromParent();
637
638
640 assert(condition->use_empty());
641 condition->eraseFromParent();
642 }
643 }
644
645 assert(entry->use_empty());
646 delete entry;
647}
648
649
650
651
654 assert(.empty() && "cleanup stack is empty!");
657 assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
658
659
660
661 CGBuilderTy::InsertPoint NormalDeactivateOrigIP;
663 NormalDeactivateOrigIP = Builder.saveAndClearIP();
664 }
665
666 bool IsActive = Scope.isActive();
667 Address NormalActiveFlag =
668 Scope.shouldTestFlagInNormalCleanup() ? Scope.getActiveFlag()
671 Scope.shouldTestFlagInEHCleanup() ? Scope.getActiveFlag()
673
674
675
676 llvm::BasicBlock *EHEntry = Scope.getCachedEHDispatchBlock();
677 assert(Scope.hasEHBranches() == (EHEntry != nullptr));
678 bool RequiresEHCleanup = (EHEntry != nullptr);
680
681
682
683
684 unsigned FixupDepth = Scope.getFixupDepth();
685 bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth;
686
687
688 bool HasExistingBranches = Scope.hasBranches();
689
690
691 llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
692 bool HasFallthrough =
693 FallthroughSource != nullptr && (IsActive || HasExistingBranches);
694
695
696
697
698
699 bool HasPrebranchedFallthrough =
700 (FallthroughSource && FallthroughSource->getTerminator());
701
702
703
704
705 assert(.isNormalCleanup() || !HasPrebranchedFallthrough ||
706 (Scope.getNormalBlock() &&
707 FallthroughSource->getTerminator()->getSuccessor(0)
708 == Scope.getNormalBlock()));
709
710 bool RequiresNormalCleanup = false;
711 if (Scope.isNormalCleanup() &&
712 (HasFixups || HasExistingBranches || HasFallthrough)) {
713 RequiresNormalCleanup = true;
714 }
715
716
717
718 if (Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
719 !RequiresNormalCleanup) {
720
721
722 assert(!IsActive);
723 llvm::BasicBlock *prebranchDest;
724
725
726
727
728 if (FallthroughIsBranchThrough) {
731
732
733
734
735
736 } else {
739 }
740
741 llvm::BasicBlock *normalEntry = Scope.getNormalBlock();
742 assert(normalEntry && !normalEntry->use_empty());
743
745 normalEntry, prebranchDest);
746 }
747
748
749 if (!RequiresNormalCleanup && !RequiresEHCleanup) {
751 EHStack.popCleanup();
752 assert(EHStack.getNumBranchFixups() == 0 ||
753 EHStack.hasNormalCleanups());
754 if (NormalDeactivateOrigIP.isSet())
755 Builder.restoreIP(NormalDeactivateOrigIP);
756 return;
757 }
758
759
760
761
762
763
764 auto *CleanupSource = reinterpret_cast<char *>(Scope.getCleanupBuffer());
766 CleanupBufferStack[8 * sizeof(void *)];
767 std::unique_ptr<char[]> CleanupBufferHeap;
768 size_t CleanupSize = Scope.getCleanupSize();
769 EHScopeStack::Cleanup *Fn;
770
771 if (CleanupSize <= sizeof(CleanupBufferStack)) {
772 memcpy(CleanupBufferStack, CleanupSource, CleanupSize);
773 Fn = reinterpret_cast<EHScopeStack::Cleanup *>(CleanupBufferStack);
774 } else {
775 CleanupBufferHeap.reset(new char[CleanupSize]);
776 memcpy(CleanupBufferHeap.get(), CleanupSource, CleanupSize);
777 Fn = reinterpret_cast<EHScopeStack::Cleanup *>(CleanupBufferHeap.get());
778 }
779
780 EHScopeStack::Cleanup::Flags cleanupFlags;
781 if (Scope.isNormalCleanup())
782 cleanupFlags.setIsNormalCleanupKind();
783 if (Scope.isEHCleanup())
784 cleanupFlags.setIsEHCleanupKind();
785
786
787 bool IsEHa = getLangOpts().EHAsynch && .isLifetimeMarker();
789 if (!RequiresNormalCleanup) {
790
791
793
794
795
796 if (NormalDeactivateOrigIP.isSet())
797 Builder.restoreIP(NormalDeactivateOrigIP);
800 if (NormalDeactivateOrigIP.isSet())
801 NormalDeactivateOrigIP = Builder.saveAndClearIP();
802 }
804 Scope.MarkEmitted();
806 } else {
807
808
809 if (HasFallthrough && !HasPrebranchedFallthrough && !HasFixups &&
810 !HasExistingBranches) {
811
812
816 else
818 }
819
821 Scope.MarkEmitted();
823
824 EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);
825
826
827
828 } else {
829
831
832
833
834 CGBuilderTy::InsertPoint savedInactiveFallthroughIP;
835
836
837
838 if (HasFallthrough) {
839 if (!HasPrebranchedFallthrough)
841
842
843
844 } else if (FallthroughSource) {
845 assert(!IsActive && "source without fallthrough for active cleanup");
846 savedInactiveFallthroughIP = Builder.saveAndClearIP();
847 }
848
849
850
851
853
854
858 else
860 }
861
862
863
864
865 bool HasEnclosingCleanups =
866 (Scope.getEnclosingNormalCleanup() != EHStack.stable_end());
867
868
869
870
871
872
873 llvm::BasicBlock *BranchThroughDest = nullptr;
874 if (Scope.hasBranchThroughs() ||
875 (FallthroughSource && FallthroughIsBranchThrough) ||
876 (HasFixups && HasEnclosingCleanups)) {
877 assert(HasEnclosingCleanups);
880 }
881
882 llvm::BasicBlock *FallthroughDest = nullptr;
884
885
886
887
888
889
890
891
892 if (.hasBranchThroughs() && !HasFixups && !HasFallthrough &&
894 assert(!BranchThroughDest || !IsActive);
895
896
897 llvm::Instruction *NormalCleanupDestSlot =
899 if (NormalCleanupDestSlot->hasOneUse()) {
900 NormalCleanupDestSlot->user_back()->eraseFromParent();
901 NormalCleanupDestSlot->eraseFromParent();
903 }
904
905 llvm::BasicBlock *BranchAfter = Scope.getBranchAfterBlock(0);
906 InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter));
907
908
909
910
911
912
913 } else if (Scope.getNumBranchAfters() ||
914 (HasFallthrough && !FallthroughIsBranchThrough) ||
915 (HasFixups && !HasEnclosingCleanups)) {
916
917 llvm::BasicBlock *Default =
919
920
921 const unsigned SwitchCapacity = 10;
922
923
924 cleanupFlags.setHasExitSwitch();
925
927 "cleanup.dest", *this);
928 llvm::SwitchInst *Switch =
929 llvm::SwitchInst::Create(Load, Default, SwitchCapacity);
930
931 InstsToAppend.push_back(Load);
932 InstsToAppend.push_back(Switch);
933
934
935 if (FallthroughSource && !FallthroughIsBranchThrough) {
937 if (HasFallthrough)
938 Switch->addCase(Builder.getInt32(0), FallthroughDest);
939 }
940
941 for (unsigned I = 0, E = Scope.getNumBranchAfters(); I != E; ++I) {
942 Switch->addCase(Scope.getBranchAfterIndex(I),
943 Scope.getBranchAfterBlock(I));
944 }
945
946
947
948 if (HasFixups && !HasEnclosingCleanups)
950 } else {
951
952 assert(BranchThroughDest);
953 InstsToAppend.push_back(llvm::BranchInst::Create(BranchThroughDest));
954 }
955
956
957 Scope.MarkEmitted();
959 assert(EHStack.hasNormalCleanups() == HasEnclosingCleanups);
960
961 EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag);
962
963
964 llvm::BasicBlock *NormalExit = Builder.GetInsertBlock();
965 for (llvm::Instruction *Inst : InstsToAppend)
966 Inst->insertInto(NormalExit, NormalExit->end());
967
968
969 for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
970 I < E; ++I) {
973 continue;
978 Fixup.InitialBranch->setSuccessor(0, NormalEntry);
979 }
981 }
982
983
984
985
986
987 if (!HasFallthrough && FallthroughSource) {
988
989
990
991 assert(!IsActive);
992 Builder.restoreIP(savedInactiveFallthroughIP);
993
994
995
996
997 } else if (HasFallthrough && FallthroughDest) {
998 assert(!FallthroughIsBranchThrough);
1000
1001
1002
1003 } else if (HasFallthrough) {
1004
1005
1006
1007 } else {
1008 Builder.ClearInsertionPoint();
1009 }
1010
1011
1012
1013
1014
1015 llvm::BasicBlock *NewNormalEntry =
1017
1018
1019
1020 if (NewNormalEntry != NormalEntry && NormalEntry == NormalExit)
1021 for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
1022 I < E; ++I)
1023 EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry;
1024 }
1025 }
1026
1027 if (NormalDeactivateOrigIP.isSet())
1028 Builder.restoreIP(NormalDeactivateOrigIP);
1029 assert(EHStack.hasNormalCleanups() || EHStack.getNumBranchFixups() == 0);
1030
1031
1032 if (RequiresEHCleanup) {
1033 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1034
1036
1038
1039
1040
1041
1042 bool PushedTerminate = false;
1044 llvm::CleanupPadInst *CPI = nullptr;
1045
1049 if (!ParentPad)
1050 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1052 }
1053
1054
1056 EHStack.pushTerminate();
1057 PushedTerminate = true;
1060 }
1061
1062
1063
1064 if (EHActiveFlag.isValid() || IsActive) {
1065 cleanupFlags.setIsForEHCleanup();
1066 EmitCleanup(*this, Fn, cleanupFlags, EHActiveFlag);
1067 }
1068
1069 if (CPI)
1070 Builder.CreateCleanupRet(CPI, NextAction);
1071 else
1072 Builder.CreateBr(NextAction);
1073
1074
1075 if (PushedTerminate)
1077
1078 Builder.restoreIP(SavedIP);
1079
1081 }
1082}
1083
1084
1085
1086
1089 && "stale jump destination");
1090
1091
1093 EHStack.getInnermostActiveNormalCleanup();
1094
1095
1096
1097
1098 if (TopCleanup == EHStack.stable_end() ||
1100 return true;
1101
1102
1103 return false;
1104}
1105
1106
1107
1108
1109
1110
1111
1114 && "stale jump destination");
1115
1117 return;
1118
1119
1120 llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
1122
1123
1125 TopCleanup = EHStack.getInnermostActiveNormalCleanup();
1126
1127
1128
1129
1130 if (TopCleanup == EHStack.stable_end() ||
1132 Builder.ClearInsertionPoint();
1133 return;
1134 }
1135
1136
1137
1144
1145 Builder.ClearInsertionPoint();
1146 return;
1147 }
1148
1149
1150
1151
1154 *this);
1155
1156
1157 {
1161 }
1162
1163
1167 while (true) {
1169 assert(Scope.isNormalCleanup());
1170 I = Scope.getEnclosingNormalCleanup();
1171
1172
1173
1176 break;
1177 }
1178
1179
1180
1181
1183 break;
1184 }
1185 }
1186
1187 Builder.ClearInsertionPoint();
1188}
1189
1191 EHScopeStack::stable_iterator cleanup) {
1192
1194 return true;
1195
1196
1197 for (EHScopeStack::stable_iterator
1199 assert(cleanup.strictlyEncloses(i));
1200
1203 return true;
1204
1206 }
1207
1208 return false;
1209}
1210
1215
1216
1217
1218
1219
1220
1222 EHScopeStack::stable_iterator C,
1224 llvm::Instruction *dominatingIP) {
1226
1227
1228
1229
1230 bool isActivatedInConditional =
1232
1233 bool needFlag = false;
1234
1235
1236
1237
1238 if (Scope.isNormalCleanup()) {
1239 Scope.setTestFlagInNormalCleanup();
1240 needFlag = true;
1241 }
1242
1243
1244 if (Scope.isEHCleanup() &&
1246 Scope.setTestFlagInEHCleanup();
1247 needFlag = true;
1248 }
1249
1250
1251 if (!needFlag)
1252 return;
1253
1255 if (!var.isValid()) {
1258 "cleanup.isactive");
1259 Scope.setActiveFlag(var);
1260 Scope.AddAuxAllocas(AllocaTracker.Take());
1261
1262 assert(dominatingIP && "no existing variable and no dominating IP!");
1263
1264
1265
1267
1268
1269
1272 } else {
1274 }
1275 }
1276
1278}
1279
1280
1282 llvm::Instruction *dominatingIP) {
1283 assert(C != EHStack.stable_end() && "activating bottom of stack?");
1285 assert(.isActive() && "double activation");
1286
1288
1289 Scope.setActive(true);
1290}
1291
1292
1294 llvm::Instruction *dominatingIP) {
1295 assert(C != EHStack.stable_end() && "deactivating bottom of stack?");
1297 assert(Scope.isActive() && "double deactivation");
1298
1299
1300
1301 if (C == EHStack.stable_begin() &&
1304 true);
1305 return;
1306 }
1307
1308
1310
1311 Scope.setActive(false);
1312}
1313
1320
1321
1328
1329
1330
1332 llvm::FunctionCallee &SehCppScope) {
1333 llvm::BasicBlock *InvokeDest = CGF.getInvokeDest();
1334 assert(CGF.Builder.GetInsertBlock() && InvokeDest);
1335 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont");
1340 CGF.Builder.CreateInvoke(SehCppScope, Cont, InvokeDest, {}, BundleList);
1342}
1343
1344
1347 llvm::FunctionType *FTy =
1348 llvm::FunctionType::get(CGM.VoidTy, false);
1349 llvm::FunctionCallee SehCppScope =
1350 CGM.CreateRuntimeFunction(FTy, "llvm.seh.scope.begin");
1352}
1353
1354
1355
1358 llvm::FunctionType *FTy =
1359 llvm::FunctionType::get(CGM.VoidTy, false);
1360 llvm::FunctionCallee SehCppScope =
1361 CGM.CreateRuntimeFunction(FTy, "llvm.seh.scope.end");
1363}
1364
1365
1368 llvm::FunctionType *FTy =
1369 llvm::FunctionType::get(CGM.VoidTy, false);
1370 llvm::FunctionCallee SehCppScope =
1371 CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin");
1373}
1374
1375
1378 llvm::FunctionType *FTy =
1379 llvm::FunctionType::get(CGM.VoidTy, false);
1380 llvm::FunctionCallee SehCppScope =
1381 CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end");
1383}
static llvm::LoadInst * createLoadInstBefore(Address addr, const Twine &name, llvm::BasicBlock::iterator beforeInst, CodeGenFunction &CGF)
Definition CGCleanup.cpp:310
static void EmitSehScope(CodeGenFunction &CGF, llvm::FunctionCallee &SehCppScope)
Definition CGCleanup.cpp:1331
static llvm::BasicBlock * CreateNormalEntry(CodeGenFunction &CGF, EHCleanupScope &Scope)
Definition CGCleanup.cpp:512
ForActivation_t
Definition CGCleanup.cpp:1211
@ ForActivation
Definition CGCleanup.cpp:1212
@ ForDeactivation
Definition CGCleanup.cpp:1213
static void EmitCleanup(CodeGenFunction &CGF, EHScopeStack::Cleanup *Fn, EHScopeStack::Cleanup::Flags flags, Address ActiveFlag)
Definition CGCleanup.cpp:562
static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, EHCleanupScope &scope)
We don't need a normal entry block for the given cleanup.
Definition CGCleanup.cpp:611
static void SetupCleanupBlockActivation(CodeGenFunction &CGF, EHScopeStack::stable_iterator C, ForActivation_t kind, llvm::Instruction *dominatingIP)
The given cleanup block is changing activation state.
Definition CGCleanup.cpp:1221
static void ForwardPrebranchedFallthrough(llvm::BasicBlock *Exit, llvm::BasicBlock *From, llvm::BasicBlock *To)
Definition CGCleanup.cpp:587
static void createStoreInstBefore(llvm::Value *value, Address addr, llvm::BasicBlock::iterator beforeInst, CodeGenFunction &CGF)
Definition CGCleanup.cpp:302
static void ResolveAllBranchFixups(CodeGenFunction &CGF, llvm::SwitchInst *Switch, llvm::BasicBlock *CleanupEntry)
All the branch fixups on the EH stack have propagated out past the outermost normal cleanup; resolve ...
Definition CGCleanup.cpp:327
static bool IsUsedAsEHCleanup(EHScopeStack &EHStack, EHScopeStack::stable_iterator cleanup)
Definition CGCleanup.cpp:1190
static llvm::BasicBlock * SimplifyCleanupEntry(CodeGenFunction &CGF, llvm::BasicBlock *Entry)
Attempts to reduce a cleanup's entry block to a fallthrough.
Definition CGCleanup.cpp:528
static llvm::SwitchInst * TransitionToCleanupSwitch(CodeGenFunction &CGF, llvm::BasicBlock *Block)
Transitions the terminator of the given exit-block of a cleanup to be a cleanup switch.
Definition CGCleanup.cpp:365
static Decl::Kind getKind(const Decl *D)
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.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Represents a C++ temporary.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
static CharUnits One()
One - Construct a CharUnits quantity of one.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
EHScopeStack::stable_iterator CurrentCleanupScopeDepth
void EmitSehCppScopeBegin()
Definition CGCleanup.cpp:1345
void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
ActivateCleanupBlock - Activates an initially-inactive cleanup.
Definition CGCleanup.cpp:1281
void EmitSehTryScopeEnd()
Definition CGCleanup.cpp:1376
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
const LangOptions & getLangOpts() const
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup.
static Destroyer destroyCXXObject
void EmitSehCppScopeEnd()
Definition CGCleanup.cpp:1356
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
Definition CGCleanup.cpp:1112
llvm::BasicBlock * getUnreachableBlock()
bool currentFunctionUsesSEHTry() const
@ Default
! No language constraints on evaluation order.
void initFullExprCleanupWithFlag(RawAddress ActiveFlag)
Definition CGCleanup.cpp:290
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
bool isInConditionalBranch() const
isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...
void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, std::initializer_list< llvm::Value ** > ValuesToReload={})
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
Definition CGCleanup.cpp:424
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
Definition CGCleanup.cpp:1293
llvm::BasicBlock * getInvokeDest()
void ResolveBranchFixups(llvm::BasicBlock *Target)
Definition CGCleanup.cpp:385
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
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 EmitSehTryScopeBegin()
Definition CGCleanup.cpp:1366
void setBeforeOutermostConditional(llvm::Value *value, Address addr, CodeGenFunction &CGF)
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
llvm::SmallVector< char, 256 > LifetimeExtendedCleanupStack
RawAddress getNormalCleanupDestSlot()
Definition CGCleanup.cpp:1314
void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, Address Ptr)
Emits all the code to cause the given temporary to be cleaned up.
Definition CGCleanup.cpp:1322
llvm::BasicBlock * getEHDispatchBlock(EHScopeStack::stable_iterator scope)
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
RawAddress createCleanupActiveFlag()
Definition CGCleanup.cpp:275
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
llvm::Instruction * CurrentFuncletPad
bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const
isObviouslyBranchWithoutCleanups - Return true if a branch to the specified destination obviously has...
Definition CGCleanup.cpp:1087
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
Definition CGCleanup.cpp:652
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
A scope which attempts to handle some, possibly all, types of exceptions.
static size_t getSizeForNumHandlers(unsigned N)
A cleanup scope which generates the cleanup blocks lazily.
EHScopeStack::stable_iterator getEnclosingNormalCleanup() const
size_t getAllocatedSize() const
void * getCleanupBuffer()
static size_t getSizeForCleanupSize(size_t Size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
llvm::BasicBlock * getNormalBlock() const
An exceptions scope which filters exceptions thrown through it.
static size_t getSizeForNumFilters(unsigned numFilters)
unsigned getNumFilters() const
A saved depth on the scope stack.
bool encloses(stable_iterator I) const
Returns true if this scope encloses I.
bool strictlyEncloses(stable_iterator I) const
Returns true if this scope strictly encloses I: that is, if it encloses I and is not I.
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
void popNullFixups()
Pops lazily-removed fixups from the end of the list.
BranchFixup & getBranchFixup(unsigned I)
bool requiresLandingPad() const
stable_iterator getInnermostNormalCleanup() const
Returns the innermost normal cleanup on the stack, or stable_end() if there are no normal cleanups.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
unsigned getNumBranchFixups() const
class EHFilterScope * pushFilter(unsigned NumFilters)
Push an exceptions filter on the stack.
stable_iterator getInnermostEHScope() const
bool empty() const
Determines whether the exception-scopes stack is empty.
bool containsOnlyNoopCleanups(stable_iterator Old) const
iterator begin() const
Returns an iterator pointing to the innermost EH scope.
void pushTerminate()
Push a terminate handler on the stack.
void popCleanup()
Pops a cleanup scope off the stack. This is private to CGCleanup.cpp.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
stable_iterator getInnermostActiveNormalCleanup() const
void popFilter()
Pops an exceptions filter off the stack.
bool hasNormalCleanups() const
Determines whether there are any normal cleanups on the stack.
stable_iterator stabilize(iterator it) const
Translates an iterator into a stable_iterator.
static stable_iterator stable_end()
Create a stable reference to the bottom of the EH stack.
void clearFixups()
Clears the branch-fixups list.
class EHCatchScope * pushCatch(unsigned NumHandlers)
Push a set of catch handlers on the stack.
A protected scope for zero-cost EH handling.
EHScopeStack::stable_iterator getEnclosingEHScope() const
bool hasEHBranches() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
An abstract representation of an aligned address.
llvm::Value * getPointer() const
static RawAddress invalid()
A (possibly-)qualified type.
Scope - A scope is a transient data structure that is used while parsing the program.
@ 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...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)
unsigned DestinationIndex
The destination index value.
llvm::BasicBlock * Destination
The ultimate destination of the branch.
llvm::BasicBlock * OptimisticBranchBlock
The block containing the terminator which needs to be modified into a switch if this fixup is resolve...
llvm::BranchInst * InitialBranch
The initial branch of the fixup.
llvm::SmallVector< llvm::AllocaInst * > Take()
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::BasicBlock * getBlock() const
EHScopeStack::stable_iterator getScopeDepth() const
unsigned getDestIndex() const
static llvm::Value * restore(CodeGenFunction &CGF, saved_type value)
static saved_type save(CodeGenFunction &CGF, llvm::Value *value)
static bool needsSaving(llvm::Value *value)
Answer whether the given value needs extra work to be saved.
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.
The exceptions personality for a function.
bool isMSVCXXPersonality() const
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
bool isMSVCPersonality() const