[WinEH] Add codegen support for cleanuppad and cleanupret
[oota-llvm.git] / include / llvm / CodeGen / WinEHFuncInfo.h
index f905af655c624265a317f0b659f2c5dc614280ac..31021f12858f4956c09a7fc135b719c0a905c9ca 100644 (file)
 #ifndef LLVM_CODEGEN_WINEHFUNCINFO_H
 #define LLVM_CODEGEN_WINEHFUNCINFO_H
 
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/DenseMap.h"
 
 namespace llvm {
+class AllocaInst;
 class BasicBlock;
 class Constant;
 class Function;
-class GlobalValue;
+class GlobalVariable;
+class InvokeInst;
 class IntrinsicInst;
 class LandingPadInst;
 class MCSymbol;
+class MachineBasicBlock;
 class Value;
 
 enum ActionType { Catch, Cleanup };
@@ -75,6 +79,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;
   }
@@ -89,7 +94,7 @@ private:
   // When the parseEHActions function is called to populate a vector of
   // instances of this class, the ExceptionObjectVar field will be nullptr
   // and the ExceptionObjectIndex will be the index of the exception object in
-  // the parent function's frameescape block.
+  // the parent function's localescape block.
   const Value *ExceptionObjectVar;
   int ExceptionObjectIndex;
   TinyPtrVector<BasicBlock *> ReturnTargets;
@@ -106,44 +111,82 @@ public:
 };
 
 void parseEHActions(const IntrinsicInst *II,
-  SmallVectorImpl<ActionHandler *> &Actions);
-
+                    SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions);
 
 // The following structs respresent the .xdata for functions using C++
 // exceptions on Windows.
 
+typedef PointerUnion<const BasicBlock *, MachineBasicBlock *> MBBOrBasicBlock;
+typedef PointerUnion<const Value *, MachineBasicBlock *> ValueOrMBB;
+
 struct WinEHUnwindMapEntry {
   int ToState;
-  Function *Cleanup;
+  ValueOrMBB Cleanup;
+};
+
+/// Similar to WinEHUnwindMapEntry, but supports SEH filters.
+struct SEHUnwindMapEntry {
+  /// If unwinding continues through this handler, transition to the handler at
+  /// this state. This indexes into SEHUnwindMap.
+  int ToState = -1;
+
+  /// Holds the filter expression function.
+  const Function *Filter = nullptr;
+
+  /// Holds the __except or __finally basic block.
+  MBBOrBasicBlock Handler;
 };
 
 struct WinEHHandlerType {
   int Adjectives;
   GlobalVariable *TypeDescriptor;
-  int CatchObjIdx;
-  int CatchObjOffset;
-  Function *Handler;
+  int CatchObjRecoverIdx;
+  ValueOrMBB Handler;
 };
 
 struct WinEHTryBlockMapEntry {
-  int TryLow;
-  int TryHigh;
-  int CatchHigh;
+  int TryLow = -1;
+  int TryHigh = -1;
+  int CatchHigh = -1;
   SmallVector<WinEHHandlerType, 1> HandlerArray;
 };
 
 struct WinEHFuncInfo {
-  DenseMap<const LandingPadInst *, int> LandingPadStateMap;
+  DenseMap<const Function *, const LandingPadInst *> RootLPad;
+  DenseMap<const Function *, const InvokeInst *> LastInvoke;
+  DenseMap<const Function *, int> HandlerEnclosedState;
+  DenseMap<const Function *, bool> LastInvokeVisited;
+  DenseMap<const Instruction *, int> EHPadStateMap;
   DenseMap<const Function *, int> CatchHandlerParentFrameObjIdx;
   DenseMap<const Function *, int> CatchHandlerParentFrameObjOffset;
+  DenseMap<const Function *, int> CatchHandlerMaxState;
+  DenseMap<const Function *, int> HandlerBaseState;
   SmallVector<WinEHUnwindMapEntry, 4> UnwindMap;
   SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap;
+  SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap;
   SmallVector<std::pair<MCSymbol *, int>, 4> IPToStateList;
-  int UnwindHelpFrameIdx;
-  int UnwindHelpFrameOffset;
+  int UnwindHelpFrameIdx = INT_MAX;
+  int UnwindHelpFrameOffset = -1;
+  unsigned NumIPToStateFuncsVisited = 0;
+
+  int getLastStateNumber() const { return UnwindMap.size() - 1; }
 
-  WinEHFuncInfo() : UnwindHelpFrameIdx(INT_MAX), UnwindHelpFrameOffset(-1) {}
+  /// localescape index of the 32-bit EH registration node. Set by
+  /// WinEHStatePass and used indirectly by SEH filter functions of the parent.
+  int EHRegNodeEscapeIndex = INT_MAX;
+  const AllocaInst *EHRegNode = nullptr;
+  int EHRegNodeFrameIndex = INT_MAX;
+
+  WinEHFuncInfo() {}
 };
 
+/// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which
+/// describes the state numbers and tables used by __CxxFrameHandler3. This
+/// analysis assumes that WinEHPrepare has already been run.
+void calculateWinCXXEHStateNumbers(const Function *ParentFn,
+                                   WinEHFuncInfo &FuncInfo);
+
+void calculateSEHStateNumbers(const Function *ParentFn,
+                              WinEHFuncInfo &FuncInfo);
 }
 #endif // LLVM_CODEGEN_WINEHFUNCINFO_H