[WinEH] Fill out .xdata for catch objects
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 3 Apr 2015 22:49:05 +0000 (22:49 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 3 Apr 2015 22:49:05 +0000 (22:49 +0000)
This add support for catching an exception such that an exception object
available to the catch handler will be initialized by the runtime.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234062 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/WinEHFuncInfo.h
lib/CodeGen/AsmPrinter/Win64Exception.cpp
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/WinEHPrepare.cpp
test/CodeGen/WinEH/cppeh-prepared-catch.ll

index f905af655c624265a317f0b659f2c5dc614280ac..732b5d249523b41c0b2210b3f5161f48b78eb3f4 100644 (file)
@@ -75,6 +75,7 @@ public:
 
   void setExceptionVar(const Value *Val) { ExceptionObjectVar = Val; }
   void setExceptionVarIndex(int Index) { ExceptionObjectIndex = Index;  }
+  int getExceptionVarIndex() const { return ExceptionObjectIndex; }
   void setReturnTargets(TinyPtrVector<BasicBlock *> &Targets) {
     ReturnTargets = Targets;
   }
@@ -120,8 +121,7 @@ struct WinEHUnwindMapEntry {
 struct WinEHHandlerType {
   int Adjectives;
   GlobalVariable *TypeDescriptor;
-  int CatchObjIdx;
-  int CatchObjOffset;
+  int CatchObjRecoverIdx;
   Function *Handler;
 };
 
index 7a82daa333709edecbabf7dede52d1206717657d..676ce65dedb1ffb0087e1533ea27500a3bb56850 100644 (file)
@@ -450,9 +450,16 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) {
         const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create(
             ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
 
+        MCSymbol *FrameAllocOffset =
+            Asm->OutContext.getOrCreateFrameAllocSymbol(
+                GlobalValue::getRealLinkageName(F->getName()),
+                HT.CatchObjRecoverIdx);
+        const MCSymbolRefExpr *FrameAllocOffsetRef = MCSymbolRefExpr::Create(
+            FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
+
         OS.EmitIntValue(HT.Adjectives, 4);                    // Adjectives
         OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type
-        OS.EmitIntValue(HT.CatchObjOffset, 4);                // CatchObjOffset
+        OS.EmitValue(FrameAllocOffsetRef, 4);                 // CatchObjOffset
         OS.EmitValue(createImageRel32(HT.Handler), 4);        // Handler
         OS.EmitValue(ParentFrameOffsetRef, 4);                // ParentFrameOffset
       }
index 987ba83b391aa90b99abb2391346482aa23a70b7..bfaab9e6b6b68123c440afc3ec8c185d94a1e8f2 100644 (file)
@@ -321,9 +321,7 @@ void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
           cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
     }
     HT.Handler = cast<Function>(CH->getHandlerBlockOrFunc());
-    // FIXME: We don't support catching objects yet!
-    HT.CatchObjIdx = INT_MAX;
-    HT.CatchObjOffset = 0;
+    HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
     TBME.HandlerArray.push_back(HT);
   }
   FuncInfo.TryBlockMap.push_back(TBME);
index 008d7dc2b2563d4f98ae61722f1a0c0878f58a00..710d8073fedf2444972f16a2e35b722e4493748b 100644 (file)
@@ -5410,8 +5410,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
              "can only escape static allocas");
       int FI = FuncInfo.StaticAllocaMap[Slot];
       MCSymbol *FrameAllocSym =
-          MF.getMMI().getContext().getOrCreateFrameAllocSymbol(MF.getName(),
-                                                               Idx);
+          MF.getMMI().getContext().getOrCreateFrameAllocSymbol(
+              GlobalValue::getRealLinkageName(MF.getName()), Idx);
       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, dl,
               TII->get(TargetOpcode::FRAME_ALLOC))
           .addSym(FrameAllocSym)
@@ -5431,8 +5431,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
     auto *Idx = cast<ConstantInt>(I.getArgOperand(2));
     unsigned IdxVal = unsigned(Idx->getLimitedValue(INT_MAX));
     MCSymbol *FrameAllocSym =
-        MF.getMMI().getContext().getOrCreateFrameAllocSymbol(Fn->getName(),
-                                                             IdxVal);
+        MF.getMMI().getContext().getOrCreateFrameAllocSymbol(
+            GlobalValue::getRealLinkageName(Fn->getName()), IdxVal);
 
     // Create a TargetExternalSymbol for the label to avoid any target lowering
     // that would make this PC relative.
index d12a8ed472bce1f96e3fdc11af44eeae2f63aabf..9ebe8a2fc10a048557ba8d52e382fdce0f08148d 100644 (file)
@@ -1595,7 +1595,7 @@ CleanupHandler *WinEHPrepare::findCleanupHandler(BasicBlock *StartBB,
 // This is a public function, declared in WinEHFuncInfo.h and is also
 // referenced by WinEHNumbering in FunctionLoweringInfo.cpp.
 void llvm::parseEHActions(const IntrinsicInst *II,
-  SmallVectorImpl<ActionHandler *> &Actions) {
+                          SmallVectorImpl<ActionHandler *> &Actions) {
   for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) {
     uint64_t ActionKind =
       cast<ConstantInt>(II->getArgOperand(I))->getZExtValue();
@@ -1609,14 +1609,14 @@ void llvm::parseEHActions(const IntrinsicInst *II,
       CH->setHandlerBlockOrFunc(Handler);
       CH->setExceptionVarIndex(EHObjIndexVal);
       Actions.push_back(CH);
-    }
-    else {
-      assert(ActionKind == 0 && "expected a cleanup or a catch action!");
+    } else if (ActionKind == 0) {
       Constant *Handler = cast<Constant>(II->getArgOperand(I + 1));
       I += 2;
       auto *CH = new CleanupHandler(/*BB=*/nullptr);
       CH->setHandlerBlockOrFunc(Handler);
       Actions.push_back(CH);
+    } else {
+      llvm_unreachable("Expected either a catch or cleanup handler!");
     }
   }
   std::reverse(Actions.begin(), Actions.end());
index 3bc864833e114e3a519050edae9235ca60b9abb5..937b216edbdfaa771472f583157f1ef610b44f6d 100644 (file)
@@ -148,13 +148,13 @@ try.cont8:                                        ; preds = %lpad2, %try.cont
 ; CHECK-NEXT:"$handlerMap$0$?f@@YAXXZ":
 ; CHECK-NEXT:        .long   8
 ; CHECK-NEXT:        .long   "??_R0H@8"@IMGREL
-; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   ".L?f@@YAXXZ$frame_escape_0"
 ; CHECK-NEXT:        .long   "?f@@YAXXZ.catch"@IMGREL
 ; CHECK-NEXT:        .long   ".L?f@@YAXXZ.catch$parent_frame_offset"
 ; CHECK-NEXT:"$handlerMap$1$?f@@YAXXZ":
 ; CHECK-NEXT:        .long   0
 ; CHECK-NEXT:        .long   "??_R0N@8"@IMGREL
-; CHECK-NEXT:        .long   0
+; CHECK-NEXT:        .long   ".L?f@@YAXXZ$frame_escape_1"
 ; CHECK-NEXT:        .long   "?f@@YAXXZ.catch1"@IMGREL
 ; CHECK-NEXT:        .long   ".L?f@@YAXXZ.catch1$parent_frame_offset"
 ; CHECK-NEXT:"$ip2state$?f@@YAXXZ":