File indexing completed on 2026-05-10 08:44:16
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_MC_MCWINEH_H
0010 #define LLVM_MC_MCWINEH_H
0011
0012 #include "llvm/ADT/MapVector.h"
0013 #include <vector>
0014
0015 namespace llvm {
0016 class MCSection;
0017 class MCStreamer;
0018 class MCSymbol;
0019
0020 namespace WinEH {
0021 struct Instruction {
0022 const MCSymbol *Label;
0023 unsigned Offset;
0024 unsigned Register;
0025 unsigned Operation;
0026
0027 Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off)
0028 : Label(L), Offset(Off), Register(Reg), Operation(Op) {}
0029
0030 bool operator==(const Instruction &I) const {
0031
0032
0033 return Offset == I.Offset && Register == I.Register &&
0034 Operation == I.Operation;
0035 }
0036 bool operator!=(const Instruction &I) const { return !(*this == I); }
0037 };
0038
0039 struct FrameInfo {
0040 const MCSymbol *Begin = nullptr;
0041 const MCSymbol *End = nullptr;
0042 const MCSymbol *FuncletOrFuncEnd = nullptr;
0043 const MCSymbol *ExceptionHandler = nullptr;
0044 const MCSymbol *Function = nullptr;
0045 const MCSymbol *PrologEnd = nullptr;
0046 const MCSymbol *Symbol = nullptr;
0047 MCSection *TextSection = nullptr;
0048 uint32_t PackedInfo = 0;
0049 uint32_t PrologCodeBytes = 0;
0050
0051 bool HandlesUnwind = false;
0052 bool HandlesExceptions = false;
0053 bool EmitAttempted = false;
0054 bool Fragment = false;
0055
0056 int LastFrameInst = -1;
0057 const FrameInfo *ChainedParent = nullptr;
0058 std::vector<Instruction> Instructions;
0059 struct Epilog {
0060 std::vector<Instruction> Instructions;
0061 unsigned Condition;
0062 MCSymbol *End;
0063 };
0064 MapVector<MCSymbol *, Epilog> EpilogMap;
0065
0066
0067 struct Segment {
0068 int64_t Offset;
0069 int64_t Length;
0070 bool HasProlog;
0071 MCSymbol *Symbol = nullptr;
0072
0073 MapVector<MCSymbol *, int64_t> Epilogs;
0074
0075 Segment(int64_t Offset, int64_t Length, bool HasProlog = false)
0076 : Offset(Offset), Length(Length), HasProlog(HasProlog) {}
0077 };
0078
0079 std::vector<Segment> Segments;
0080
0081 FrameInfo() = default;
0082 FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel)
0083 : Begin(BeginFuncEHLabel), Function(Function) {}
0084 FrameInfo(const MCSymbol *Function, const MCSymbol *BeginFuncEHLabel,
0085 const FrameInfo *ChainedParent)
0086 : Begin(BeginFuncEHLabel), Function(Function),
0087 ChainedParent(ChainedParent) {}
0088
0089 bool empty() const {
0090 if (!Instructions.empty())
0091 return false;
0092 for (const auto &E : EpilogMap)
0093 if (!E.second.Instructions.empty())
0094 return false;
0095 return true;
0096 }
0097 };
0098
0099 class UnwindEmitter {
0100 public:
0101 virtual ~UnwindEmitter();
0102
0103
0104 virtual void Emit(MCStreamer &Streamer) const = 0;
0105 virtual void EmitUnwindInfo(MCStreamer &Streamer, FrameInfo *FI,
0106 bool HandlerData) const = 0;
0107 };
0108 }
0109 }
0110
0111 #endif