1 //===-- llvm/CodeGen/WinEHFuncInfo.h ----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Data structures and associated state for Windows exception handling schemes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_WINEHFUNCINFO_H 15 #define LLVM_CODEGEN_WINEHFUNCINFO_H 16 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/TinyPtrVector.h" 19 #include "llvm/ADT/DenseMap.h" 20 21 namespace llvm { 22 class BasicBlock; 23 class Constant; 24 class Function; 25 class GlobalVariable; 26 class InvokeInst; 27 class IntrinsicInst; 28 class LandingPadInst; 29 class MCSymbol; 30 class Value; 31 32 enum ActionType { Catch, Cleanup }; 33 34 class ActionHandler { 35 public: ActionHandler(BasicBlock * BB,ActionType Type)36 ActionHandler(BasicBlock *BB, ActionType Type) 37 : StartBB(BB), Type(Type), EHState(-1), HandlerBlockOrFunc(nullptr) {} 38 getType()39 ActionType getType() const { return Type; } getStartBlock()40 BasicBlock *getStartBlock() const { return StartBB; } 41 hasBeenProcessed()42 bool hasBeenProcessed() { return HandlerBlockOrFunc != nullptr; } 43 setHandlerBlockOrFunc(Constant * F)44 void setHandlerBlockOrFunc(Constant *F) { HandlerBlockOrFunc = F; } getHandlerBlockOrFunc()45 Constant *getHandlerBlockOrFunc() { return HandlerBlockOrFunc; } 46 setEHState(int State)47 void setEHState(int State) { EHState = State; } getEHState()48 int getEHState() const { return EHState; } 49 50 private: 51 BasicBlock *StartBB; 52 ActionType Type; 53 int EHState; 54 55 // Can be either a BlockAddress or a Function depending on the EH personality. 56 Constant *HandlerBlockOrFunc; 57 }; 58 59 class CatchHandler : public ActionHandler { 60 public: CatchHandler(BasicBlock * BB,Constant * Selector,BasicBlock * NextBB)61 CatchHandler(BasicBlock *BB, Constant *Selector, BasicBlock *NextBB) 62 : ActionHandler(BB, ActionType::Catch), Selector(Selector), 63 NextBB(NextBB), ExceptionObjectVar(nullptr), 64 ExceptionObjectIndex(-1) {} 65 66 // Method for support type inquiry through isa, cast, and dyn_cast: classof(const ActionHandler * H)67 static inline bool classof(const ActionHandler *H) { 68 return H->getType() == ActionType::Catch; 69 } 70 getSelector()71 Constant *getSelector() const { return Selector; } getNextBB()72 BasicBlock *getNextBB() const { return NextBB; } 73 getExceptionVar()74 const Value *getExceptionVar() { return ExceptionObjectVar; } getReturnTargets()75 TinyPtrVector<BasicBlock *> &getReturnTargets() { return ReturnTargets; } 76 setExceptionVar(const Value * Val)77 void setExceptionVar(const Value *Val) { ExceptionObjectVar = Val; } setExceptionVarIndex(int Index)78 void setExceptionVarIndex(int Index) { ExceptionObjectIndex = Index; } getExceptionVarIndex()79 int getExceptionVarIndex() const { return ExceptionObjectIndex; } setReturnTargets(TinyPtrVector<BasicBlock * > & Targets)80 void setReturnTargets(TinyPtrVector<BasicBlock *> &Targets) { 81 ReturnTargets = Targets; 82 } 83 84 private: 85 Constant *Selector; 86 BasicBlock *NextBB; 87 // While catch handlers are being outlined the ExceptionObjectVar field will 88 // be populated with the instruction in the parent frame that corresponds 89 // to the exception object (or nullptr if the catch does not use an 90 // exception object) and the ExceptionObjectIndex field will be -1. 91 // When the parseEHActions function is called to populate a vector of 92 // instances of this class, the ExceptionObjectVar field will be nullptr 93 // and the ExceptionObjectIndex will be the index of the exception object in 94 // the parent function's localescape block. 95 const Value *ExceptionObjectVar; 96 int ExceptionObjectIndex; 97 TinyPtrVector<BasicBlock *> ReturnTargets; 98 }; 99 100 class CleanupHandler : public ActionHandler { 101 public: CleanupHandler(BasicBlock * BB)102 CleanupHandler(BasicBlock *BB) : ActionHandler(BB, ActionType::Cleanup) {} 103 104 // Method for support type inquiry through isa, cast, and dyn_cast: classof(const ActionHandler * H)105 static inline bool classof(const ActionHandler *H) { 106 return H->getType() == ActionType::Cleanup; 107 } 108 }; 109 110 void parseEHActions(const IntrinsicInst *II, 111 SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions); 112 113 // The following structs respresent the .xdata for functions using C++ 114 // exceptions on Windows. 115 116 struct WinEHUnwindMapEntry { 117 int ToState; 118 Function *Cleanup; 119 }; 120 121 struct WinEHHandlerType { 122 int Adjectives; 123 GlobalVariable *TypeDescriptor; 124 int CatchObjRecoverIdx; 125 Function *Handler; 126 }; 127 128 struct WinEHTryBlockMapEntry { 129 int TryLow; 130 int TryHigh; 131 SmallVector<WinEHHandlerType, 1> HandlerArray; 132 }; 133 134 struct WinEHFuncInfo { 135 DenseMap<const Function *, const LandingPadInst *> RootLPad; 136 DenseMap<const Function *, const InvokeInst *> LastInvoke; 137 DenseMap<const Function *, int> HandlerEnclosedState; 138 DenseMap<const Function *, bool> LastInvokeVisited; 139 DenseMap<const LandingPadInst *, int> LandingPadStateMap; 140 DenseMap<const Function *, int> CatchHandlerParentFrameObjIdx; 141 DenseMap<const Function *, int> CatchHandlerParentFrameObjOffset; 142 DenseMap<const Function *, int> CatchHandlerMaxState; 143 DenseMap<const Function *, int> HandlerBaseState; 144 SmallVector<WinEHUnwindMapEntry, 4> UnwindMap; 145 SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap; 146 SmallVector<std::pair<MCSymbol *, int>, 4> IPToStateList; 147 int UnwindHelpFrameIdx = INT_MAX; 148 int UnwindHelpFrameOffset = -1; 149 unsigned NumIPToStateFuncsVisited = 0; 150 151 /// localescape index of the 32-bit EH registration node. Set by 152 /// WinEHStatePass and used indirectly by SEH filter functions of the parent. 153 int EHRegNodeEscapeIndex = INT_MAX; 154 WinEHFuncInfoWinEHFuncInfo155 WinEHFuncInfo() {} 156 }; 157 158 /// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which 159 /// describes the state numbers and tables used by __CxxFrameHandler3. This 160 /// analysis assumes that WinEHPrepare has already been run. 161 void calculateWinCXXEHStateNumbers(const Function *ParentFn, 162 WinEHFuncInfo &FuncInfo); 163 164 } 165 #endif // LLVM_CODEGEN_WINEHFUNCINFO_H 166