[SEH] Emit 32-bit SEH tables for the new EH IR
[oota-llvm.git] / lib / CodeGen / AsmPrinter / WinException.cpp
index aedac5467c67e02dd1e54c7514e48383a724bbd5..e706d73dee2ac32c7fe8b12c92724c6e474a1aa6 100644 (file)
@@ -161,7 +161,7 @@ void WinException::endFunction(const MachineFunction *MF) {
     // Emit the tables appropriate to the personality function in use. If we
     // don't recognize the personality, assume it uses an Itanium-style LSDA.
     if (Per == EHPersonality::MSVC_Win64SEH)
-      emitCSpecificHandlerTable();
+      emitCSpecificHandlerTable(MF);
     else if (Per == EHPersonality::MSVC_X86SEH)
       emitExceptHandlerTable(MF);
     else if (Per == EHPersonality::MSVC_CXX)
@@ -222,9 +222,13 @@ const MCExpr *WinException::create32bitRef(const Value *V) {
 ///       imagerel32 LabelLPad;        // Zero means __finally.
 ///     } Entries[NumEntries];
 ///   };
-void WinException::emitCSpecificHandlerTable() {
+void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
 
+  WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(MF->getFunction());
+  if (!FuncInfo.SEHUnwindMap.empty())
+    report_fatal_error("x64 SEH tables not yet implemented");
+
   // Simplifying assumptions for first implementation:
   // - Cleanups are not implemented.
   // - Filters are not implemented.
@@ -309,6 +313,15 @@ void WinException::emitCSpecificHandlerTable() {
   }
 }
 
+/// Retreive the MCSymbol for a GlobalValue or MachineBasicBlock. GlobalValues
+/// are used in the old WinEH scheme, and they will be removed eventually.
+static MCSymbol *getMCSymbolForMBBOrGV(AsmPrinter *Asm, ValueOrMBB Handler) {
+  if (Handler.is<MachineBasicBlock *>())
+    return Handler.get<MachineBasicBlock *>()->getSymbol();
+  else
+    return Asm->getSymbol(cast<GlobalValue>(Handler.get<const Value *>()));
+}
+
 void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
   const Function *F = MF->getFunction();
   const Function *ParentF = MMI->getWinEHParent(F);
@@ -422,9 +435,9 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
       int CatchHigh = TBME.CatchHigh;
       if (CatchHigh == -1) {
         for (WinEHHandlerType &HT : TBME.HandlerArray)
-          CatchHigh = std::max(
-              CatchHigh,
-              FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
+          CatchHigh =
+              std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[cast<Function>(
+                                      HT.Handler.get<const Value *>())]);
       }
 
       assert(TBME.TryLow <= TBME.TryHigh);
@@ -464,13 +477,12 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
           FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);
         }
 
-        OS.EmitIntValue(HT.Adjectives, 4);                    // Adjectives
-        OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4);   // Type
-        OS.EmitValue(FrameAllocOffsetRef, 4);                 // CatchObjOffset
-        if (HT.HandlerMBB)                                    // Handler
-          OS.EmitValue(create32bitRef(HT.HandlerMBB->getSymbol()), 4);
-        else
-          OS.EmitValue(create32bitRef(HT.Handler), 4);
+        MCSymbol *HandlerSym = getMCSymbolForMBBOrGV(Asm, HT.Handler);
+
+        OS.EmitIntValue(HT.Adjectives, 4);                  // Adjectives
+        OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type
+        OS.EmitValue(FrameAllocOffsetRef, 4);               // CatchObjOffset
+        OS.EmitValue(create32bitRef(HandlerSym), 4);        // Handler
 
         if (shouldEmitPersonality) {
           if (FuncInfo.CatchHandlerParentFrameObjOffset.empty()) {
@@ -482,7 +494,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
           } else {
             MCSymbol *ParentFrameOffset =
                 Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
-                    GlobalValue::getRealLinkageName(HT.Handler->getName()));
+                    GlobalValue::getRealLinkageName(
+                        HT.Handler.get<const Value *>()->getName()));
             const MCSymbolRefExpr *ParentFrameOffsetRef =
                 MCSymbolRefExpr::create(ParentFrameOffset, Asm->OutContext);
             OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset
@@ -642,6 +655,19 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
     BaseState = -2;
   }
 
+  if (!FuncInfo.SEHUnwindMap.empty()) {
+    for (SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
+      MCSymbol *ExceptOrFinally =
+          UME.Handler.get<MachineBasicBlock *>()->getSymbol();
+      OS.EmitIntValue(UME.ToState, 4);                  // ToState
+      OS.EmitValue(create32bitRef(UME.Filter), 4);      // Filter
+      OS.EmitValue(create32bitRef(ExceptOrFinally), 4); // Except/Finally
+    }
+    return;
+  }
+  // FIXME: The following code is for the old landingpad-based SEH
+  // implementation. Remove it when possible.
+
   // Build a list of pointers to LandingPadInfos and then sort by WinEHState.
   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
   SmallVector<const LandingPadInfo *, 4> LPads;