| //===- EHStreamer.h - Exception Handling Directive Streamer -----*- 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 | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file contains support for writing exception info into assembly files. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H | 
 | #define LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H | 
 |  | 
 | #include "llvm/ADT/DenseMap.h" | 
 | #include "llvm/CodeGen/AsmPrinterHandler.h" | 
 | #include "llvm/Support/Compiler.h" | 
 |  | 
 | namespace llvm { | 
 |  | 
 | class AsmPrinter; | 
 | struct LandingPadInfo; | 
 | class MachineInstr; | 
 | class MachineModuleInfo; | 
 | class MCSymbol; | 
 | template <typename T> class SmallVectorImpl; | 
 |  | 
 | /// Emits exception handling directives. | 
 | class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler { | 
 | protected: | 
 |   /// Target of directive emission. | 
 |   AsmPrinter *Asm; | 
 |  | 
 |   /// Collected machine module information. | 
 |   MachineModuleInfo *MMI; | 
 |  | 
 |   /// How many leading type ids two landing pads have in common. | 
 |   static unsigned sharedTypeIDs(const LandingPadInfo *L, | 
 |                                 const LandingPadInfo *R); | 
 |  | 
 |   /// Structure holding a try-range and the associated landing pad. | 
 |   struct PadRange { | 
 |     // The index of the landing pad. | 
 |     unsigned PadIndex; | 
 |  | 
 |     // The index of the begin and end labels in the landing pad's label lists. | 
 |     unsigned RangeIndex; | 
 |   }; | 
 |  | 
 |   using RangeMapType = DenseMap<MCSymbol *, PadRange>; | 
 |  | 
 |   /// Structure describing an entry in the actions table. | 
 |   struct ActionEntry { | 
 |     int ValueForTypeID; // The value to write - may not be equal to the type id. | 
 |     int NextAction; | 
 |     unsigned Previous; | 
 |   }; | 
 |  | 
 |   /// Structure describing an entry in the call-site table. | 
 |   struct CallSiteEntry { | 
 |     // The 'try-range' is BeginLabel .. EndLabel. | 
 |     MCSymbol *BeginLabel; // Null indicates the start of the function. | 
 |     MCSymbol *EndLabel;   // Null indicates the end of the function. | 
 |  | 
 |     // LPad contains the landing pad start labels. | 
 |     const LandingPadInfo *LPad; // Null indicates that there is no landing pad. | 
 |  | 
 |     unsigned Action; | 
 |   }; | 
 |  | 
 |   /// Structure describing a contiguous range of call-sites which reside | 
 |   /// in the same procedure fragment. With -fbasic-block-sections, there will | 
 |   /// be one call site range per basic block section. Otherwise, we will have | 
 |   /// one call site range containing all the call sites in the function. | 
 |   struct CallSiteRange { | 
 |     // Symbol marking the beginning of the precedure fragment. | 
 |     MCSymbol *FragmentBeginLabel = nullptr; | 
 |     // Symbol marking the end of the procedure fragment. | 
 |     MCSymbol *FragmentEndLabel = nullptr; | 
 |     // LSDA symbol for this call-site range. | 
 |     MCSymbol *ExceptionLabel = nullptr; | 
 |     // Index of the first call-site entry in the call-site table which | 
 |     // belongs to this range. | 
 |     size_t CallSiteBeginIdx = 0; | 
 |     // Index just after the last call-site entry in the call-site table which | 
 |     // belongs to this range. | 
 |     size_t CallSiteEndIdx = 0; | 
 |     // Whether this is the call-site range containing all the landing pads. | 
 |     bool IsLPRange = false; | 
 |   }; | 
 |  | 
 |   /// Compute the actions table and gather the first action index for each | 
 |   /// landing pad site. | 
 |   void computeActionsTable( | 
 |       const SmallVectorImpl<const LandingPadInfo *> &LandingPads, | 
 |       SmallVectorImpl<ActionEntry> &Actions, | 
 |       SmallVectorImpl<unsigned> &FirstActions); | 
 |  | 
 |   void computePadMap(const SmallVectorImpl<const LandingPadInfo *> &LandingPads, | 
 |                      RangeMapType &PadMap); | 
 |  | 
 |   /// Compute the call-site table and the call-site ranges. The entry for an | 
 |   /// invoke has a try-range containing the call, a non-zero landing pad and an | 
 |   /// appropriate action. The entry for an ordinary call has a try-range | 
 |   /// containing the call and zero for the landing pad and the action.  Calls | 
 |   /// marked 'nounwind' have no entry and must not be contained in the try-range | 
 |   /// of any entry - they form gaps in the table.  Entries must be ordered by | 
 |   /// try-range address. CallSiteRanges vector is only populated for Itanium | 
 |   /// exception handling. | 
 |   virtual void computeCallSiteTable( | 
 |       SmallVectorImpl<CallSiteEntry> &CallSites, | 
 |       SmallVectorImpl<CallSiteRange> &CallSiteRanges, | 
 |       const SmallVectorImpl<const LandingPadInfo *> &LandingPads, | 
 |       const SmallVectorImpl<unsigned> &FirstActions); | 
 |  | 
 |   /// Emit landing pads and actions. | 
 |   /// | 
 |   /// The general organization of the table is complex, but the basic concepts | 
 |   /// are easy.  First there is a header which describes the location and | 
 |   /// organization of the three components that follow. | 
 |   ///  1. The landing pad site information describes the range of code covered | 
 |   ///     by the try.  In our case it's an accumulation of the ranges covered | 
 |   ///     by the invokes in the try.  There is also a reference to the landing | 
 |   ///     pad that handles the exception once processed.  Finally an index into | 
 |   ///     the actions table. | 
 |   ///  2. The action table, in our case, is composed of pairs of type ids | 
 |   ///     and next action offset.  Starting with the action index from the | 
 |   ///     landing pad site, each type Id is checked for a match to the current | 
 |   ///     exception.  If it matches then the exception and type id are passed | 
 |   ///     on to the landing pad.  Otherwise the next action is looked up.  This | 
 |   ///     chain is terminated with a next action of zero.  If no type id is | 
 |   ///     found the frame is unwound and handling continues. | 
 |   ///  3. Type id table contains references to all the C++ typeinfo for all | 
 |   ///     catches in the function.  This tables is reversed indexed base 1. | 
 |   /// | 
 |   /// Returns the starting symbol of an exception table. | 
 |   MCSymbol *emitExceptionTable(); | 
 |  | 
 |   virtual void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel); | 
 |  | 
 |   // Helpers for identifying what kind of clause an EH typeid or selector | 
 |   // corresponds to. Negative selectors are for filter clauses, the zero | 
 |   // selector is for cleanups, and positive selectors are for catch clauses. | 
 |   static bool isFilterEHSelector(int Selector) { return Selector < 0; } | 
 |   static bool isCleanupEHSelector(int Selector) { return Selector == 0; } | 
 |   static bool isCatchEHSelector(int Selector) { return Selector > 0; } | 
 |  | 
 | public: | 
 |   EHStreamer(AsmPrinter *A); | 
 |   ~EHStreamer() override; | 
 |  | 
 |   // Unused. | 
 |   void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {} | 
 |   void beginInstruction(const MachineInstr *MI) override {} | 
 |   void endInstruction() override {} | 
 |  | 
 |   /// Return `true' if this is a call to a function marked `nounwind'. Return | 
 |   /// `false' otherwise. | 
 |   static bool callToNoUnwindFunction(const MachineInstr *MI); | 
 | }; | 
 |  | 
 | } // end namespace llvm | 
 |  | 
 | #endif // LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H |