Line data Source code
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 : #include "llvm/Support/Compiler.h"
20 :
21 : namespace llvm {
22 :
23 : class AsmPrinter;
24 : struct LandingPadInfo;
25 : class MachineInstr;
26 : class MachineModuleInfo;
27 : class MCSymbol;
28 : template <typename T> class SmallVectorImpl;
29 :
30 : /// Emits exception handling directives.
31 24166 : class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler {
32 : protected:
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 :
48 : // The index of the begin and end labels in the landing pad's label lists.
49 : unsigned RangeIndex;
50 : };
51 :
52 : using RangeMapType = DenseMap<MCSymbol *, PadRange>;
53 :
54 : /// Structure describing an entry in the actions table.
55 : struct ActionEntry {
56 : int ValueForTypeID; // The value to write - may not be equal to the type id.
57 : int NextAction;
58 : unsigned Previous;
59 : };
60 :
61 : /// Structure describing an entry in the call-site table.
62 : struct CallSiteEntry {
63 : // The 'try-range' is BeginLabel .. EndLabel.
64 : MCSymbol *BeginLabel; // Null indicates the start of the function.
65 : MCSymbol *EndLabel; // Null indicates the end of the function.
66 :
67 : // LPad contains the landing pad start labels.
68 : const LandingPadInfo *LPad; // Null indicates that there is no landing pad.
69 :
70 : unsigned Action;
71 : };
72 :
73 : /// Compute the actions table and gather the first action index for each
74 : /// landing pad site.
75 : void computeActionsTable(const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
76 : SmallVectorImpl<ActionEntry> &Actions,
77 : SmallVectorImpl<unsigned> &FirstActions);
78 :
79 : void computePadMap(const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
80 : RangeMapType &PadMap);
81 :
82 : /// Compute the call-site table. The entry for an invoke has a try-range
83 : /// containing the call, a non-zero landing pad and an appropriate action.
84 : /// The entry for an ordinary call has a try-range containing the call and
85 : /// zero for the landing pad and the action. Calls marked 'nounwind' have
86 : /// no entry and must not be contained in the try-range of any entry - they
87 : /// form gaps in the table. Entries must be ordered by try-range address.
88 : void computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
89 : const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
90 : const SmallVectorImpl<unsigned> &FirstActions);
91 :
92 : /// Emit landing pads and actions.
93 : ///
94 : /// The general organization of the table is complex, but the basic concepts
95 : /// are easy. First there is a header which describes the location and
96 : /// organization of the three components that follow.
97 : /// 1. The landing pad site information describes the range of code covered
98 : /// by the try. In our case it's an accumulation of the ranges covered
99 : /// by the invokes in the try. There is also a reference to the landing
100 : /// pad that handles the exception once processed. Finally an index into
101 : /// the actions table.
102 : /// 2. The action table, in our case, is composed of pairs of type ids
103 : /// and next action offset. Starting with the action index from the
104 : /// landing pad site, each type Id is checked for a match to the current
105 : /// exception. If it matches then the exception and type id are passed
106 : /// on to the landing pad. Otherwise the next action is looked up. This
107 : /// chain is terminated with a next action of zero. If no type id is
108 : /// found the frame is unwound and handling continues.
109 : /// 3. Type id table contains references to all the C++ typeinfo for all
110 : /// catches in the function. This tables is reversed indexed base 1.
111 : void emitExceptionTable();
112 :
113 : virtual void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel);
114 :
115 : // Helpers for identifying what kind of clause an EH typeid or selector
116 : // corresponds to. Negative selectors are for filter clauses, the zero
117 : // selector is for cleanups, and positive selectors are for catch clauses.
118 : static bool isFilterEHSelector(int Selector) { return Selector < 0; }
119 : static bool isCleanupEHSelector(int Selector) { return Selector == 0; }
120 : static bool isCatchEHSelector(int Selector) { return Selector > 0; }
121 :
122 : public:
123 : EHStreamer(AsmPrinter *A);
124 : ~EHStreamer() override;
125 :
126 : // Unused.
127 273224 : void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
128 2071968 : void beginInstruction(const MachineInstr *MI) override {}
129 2071969 : void endInstruction() override {}
130 :
131 : /// Return `true' if this is a call to a function marked `nounwind'. Return
132 : /// `false' otherwise.
133 : static bool callToNoUnwindFunction(const MachineInstr *MI);
134 : };
135 :
136 : } // end namespace llvm
137 :
138 : #endif // LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H
|