EHStreamer.h 5.7 KB

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