EHStreamer.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //===-- EHStreamer.h - Exception Handling Directive Streamer ---*- 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. // This file contains support for writing exception info into assembly files.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H
  14. #define LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H
  15. #include "AsmPrinterHandler.h"
  16. #include "llvm/ADT/DenseMap.h"
  17. namespace llvm {
  18. struct LandingPadInfo;
  19. class MachineModuleInfo;
  20. class MachineInstr;
  21. class MachineFunction;
  22. class AsmPrinter;
  23. class MCSymbol;
  24. class MCSymbolRefExpr;
  25. template <typename T>
  26. class SmallVectorImpl;
  27. /// Emits exception handling directives.
  28. class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler {
  29. protected:
  30. /// Target of directive emission.
  31. AsmPrinter *Asm;
  32. /// Collected machine module information.
  33. MachineModuleInfo *MMI;
  34. /// How many leading type ids two landing pads have in common.
  35. static unsigned sharedTypeIDs(const LandingPadInfo *L,
  36. const LandingPadInfo *R);
  37. /// Structure holding a try-range and the associated landing pad.
  38. struct PadRange {
  39. // The index of the landing pad.
  40. unsigned PadIndex;
  41. // The index of the begin and end labels in the landing pad's label lists.
  42. unsigned RangeIndex;
  43. };
  44. typedef DenseMap<MCSymbol *, PadRange> RangeMapType;
  45. /// Structure describing an entry in the actions table.
  46. struct ActionEntry {
  47. int ValueForTypeID; // The value to write - may not be equal to the type id.
  48. int NextAction;
  49. unsigned Previous;
  50. };
  51. /// Structure describing an entry in the call-site table.
  52. struct CallSiteEntry {
  53. // The 'try-range' is BeginLabel .. EndLabel.
  54. MCSymbol *BeginLabel; // Null indicates the start of the function.
  55. MCSymbol *EndLabel; // Null indicates the end of the function.
  56. // LPad contains the landing pad start labels.
  57. const LandingPadInfo *LPad; // Null indicates that there is no landing pad.
  58. unsigned Action;
  59. };
  60. /// Compute the actions table and gather the first action index for each
  61. /// landing pad site.
  62. unsigned computeActionsTable(const SmallVectorImpl<const LandingPadInfo*>&LPs,
  63. SmallVectorImpl<ActionEntry> &Actions,
  64. SmallVectorImpl<unsigned> &FirstActions);
  65. /// Return `true' if this is a call to a function marked `nounwind'. Return
  66. /// `false' otherwise.
  67. bool callToNoUnwindFunction(const MachineInstr *MI);
  68. void computePadMap(const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
  69. RangeMapType &PadMap);
  70. /// Compute the call-site table. The entry for an invoke has a try-range
  71. /// containing the call, a non-zero landing pad and an appropriate action.
  72. /// The entry for an ordinary call has a try-range containing the call and
  73. /// zero for the landing pad and the action. Calls marked 'nounwind' have
  74. /// no entry and must not be contained in the try-range of any entry - they
  75. /// form gaps in the table. Entries must be ordered by try-range address.
  76. void computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
  77. const SmallVectorImpl<const LandingPadInfo *> &LPs,
  78. const SmallVectorImpl<unsigned> &FirstActions);
  79. /// Emit landing pads and actions.
  80. ///
  81. /// The general organization of the table is complex, but the basic concepts
  82. /// are easy. First there is a header which describes the location and
  83. /// organization of the three components that follow.
  84. /// 1. The landing pad site information describes the range of code covered
  85. /// by the try. In our case it's an accumulation of the ranges covered
  86. /// by the invokes in the try. There is also a reference to the landing
  87. /// pad that handles the exception once processed. Finally an index into
  88. /// the actions table.
  89. /// 2. The action table, in our case, is composed of pairs of type ids
  90. /// and next action offset. Starting with the action index from the
  91. /// landing pad site, each type Id is checked for a match to the current
  92. /// exception. If it matches then the exception and type id are passed
  93. /// on to the landing pad. Otherwise the next action is looked up. This
  94. /// chain is terminated with a next action of zero. If no type id is
  95. /// found the frame is unwound and handling continues.
  96. /// 3. Type id table contains references to all the C++ typeinfo for all
  97. /// catches in the function. This tables is reversed indexed base 1.
  98. void emitExceptionTable();
  99. virtual void emitTypeInfos(unsigned TTypeEncoding);
  100. // Helpers for for identifying what kind of clause an EH typeid or selector
  101. // corresponds to. Negative selectors are for filter clauses, the zero
  102. // selector is for cleanups, and positive selectors are for catch clauses.
  103. static bool isFilterEHSelector(int Selector) { return Selector < 0; }
  104. static bool isCleanupEHSelector(int Selector) { return Selector == 0; }
  105. static bool isCatchEHSelector(int Selector) { return Selector > 0; }
  106. public:
  107. EHStreamer(AsmPrinter *A);
  108. ~EHStreamer() override;
  109. // Unused.
  110. void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
  111. void beginInstruction(const MachineInstr *MI) override {}
  112. void endInstruction() override {}
  113. };
  114. }
  115. #endif