[WinEH] Pull Adjectives and CatchObj out of the catchpad arg list

Clang now passes the adjectives as an argument to catchpad.

Getting the CatchObj working is simply a matter of threading another
static alloca through codegen, first as an alloca, then as a frame
index, and finally as a frame offset.

llvm-svn: 247844
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index cd36021..1b75051 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -475,6 +475,16 @@
                   HT.CatchObjRecoverIdx);
           FrameAllocOffsetRef = MCSymbolRefExpr::create(
               FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
+        } else if (HT.CatchObj.FrameOffset != INT_MAX) {
+          int Offset = HT.CatchObj.FrameOffset;
+          // For 32-bit, the catch object offset is relative to the end of the
+          // EH registration node. For 64-bit, it's relative to SP at the end of
+          // the prologue.
+          if (!shouldEmitPersonality) {
+            assert(FuncInfo.EHRegNodeEndOffset != INT_MAX);
+            Offset += FuncInfo.EHRegNodeEndOffset;
+          }
+          FrameAllocOffsetRef = MCConstantExpr::create(Offset, Asm->OutContext);
         } else {
           FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);
         }
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index f169f48..54f5553 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -819,6 +819,16 @@
     if (FuncInfo.UnwindHelpFrameIdx != INT_MAX)
       FuncInfo.UnwindHelpFrameOffset = TFI.getFrameIndexReferenceFromSP(
           Fn, FuncInfo.UnwindHelpFrameIdx, FrameReg);
+    for (WinEHTryBlockMapEntry &TBME : FuncInfo.TryBlockMap) {
+      for (WinEHHandlerType &H : TBME.HandlerArray) {
+        unsigned UnusedReg;
+        if (H.CatchObj.FrameIndex == INT_MAX)
+          H.CatchObj.FrameOffset = INT_MAX;
+        else
+          H.CatchObj.FrameOffset =
+              TFI.getFrameIndexReference(Fn, H.CatchObj.FrameIndex, UnusedReg);
+      }
+    }
   } else if (MMI.hasWinEHFuncInfo(F)) {
     WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn.getFunction());
     auto I = FuncInfo.CatchHandlerParentFrameObjIdx.find(F);
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index fe35977..baf9ee9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -294,11 +294,18 @@
     calculateSEHStateNumbers(WinEHParentFn, EHInfo);
 
   // Map all BB references in the WinEH data to MBBs.
-  for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap)
-    for (WinEHHandlerType &H : TBME.HandlerArray)
-      if (const auto *BB =
-              dyn_cast<BasicBlock>(H.Handler.get<const Value *>()))
+  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 *>()))
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 8ba6f5e..fefb444 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -2622,22 +2622,17 @@
   for (const CatchPadInst *CPI : Handlers) {
     WinEHHandlerType HT;
     Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
-    if (TypeInfo->isNullValue()) {
-      HT.Adjectives = 0x40;
+    if (TypeInfo->isNullValue())
       HT.TypeDescriptor = nullptr;
-    } else {
-      auto *GV = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
-      // Selectors are always pointers to GlobalVariables with 'struct' type.
-      // The struct has two fields, adjectives and a type descriptor.
-      auto *CS = cast<ConstantStruct>(GV->getInitializer());
-      HT.Adjectives =
-          cast<ConstantInt>(CS->getAggregateElement(0U))->getZExtValue();
-      HT.TypeDescriptor =
-          cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
-    }
+    else
+      HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
+    HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
     HT.Handler = CPI->getNormalDest();
-    // FIXME: Pass CPI->getArgOperand(1).
-    HT.CatchObjRecoverIdx = -1;
+    HT.CatchObjRecoverIdx = -2;
+    if (isa<ConstantPointerNull>(CPI->getArgOperand(2)))
+      HT.CatchObj.Alloca = nullptr;
+    else
+      HT.CatchObj.Alloca = cast<AllocaInst>(CPI->getArgOperand(2));
     TBME.HandlerArray.push_back(HT);
   }
   FuncInfo.TryBlockMap.push_back(TBME);
@@ -2713,6 +2708,7 @@
     }
     HT.Handler = cast<Function>(CH->getHandlerBlockOrFunc());
     HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
+    HT.CatchObj.Alloca = nullptr;
     TBME.HandlerArray.push_back(HT);
   }
   FuncInfo.TryBlockMap.push_back(TBME);