+ SmallVector<const LandingPadInst *, 4> LPads;
+ for (BB = Fn->begin(); BB != EB; ++BB) {
+ const Instruction *FNP = BB->getFirstNonPHI();
+ if (BB->isEHPad() && MBBMap.count(BB))
+ MBBMap[BB]->setIsEHPad();
+ if (const auto *LPI = dyn_cast<LandingPadInst>(FNP))
+ LPads.push_back(LPI);
+ }
+
+ // If this personality uses funclets, we need to do a bit more work.
+ if (!Fn->hasPersonalityFn())
+ return;
+ EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
+ if (!isFuncletEHPersonality(Personality))
+ return;
+
+ if (Personality == EHPersonality::MSVC_Win64SEH ||
+ Personality == EHPersonality::MSVC_X86SEH) {
+ addSEHHandlersForLPads(LPads);
+ }
+
+ // Calculate state numbers if we haven't already.
+ WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
+ const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
+ if (Personality == EHPersonality::MSVC_CXX)
+ calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
+ else if (isAsynchronousEHPersonality(Personality))
+ calculateSEHStateNumbers(WinEHParentFn, EHInfo);
+ else if (Personality == EHPersonality::CoreCLR)
+ calculateClrEHStateNumbers(WinEHParentFn, EHInfo);
+
+ calculateCatchReturnSuccessorColors(WinEHParentFn, EHInfo);
+
+ // Map all BB references in the WinEH data to MBBs.
+ for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
+ for (WinEHHandlerType &H : TBME.HandlerArray) {
+ if (H.CatchObjRecoverIdx == -2 && H.CatchObj.Alloca) {
+ assert(StaticAllocaMap.count(H.CatchObj.Alloca));
+ H.CatchObj.FrameIndex = StaticAllocaMap[H.CatchObj.Alloca];
+ } else {
+ H.CatchObj.FrameIndex = INT_MAX;
+ }
+ if (const auto *BB = dyn_cast<BasicBlock>(H.Handler.get<const Value *>()))
+ H.Handler = MBBMap[BB];
+ }
+ }
+ for (WinEHUnwindMapEntry &UME : EHInfo.UnwindMap)
+ if (UME.Cleanup)
+ if (const auto *BB = dyn_cast<BasicBlock>(UME.Cleanup.get<const Value *>()))
+ UME.Cleanup = MBBMap[BB];
+ for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) {
+ const BasicBlock *BB = UME.Handler.get<const BasicBlock *>();
+ UME.Handler = MBBMap[BB];
+ }
+ for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) {
+ const BasicBlock *BB = CME.Handler.get<const BasicBlock *>();
+ CME.Handler = MBBMap[BB];
+ }
+
+ // If there's an explicit EH registration node on the stack, record its
+ // frame index.
+ if (EHInfo.EHRegNode && EHInfo.EHRegNode->getParent()->getParent() == Fn) {
+ assert(StaticAllocaMap.count(EHInfo.EHRegNode));
+ EHInfo.EHRegNodeFrameIndex = StaticAllocaMap[EHInfo.EHRegNode];
+ }
+
+ // Copy the state numbers to LandingPadInfo for the current function, which
+ // could be a handler or the parent. This should happen for 32-bit SEH and
+ // C++ EH.
+ if (Personality == EHPersonality::MSVC_CXX ||
+ Personality == EHPersonality::MSVC_X86SEH) {
+ for (const LandingPadInst *LP : LPads) {
+ MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
+ MMI.addWinEHState(LPadMBB, EHInfo.EHPadStateMap[LP]);
+ }
+ }
+}
+
+void FunctionLoweringInfo::addSEHHandlersForLPads(
+ ArrayRef<const LandingPadInst *> LPads) {
+ MachineModuleInfo &MMI = MF->getMMI();
+
+ // Iterate over all landing pads with llvm.eh.actions calls.
+ for (const LandingPadInst *LP : LPads) {
+ const IntrinsicInst *ActionsCall =
+ dyn_cast<IntrinsicInst>(LP->getNextNode());
+ if (!ActionsCall ||
+ ActionsCall->getIntrinsicID() != Intrinsic::eh_actions)
+ continue;
+
+ // Parse the llvm.eh.actions call we found.
+ MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
+ SmallVector<std::unique_ptr<ActionHandler>, 4> Actions;
+ parseEHActions(ActionsCall, Actions);
+
+ // Iterate EH actions from most to least precedence, which means
+ // iterating in reverse.
+ for (auto I = Actions.rbegin(), E = Actions.rend(); I != E; ++I) {
+ ActionHandler *Action = I->get();
+ if (auto *CH = dyn_cast<CatchHandler>(Action)) {
+ const auto *Filter =
+ dyn_cast<Function>(CH->getSelector()->stripPointerCasts());
+ assert((Filter || CH->getSelector()->isNullValue()) &&
+ "expected function or catch-all");
+ const auto *RecoverBA =
+ cast<BlockAddress>(CH->getHandlerBlockOrFunc());
+ MMI.addSEHCatchHandler(LPadMBB, Filter, RecoverBA);
+ } else {
+ assert(isa<CleanupHandler>(Action));
+ const auto *Fini = cast<Function>(Action->getHandlerBlockOrFunc());
+ MMI.addSEHCleanupHandler(LPadMBB, Fini);
+ }
+ }
+ }