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