//===- llvm/CodeGen/WinEHFuncInfo.h -----------------------------*- C++ -*-===//
 
//
 
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 
// See https://llvm.org/LICENSE.txt for license information.
 
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
//
 
//===----------------------------------------------------------------------===//
 
//
 
// 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