//===- llvm/CodeGen/WinEHFuncInfo.h -----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // Data structures and associated state for Windows exception handling schemes. // //===----------------------------------------------------------------------===// #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 <cstdint> #include <limits> #include <utility> namespace llvm { class AllocaInst; class BasicBlock; class FuncletPadInst; class Function; class GlobalVariable; class Instruction; class InvokeInst; class MachineBasicBlock; class MCSymbol; // The following structs respresent the .xdata tables for various // Windows-related EH personalities. using MBBOrBasicBlock = PointerUnion<const BasicBlock *, MachineBasicBlock *>; struct CxxUnwindMapEntry { int ToState; MBBOrBasicBlock Cleanup; }; /// Similar to CxxUnwindMapEntry, 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; bool IsFinally = false; /// Holds the filter expression function. const Function *Filter = nullptr; /// Holds the __except or __finally basic block. MBBOrBasicBlock Handler; }; struct WinEHHandlerType { int Adjectives; /// The CatchObj starts out life as an LLVM alloca and is eventually turned /// frame index. union { const AllocaInst *Alloca; int FrameIndex; } CatchObj = {}; GlobalVariable *TypeDescriptor; MBBOrBasicBlock Handler; }; struct WinEHTryBlockMapEntry { int TryLow = -1; int TryHigh = -1; int CatchHigh = -1; SmallVector<WinEHHandlerType, 1> HandlerArray; }; enum class ClrHandlerType { Catch, Finally, Fault, Filter }; struct ClrEHUnwindMapEntry { MBBOrBasicBlock Handler; uint32_t TypeToken; int HandlerParentState; ///< Outer handler enclosing this entry's handler int TryParentState; ///< Outer try region enclosing this entry's try region, ///< treating later catches on same try as "outer" ClrHandlerType HandlerType; }; struct WinEHFuncInfo { DenseMap<const Instruction *, int> EHPadStateMap; DenseMap<const FuncletPadInst *, int> FuncletBaseStateMap; DenseMap<const InvokeInst *, int> InvokeStateMap; DenseMap<MCSymbol *, std::pair<int, MCSymbol *>> LabelToStateMap; SmallVector<CxxUnwindMapEntry, 4> CxxUnwindMap; SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap; SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap; SmallVector<ClrEHUnwindMapEntry, 4> ClrEHUnwindMap; int UnwindHelpFrameIdx = std::numeric_limits<int>::max(); int PSPSymFrameIdx = std::numeric_limits<int>::max(); int getLastStateNumber() const { return CxxUnwindMap.size() - 1; } void addIPToStateRange(const InvokeInst *II, MCSymbol *InvokeBegin, MCSymbol *InvokeEnd); int EHRegNodeFrameIndex = std::numeric_limits<int>::max(); int EHRegNodeEndOffset = std::numeric_limits<int>::max(); int EHGuardFrameIndex = std::numeric_limits<int>::max(); int SEHSetFrameOffset = std::numeric_limits<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); void calculateClrEHStateNumbers(const Function *Fn, WinEHFuncInfo &FuncInfo); } // end namespace llvm #endif // LLVM_CODEGEN_WINEHFUNCINFO_H