[SEH] Implement GetExceptionCode in __except blocks
[oota-llvm.git] / lib / CodeGen / SelectionDAG / FunctionLoweringInfo.cpp
index bb40326ba2d16308178755602ff925599b33feaa..fc5ca3ec58635304248f410e6c963d1d90edf574 100644 (file)
@@ -202,8 +202,9 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
       // during the initial isel pass through the IR so that it is done
       // in a predictable order.
       if (const DbgDeclareInst *DI = dyn_cast<DbgDeclareInst>(I)) {
-        DIVariable DIVar = DI->getVariable();
-        if (MMI.hasDebugInfo() && DIVar && DI->getDebugLoc()) {
+        assert(DI->getVariable() && "Missing variable");
+        assert(DI->getDebugLoc() && "Missing location");
+        if (MMI.hasDebugInfo()) {
           // Don't handle byval struct arguments or VLAs, for example.
           // Non-byval arguments are handled here (they refer to the stack
           // temporary alloca at this point).
@@ -270,40 +271,49 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
   }
 
   // Mark landing pad blocks.
-  const LandingPadInst *LP = nullptr;
+  SmallVector<const LandingPadInst *, 4> LPads;
   for (BB = Fn->begin(); BB != EB; ++BB) {
     if (const auto *Invoke = dyn_cast<InvokeInst>(BB->getTerminator()))
       MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
     if (BB->isLandingPad())
-      LP = BB->getLandingPadInst();
+      LPads.push_back(BB->getLandingPadInst());
   }
 
-  // Calculate EH numbers for MSVC C++ EH and save SEH handlers if necessary.
+  // If this is an MSVC EH personality, we need to do a bit more work.
   EHPersonality Personality = EHPersonality::Unknown;
-  if (LP)
-    Personality = classifyEHPersonality(LP->getPersonalityFn());
+  if (!LPads.empty())
+    Personality = classifyEHPersonality(LPads.back()->getPersonalityFn());
+  if (!isMSVCEHPersonality(Personality))
+    return;
+
+  WinEHFuncInfo *EHInfo = nullptr;
   if (Personality == EHPersonality::MSVC_Win64SEH) {
-    addSEHHandlersForLPads();
+    addSEHHandlersForLPads(LPads);
   } else if (Personality == EHPersonality::MSVC_CXX) {
     const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
-    WinEHFuncInfo &FI = MMI.getWinEHFuncInfo(WinEHParentFn);
-    if (FI.LandingPadStateMap.empty()) {
-      WinEHNumbering Num(FI);
+    EHInfo = &MMI.getWinEHFuncInfo(WinEHParentFn);
+    if (EHInfo->LandingPadStateMap.empty()) {
+      WinEHNumbering Num(*EHInfo);
       Num.calculateStateNumbers(*WinEHParentFn);
       // Pop everything on the handler stack.
       Num.processCallSite(None, ImmutableCallSite());
     }
+
+    // Copy the state numbers to LandingPadInfo for the current function, which
+    // could be a handler or the parent.
+    for (const LandingPadInst *LP : LPads) {
+      MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
+      MMI.addWinEHState(LPadMBB, EHInfo->LandingPadStateMap[LP]);
+    }
   }
 }
 
-void FunctionLoweringInfo::addSEHHandlersForLPads() {
+void FunctionLoweringInfo::addSEHHandlersForLPads(
+    ArrayRef<const LandingPadInst *> LPads) {
   MachineModuleInfo &MMI = MF->getMMI();
 
   // Iterate over all landing pads with llvm.eh.actions calls.
-  for (const BasicBlock &BB : *Fn) {
-    const LandingPadInst *LP = BB.getLandingPadInst();
-    if (!LP)
-      continue;
+  for (const LandingPadInst *LP : LPads) {
     const IntrinsicInst *ActionsCall =
         dyn_cast<IntrinsicInst>(LP->getNextNode());
     if (!ActionsCall ||