21 #include "llvm/Support/SaveAndRestore.h"
23 using namespace clang;
24 using namespace CodeGen;
65 case AggregateLiteral:
66 case AggregateAddress:
69 case ComplexAddress: {
76 llvm_unreachable(
"bad saved r-value kind");
80 char *EHScopeStack::allocate(
size_t Size) {
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);
91 unsigned NewCapacity = CurrentCapacity;
94 }
while (NewCapacity < UsedCapacity + Size);
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;
106 assert(StartOfBuffer + Size <= StartOfData);
111 void EHScopeStack::deallocate(
size_t Size) {
129 if (
auto *
cleanup = dyn_cast<EHCleanupScope>(&*
find(si)))
130 if (
cleanup->isLifetimeMarker()) {
131 si =
cleanup->getEnclosingEHScope();
145 if (
cleanup.isActive())
return si;
146 si =
cleanup.getEnclosingNormalCleanup();
171 InnermostNormalCleanup,
177 if (IsLifetimeMarker)
178 Scope->setLifetimeMarker();
186 if (CGF->
getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
190 return Scope->getCleanupBuffer();
194 assert(!
empty() &&
"popping exception stack when not empty");
196 assert(isa<EHCleanupScope>(*
begin()));
198 InnermostNormalCleanup =
Cleanup.getEnclosingNormalCleanup();
199 InnermostEHScope =
Cleanup.getEnclosingEHScope();
200 deallocate(
Cleanup.getAllocatedSize());
206 if (!BranchFixups.empty()) {
210 BranchFixups.clear();
227 assert(!
empty() &&
"popping exception stack when not empty");
238 new (buffer)
EHCatchScope(numHandlers, InnermostEHScope);
260 unsigned MinSize = cast<EHCleanupScope>(*it).getFixupDepth();
261 assert(BranchFixups.size() >= MinSize &&
"fixup stack out of order");
263 while (BranchFixups.size() > MinSize &&
264 BranchFixups.back().Destination ==
nullptr)
265 BranchFixups.pop_back();
286 assert(!
cleanup.hasActiveFlag() &&
"cleanup already has active flag?");
287 cleanup.setActiveFlag(ActiveFlag);
289 if (
cleanup.isNormalCleanup())
cleanup.setTestFlagInNormalCleanup();
293 void EHScopeStack::Cleanup::anchor() {}
296 llvm::Instruction *beforeInst,
298 auto store =
new llvm::StoreInst(value, addr.
emitRawPointer(CGF), beforeInst);
303 llvm::Instruction *beforeInst,
314 llvm::SwitchInst *Switch,
315 llvm::BasicBlock *CleanupEntry) {
352 llvm::BasicBlock *Block) {
356 assert(Term &&
"can't transition block without terminator");
358 if (llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Term)) {
359 assert(Br->isUnconditional());
361 "cleanup.dest", Term, CGF);
362 llvm::SwitchInst *
Switch =
363 llvm::SwitchInst::Create(
Load, Br->getSuccessor(0), 4,
Block);
364 Br->eraseFromParent();
367 return cast<llvm::SwitchInst>(Term);
372 assert(
Block &&
"resolving a null target block");
373 if (!EHStack.getNumBranchFixups())
return;
375 assert(EHStack.hasNormalCleanups() &&
376 "branch fixups exist with no normal cleanups on stack");
379 bool ResolvedAny =
false;
381 for (
unsigned I = 0, E = EHStack.getNumBranchFixups(); I != E; ++I) {
396 if (!ModifiedOptimisticBlocks.insert(BranchBB).second)
406 EHStack.popNullFixups();
412 std::initializer_list<llvm::Value **> ValuesToReload) {
415 bool HadBranches =
false;
416 while (EHStack.stable_begin() != Old) {
418 HadBranches |=
Scope.hasBranches();
423 bool FallThroughIsBranchThrough =
426 PopCleanupBlock(FallThroughIsBranchThrough);
437 for (llvm::Value **ReloadedValue : ValuesToReload) {
438 auto *Inst = dyn_cast_or_null<llvm::Instruction>(*ReloadedValue);
444 auto *AI = dyn_cast<llvm::AllocaInst>(Inst);
445 if (AI && AI->isStaticAlloca())
449 CreateDefaultAlignTempAlloca(Inst->getType(),
"tmp.exprcleanup");
452 llvm::BasicBlock::iterator InsertBefore;
453 if (
auto *Invoke = dyn_cast<llvm::InvokeInst>(Inst))
454 InsertBefore = Invoke->getNormalDest()->getFirstInsertionPt();
456 InsertBefore = std::next(Inst->getIterator());
460 *ReloadedValue = Builder.CreateLoad(Tmp);
468 std::initializer_list<llvm::Value **> ValuesToReload) {
469 PopCleanupBlocks(Old, ValuesToReload);
472 for (
size_t I = OldLifetimeExtendedSize,
473 E = LifetimeExtendedCleanupStack.size(); I != E; ) {
476 "misaligned cleanup stack entry");
480 LifetimeExtendedCleanupStack[I]);
483 EHStack.pushCopyOfCleanup(Header.
getKind(),
484 &LifetimeExtendedCleanupStack[I],
490 reinterpret_cast<RawAddress &
>(LifetimeExtendedCleanupStack[I]);
491 initFullExprCleanupWithFlag(ActiveFlag);
492 I +=
sizeof(ActiveFlag);
495 LifetimeExtendedCleanupStack.resize(OldLifetimeExtendedSize);
500 assert(
Scope.isNormalCleanup());
501 llvm::BasicBlock *Entry =
Scope.getNormalBlock();
504 Scope.setNormalBlock(Entry);
515 llvm::BasicBlock *Entry) {
516 llvm::BasicBlock *Pred = Entry->getSinglePredecessor();
517 if (!Pred)
return Entry;
519 llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Pred->getTerminator());
520 if (!Br || Br->isConditional())
return Entry;
521 assert(Br->getSuccessor(0) == Entry);
526 bool WasInsertBlock = CGF.
Builder.GetInsertBlock() == Entry;
527 assert(!WasInsertBlock || CGF.
Builder.GetInsertPoint() == Entry->end());
530 Br->eraseFromParent();
534 Entry->replaceAllUsesWith(Pred);
537 Pred->splice(Pred->end(), Entry);
540 Entry->eraseFromParent();
543 CGF.
Builder.SetInsertPoint(Pred);
554 llvm::BasicBlock *ContBB =
nullptr;
558 llvm::Value *IsActive
560 CGF.
Builder.CreateCondBr(IsActive, CleanupBB, ContBB);
565 Fn->
Emit(CGF, flags);
566 assert(CGF.
HaveInsertPoint() &&
"cleanup ended with no insertion point?");
574 llvm::BasicBlock *From,
575 llvm::BasicBlock *To) {
578 llvm::Instruction *Term = Exit->getTerminator();
580 if (llvm::BranchInst *Br = dyn_cast<llvm::BranchInst>(Term)) {
581 assert(Br->isUnconditional() && Br->getSuccessor(0) == From);
582 Br->setSuccessor(0, To);
584 llvm::SwitchInst *
Switch = cast<llvm::SwitchInst>(Term);
585 for (
unsigned I = 0, E =
Switch->getNumSuccessors(); I != E; ++I)
586 if (
Switch->getSuccessor(I) == From)
587 Switch->setSuccessor(I, To);
604 for (llvm::BasicBlock::use_iterator
605 i = entry->use_begin(), e = entry->use_end(); i != e; ) {
609 use.set(unreachableBB);
612 llvm::SwitchInst *si = cast<llvm::SwitchInst>(use.getUser());
613 if (si->getNumCases() == 1 && si->getDefaultDest() == unreachableBB) {
615 llvm::BranchInst::Create(si->case_begin()->getCaseSuccessor(), si);
618 llvm::LoadInst *condition = cast<llvm::LoadInst>(si->getCondition());
621 si->eraseFromParent();
625 assert(condition->use_empty());
626 condition->eraseFromParent();
630 assert(entry->use_empty());
639 assert(!EHStack.empty() &&
"cleanup stack is empty!");
640 assert(isa<EHCleanupScope>(*EHStack.begin()) &&
"top not a cleanup!");
642 assert(
Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
646 CGBuilderTy::InsertPoint NormalDeactivateOrigIP;
648 NormalDeactivateOrigIP = Builder.saveAndClearIP();
651 bool IsActive =
Scope.isActive();
653 Scope.shouldTestFlagInNormalCleanup() ?
Scope.getActiveFlag()
656 Scope.shouldTestFlagInEHCleanup() ?
Scope.getActiveFlag()
661 llvm::BasicBlock *EHEntry =
Scope.getCachedEHDispatchBlock();
662 assert(
Scope.hasEHBranches() == (EHEntry !=
nullptr));
663 bool RequiresEHCleanup = (EHEntry !=
nullptr);
669 unsigned FixupDepth =
Scope.getFixupDepth();
670 bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth;
673 bool HasExistingBranches =
Scope.hasBranches();
676 llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
677 bool HasFallthrough =
678 FallthroughSource !=
nullptr && (IsActive || HasExistingBranches);
684 bool HasPrebranchedFallthrough =
685 (FallthroughSource && FallthroughSource->getTerminator());
690 assert(!
Scope.isNormalCleanup() || !HasPrebranchedFallthrough ||
691 (
Scope.getNormalBlock() &&
692 FallthroughSource->getTerminator()->getSuccessor(0)
693 ==
Scope.getNormalBlock()));
695 bool RequiresNormalCleanup =
false;
696 if (
Scope.isNormalCleanup() &&
697 (HasFixups || HasExistingBranches || HasFallthrough)) {
698 RequiresNormalCleanup =
true;
703 if (
Scope.isNormalCleanup() && HasPrebranchedFallthrough &&
704 !RequiresNormalCleanup) {
708 llvm::BasicBlock *prebranchDest;
713 if (FallthroughIsBranchThrough) {
714 EHScope &enclosing = *EHStack.find(
Scope.getEnclosingNormalCleanup());
722 prebranchDest = createBasicBlock(
"forwarded-prebranch");
723 EmitBlock(prebranchDest);
726 llvm::BasicBlock *normalEntry =
Scope.getNormalBlock();
727 assert(normalEntry && !normalEntry->use_empty());
730 normalEntry, prebranchDest);
734 if (!RequiresNormalCleanup && !RequiresEHCleanup) {
736 EHStack.popCleanup();
737 assert(EHStack.getNumBranchFixups() == 0 ||
738 EHStack.hasNormalCleanups());
739 if (NormalDeactivateOrigIP.isSet())
740 Builder.restoreIP(NormalDeactivateOrigIP);
749 auto *CleanupSource =
reinterpret_cast<char *
>(
Scope.getCleanupBuffer());
751 CleanupBufferStack[8 *
sizeof(
void *)];
752 std::unique_ptr<char[]> CleanupBufferHeap;
753 size_t CleanupSize =
Scope.getCleanupSize();
756 if (CleanupSize <=
sizeof(CleanupBufferStack)) {
757 memcpy(CleanupBufferStack, CleanupSource, CleanupSize);
760 CleanupBufferHeap.reset(
new char[CleanupSize]);
761 memcpy(CleanupBufferHeap.get(), CleanupSource, CleanupSize);
766 if (
Scope.isNormalCleanup())
768 if (
Scope.isEHCleanup())
772 bool IsEHa = getLangOpts().EHAsynch && !
Scope.isLifetimeMarker();
774 if (!RequiresNormalCleanup) {
777 if (IsEHa && getInvokeDest()) {
781 if (NormalDeactivateOrigIP.isSet())
782 Builder.restoreIP(NormalDeactivateOrigIP);
784 EmitSehCppScopeEnd();
785 if (NormalDeactivateOrigIP.isSet())
786 NormalDeactivateOrigIP = Builder.saveAndClearIP();
790 EHStack.popCleanup();
794 if (HasFallthrough && !HasPrebranchedFallthrough && !HasFixups &&
795 !HasExistingBranches) {
798 if (IsEHa && getInvokeDest()) {
800 EmitSehCppScopeEnd();
802 EmitSehTryScopeEnd();
807 EHStack.popCleanup();
809 EmitCleanup(*
this, Fn, cleanupFlags, NormalActiveFlag);
819 CGBuilderTy::InsertPoint savedInactiveFallthroughIP;
823 if (HasFallthrough) {
824 if (!HasPrebranchedFallthrough)
825 Builder.CreateStore(Builder.getInt32(0), getNormalCleanupDestSlot());
829 }
else if (FallthroughSource) {
830 assert(!IsActive &&
"source without fallthrough for active cleanup");
831 savedInactiveFallthroughIP = Builder.saveAndClearIP();
837 EmitBlock(NormalEntry);
840 if (IsEHa && getInvokeDest()) {
842 EmitSehCppScopeEnd();
844 EmitSehTryScopeEnd();
850 bool HasEnclosingCleanups =
851 (
Scope.getEnclosingNormalCleanup() != EHStack.stable_end());
858 llvm::BasicBlock *BranchThroughDest =
nullptr;
859 if (
Scope.hasBranchThroughs() ||
860 (FallthroughSource && FallthroughIsBranchThrough) ||
861 (HasFixups && HasEnclosingCleanups)) {
862 assert(HasEnclosingCleanups);
863 EHScope &S = *EHStack.find(
Scope.getEnclosingNormalCleanup());
867 llvm::BasicBlock *FallthroughDest =
nullptr;
877 if (!
Scope.hasBranchThroughs() && !HasFixups && !HasFallthrough &&
878 !currentFunctionUsesSEHTry() &&
Scope.getNumBranchAfters() == 1) {
879 assert(!BranchThroughDest || !IsActive);
882 llvm::Instruction *NormalCleanupDestSlot =
883 cast<llvm::Instruction>(getNormalCleanupDestSlot().getPointer());
884 if (NormalCleanupDestSlot->hasOneUse()) {
885 NormalCleanupDestSlot->user_back()->eraseFromParent();
886 NormalCleanupDestSlot->eraseFromParent();
890 llvm::BasicBlock *BranchAfter =
Scope.getBranchAfterBlock(0);
891 InstsToAppend.push_back(llvm::BranchInst::Create(BranchAfter));
898 }
else if (
Scope.getNumBranchAfters() ||
899 (HasFallthrough && !FallthroughIsBranchThrough) ||
900 (HasFixups && !HasEnclosingCleanups)) {
903 (BranchThroughDest ? BranchThroughDest : getUnreachableBlock());
906 const unsigned SwitchCapacity = 10;
912 getNormalCleanupDestSlot(),
"cleanup.dest",
nullptr, *
this);
913 llvm::SwitchInst *
Switch =
914 llvm::SwitchInst::Create(
Load,
Default, SwitchCapacity);
916 InstsToAppend.push_back(
Load);
917 InstsToAppend.push_back(
Switch);
920 if (FallthroughSource && !FallthroughIsBranchThrough) {
921 FallthroughDest = createBasicBlock(
"cleanup.cont");
923 Switch->addCase(Builder.getInt32(0), FallthroughDest);
926 for (
unsigned I = 0, E =
Scope.getNumBranchAfters(); I != E; ++I) {
928 Scope.getBranchAfterBlock(I));
933 if (HasFixups && !HasEnclosingCleanups)
937 assert(BranchThroughDest);
938 InstsToAppend.push_back(llvm::BranchInst::Create(BranchThroughDest));
943 EHStack.popCleanup();
944 assert(EHStack.hasNormalCleanups() == HasEnclosingCleanups);
946 EmitCleanup(*
this, Fn, cleanupFlags, NormalActiveFlag);
949 llvm::BasicBlock *NormalExit = Builder.GetInsertBlock();
950 for (
unsigned I = 0, E = InstsToAppend.size(); I != E; ++I)
951 InstsToAppend[I]->insertInto(NormalExit, NormalExit->end());
954 for (
unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
971 if (!HasFallthrough && FallthroughSource) {
976 Builder.restoreIP(savedInactiveFallthroughIP);
981 }
else if (HasFallthrough && FallthroughDest) {
982 assert(!FallthroughIsBranchThrough);
983 EmitBlock(FallthroughDest);
987 }
else if (HasFallthrough) {
992 Builder.ClearInsertionPoint();
999 llvm::BasicBlock *NewNormalEntry =
1004 if (NewNormalEntry != NormalEntry && NormalEntry == NormalExit)
1005 for (
unsigned I = FixupDepth, E = EHStack.getNumBranchFixups();
1007 EHStack.getBranchFixup(I).OptimisticBranchBlock = NewNormalEntry;
1011 if (NormalDeactivateOrigIP.isSet())
1012 Builder.restoreIP(NormalDeactivateOrigIP);
1013 assert(EHStack.hasNormalCleanups() || EHStack.getNumBranchFixups() == 0);
1016 if (RequiresEHCleanup) {
1017 CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1021 llvm::BasicBlock *NextAction = getEHDispatchBlock(EHParent);
1026 bool PushedTerminate =
false;
1028 llvm::CleanupPadInst *CPI =
nullptr;
1032 llvm::Value *ParentPad = CurrentFuncletPad;
1034 ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1035 CurrentFuncletPad = CPI = Builder.CreateCleanupPad(ParentPad);
1040 EHStack.pushTerminate();
1041 PushedTerminate =
true;
1042 }
else if (IsEHa && getInvokeDest()) {
1043 EmitSehCppScopeEnd();
1048 if (EHActiveFlag.
isValid() || IsActive) {
1050 EmitCleanup(*
this, Fn, cleanupFlags, EHActiveFlag);
1054 Builder.CreateCleanupRet(CPI, NextAction);
1056 Builder.CreateBr(NextAction);
1059 if (PushedTerminate)
1060 EHStack.popTerminate();
1062 Builder.restoreIP(SavedIP);
1073 &&
"stale jump destination");
1077 EHStack.getInnermostActiveNormalCleanup();
1082 if (TopCleanup == EHStack.stable_end() ||
1098 &&
"stale jump destination");
1100 if (!HaveInsertPoint())
1104 llvm::BranchInst *BI = Builder.CreateBr(Dest.
getBlock());
1108 TopCleanup = EHStack.getInnermostActiveNormalCleanup();
1113 if (TopCleanup == EHStack.stable_end() ||
1115 Builder.ClearInsertionPoint();
1128 Builder.ClearInsertionPoint();
1135 llvm::ConstantInt *Index = Builder.getInt32(Dest.
getDestIndex());
1141 cast<EHCleanupScope>(*EHStack.find(TopCleanup));
1151 assert(
Scope.isNormalCleanup());
1152 I =
Scope.getEnclosingNormalCleanup();
1169 Builder.ClearInsertionPoint();
1181 assert(
cleanup.strictlyEncloses(i));
1206 llvm::Instruction *dominatingIP) {
1212 bool isActivatedInConditional =
1215 bool needFlag =
false;
1220 if (
Scope.isNormalCleanup()) {
1221 Scope.setTestFlagInNormalCleanup();
1226 if (
Scope.isEHCleanup() &&
1228 Scope.setTestFlagInEHCleanup();
1237 if (!
var.isValid()) {
1240 "cleanup.isactive");
1242 Scope.AddAuxAllocas(AllocaTracker.
Take());
1244 assert(dominatingIP &&
"no existing variable and no dominating IP!");
1264 llvm::Instruction *dominatingIP) {
1265 assert(C != EHStack.stable_end() &&
"activating bottom of stack?");
1267 assert(!
Scope.isActive() &&
"double activation");
1271 Scope.setActive(
true);
1276 llvm::Instruction *dominatingIP) {
1277 assert(C != EHStack.stable_end() &&
"deactivating bottom of stack?");
1279 assert(
Scope.isActive() &&
"double deactivation");
1283 if (C == EHStack.stable_begin() &&
1284 CurrentCleanupScopeDepth.strictlyEncloses(C)) {
1285 PopCleanupBlock(
false,
1293 Scope.setActive(
false);
1297 if (!NormalCleanupDest.isValid())
1299 CreateDefaultAlignTempAlloca(Builder.getInt32Ty(),
"cleanup.dest.slot");
1300 return NormalCleanupDest;
1314 llvm::FunctionCallee &SehCppScope) {
1316 assert(CGF.
Builder.GetInsertBlock() && InvokeDest);
1322 CGF.
Builder.CreateInvoke(SehCppScope, Cont, InvokeDest, std::nullopt,
1329 assert(getLangOpts().EHAsynch);
1330 llvm::FunctionType *FTy =
1331 llvm::FunctionType::get(CGM.VoidTy,
false);
1332 llvm::FunctionCallee SehCppScope =
1333 CGM.CreateRuntimeFunction(FTy,
"llvm.seh.scope.begin");
1340 assert(getLangOpts().EHAsynch);
1341 llvm::FunctionType *FTy =
1342 llvm::FunctionType::get(CGM.VoidTy,
false);
1343 llvm::FunctionCallee SehCppScope =
1344 CGM.CreateRuntimeFunction(FTy,
"llvm.seh.scope.end");
1350 assert(getLangOpts().EHAsynch);
1351 llvm::FunctionType *FTy =
1352 llvm::FunctionType::get(CGM.VoidTy,
false);
1353 llvm::FunctionCallee SehCppScope =
1354 CGM.CreateRuntimeFunction(FTy,
"llvm.seh.try.begin");
1360 assert(getLangOpts().EHAsynch);
1361 llvm::FunctionType *FTy =
1362 llvm::FunctionType::get(CGM.VoidTy,
false);
1363 llvm::FunctionCallee SehCppScope =
1364 CGM.CreateRuntimeFunction(FTy,
"llvm.seh.try.end");
static void EmitSehScope(CodeGenFunction &CGF, llvm::FunctionCallee &SehCppScope)
static void EmitCleanup(CodeGenFunction &CGF, EHScopeStack::Cleanup *Fn, EHScopeStack::Cleanup::Flags flags, Address ActiveFlag)
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.
static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, EHCleanupScope &scope)
We don't need a normal entry block for the given cleanup.
static void SetupCleanupBlockActivation(CodeGenFunction &CGF, EHScopeStack::stable_iterator C, ForActivation_t kind, llvm::Instruction *dominatingIP)
The given cleanup block is changing activation state.
static llvm::BasicBlock * CreateNormalEntry(CodeGenFunction &CGF, EHCleanupScope &Scope)
static llvm::BasicBlock * SimplifyCleanupEntry(CodeGenFunction &CGF, llvm::BasicBlock *Entry)
Attempts to reduce a cleanup's entry block to a fallthrough.
static void ForwardPrebranchedFallthrough(llvm::BasicBlock *Exit, llvm::BasicBlock *From, llvm::BasicBlock *To)
static void createStoreInstBefore(llvm::Value *value, Address addr, llvm::Instruction *beforeInst, CodeGenFunction &CGF)
static llvm::LoadInst * createLoadInstBefore(Address addr, const Twine &name, llvm::Instruction *beforeInst, CodeGenFunction &CGF)
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 ...
static bool IsUsedAsEHCleanup(EHScopeStack &EHStack, EHScopeStack::stable_iterator cleanup)
static Decl::Kind getKind(const Decl *D)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
CFGTerminator getTerminator() const
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...
void EmitSehCppScopeBegin()
void ActivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
ActivateCleanupBlock - Activates an initially-inactive cleanup.
void EmitSehTryScopeEnd()
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::BasicBlock * getUnreachableBlock()
void EmitSehCppScopeEnd()
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
void initFullExprCleanupWithFlag(RawAddress ActiveFlag)
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.
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void ResolveBranchFixups(llvm::BasicBlock *Target)
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()
const TargetInfo & getTarget() const
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.
RawAddress getNormalCleanupDestSlot()
llvm::BasicBlock * getInvokeDest()
void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, Address Ptr)
Emits all the code to cause the given temporary to be cleaned up.
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
RawAddress createCleanupActiveFlag()
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...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
const LangOptions & getLangOpts() const
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.
llvm::BasicBlock * getNormalBlock() const
static size_t getSizeForCleanupSize(size_t Size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
An exceptions scope which filters exceptions thrown through it.
static size_t getSizeForNumFilters(unsigned numFilters)
unsigned getNumFilters() const
void setIsNormalCleanupKind()
void setIsEHCleanupKind()
Information for lazily generating a cleanup.
virtual void Emit(CodeGenFunction &CGF, Flags flags)=0
Emit the cleanup.
A non-stable pointer into the scope stack.
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.
class EHFilterScope * pushFilter(unsigned NumFilters)
Push an exceptions filter on the stack.
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
void popCleanup()
Pops a cleanup scope off the stack. This is private to CGCleanup.cpp.
stable_iterator getInnermostEHScope() const
bool requiresLandingPad() const
bool containsOnlyLifetimeMarkers(stable_iterator Old) const
bool empty() const
Determines whether the exception-scopes stack is empty.
void popFilter()
Pops an exceptions filter off the stack.
BranchFixup & getBranchFixup(unsigned I)
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.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
void popNullFixups()
Pops lazily-removed fixups from the end of the list.
bool hasNormalCleanups() const
Determines whether there are any normal cleanups on the stack.
stable_iterator getInnermostActiveNormalCleanup() const
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.
void pushTerminate()
Push a terminate handler on the stack.
A protected scope for zero-cost EH handling.
EHScopeStack::stable_iterator getEnclosingEHScope() const
bool hasEHBranches() const
An exceptions scope which calls std::terminate if any exception reaches it.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
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.
bool isVolatileQualified() const
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.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
@ 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...
constexpr Variable var(Literal L)
Returns the variable of L.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
bool Load(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
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
static bool needsSaving(type value)