[C++11] More 'nullptr' conversion or in some cases just using a boolean check instead...
[oota-llvm.git] / include / llvm / MC / MCDwarf.h
1 //===- MCDwarf.h - Machine Code Dwarf support -------------------*- 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 the declaration of the MCDwarfFile to support the dwarf
11 // .file directive and the .loc directive.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_MC_MCDWARF_H
16 #define LLVM_MC_MCDWARF_H
17
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/MapVector.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/Dwarf.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include <map>
26 #include <vector>
27 #include <string>
28 #include <utility>
29
30 namespace llvm {
31 class MCAsmBackend;
32 class MCContext;
33 class MCSection;
34 class MCStreamer;
35 class MCSymbol;
36 class SourceMgr;
37 class SMLoc;
38
39 /// MCDwarfFile - Instances of this class represent the name of the dwarf
40 /// .file directive and its associated dwarf file number in the MC file,
41 /// and MCDwarfFile's are created and unique'd by the MCContext class where
42 /// the file number for each is its index into the vector of DwarfFiles (note
43 /// index 0 is not used and not a valid dwarf file number).
44 struct MCDwarfFile {
45   // Name - the base name of the file without its directory path.
46   // The StringRef references memory allocated in the MCContext.
47   std::string Name;
48
49   // DirIndex - the index into the list of directory names for this file name.
50   unsigned DirIndex;
51 };
52
53 /// MCDwarfLoc - Instances of this class represent the information from a
54 /// dwarf .loc directive.
55 class MCDwarfLoc {
56   // FileNum - the file number.
57   unsigned FileNum;
58   // Line - the line number.
59   unsigned Line;
60   // Column - the column position.
61   unsigned Column;
62   // Flags (see #define's below)
63   unsigned Flags;
64   // Isa
65   unsigned Isa;
66   // Discriminator
67   unsigned Discriminator;
68
69 // Flag that indicates the initial value of the is_stmt_start flag.
70 #define DWARF2_LINE_DEFAULT_IS_STMT 1
71
72 #define DWARF2_FLAG_IS_STMT (1 << 0)
73 #define DWARF2_FLAG_BASIC_BLOCK (1 << 1)
74 #define DWARF2_FLAG_PROLOGUE_END (1 << 2)
75 #define DWARF2_FLAG_EPILOGUE_BEGIN (1 << 3)
76
77 private: // MCContext manages these
78   friend class MCContext;
79   friend class MCLineEntry;
80   MCDwarfLoc(unsigned fileNum, unsigned line, unsigned column, unsigned flags,
81              unsigned isa, unsigned discriminator)
82       : FileNum(fileNum), Line(line), Column(column), Flags(flags), Isa(isa),
83         Discriminator(discriminator) {}
84
85   // Allow the default copy constructor and assignment operator to be used
86   // for an MCDwarfLoc object.
87
88 public:
89   /// getFileNum - Get the FileNum of this MCDwarfLoc.
90   unsigned getFileNum() const { return FileNum; }
91
92   /// getLine - Get the Line of this MCDwarfLoc.
93   unsigned getLine() const { return Line; }
94
95   /// getColumn - Get the Column of this MCDwarfLoc.
96   unsigned getColumn() const { return Column; }
97
98   /// getFlags - Get the Flags of this MCDwarfLoc.
99   unsigned getFlags() const { return Flags; }
100
101   /// getIsa - Get the Isa of this MCDwarfLoc.
102   unsigned getIsa() const { return Isa; }
103
104   /// getDiscriminator - Get the Discriminator of this MCDwarfLoc.
105   unsigned getDiscriminator() const { return Discriminator; }
106
107   /// setFileNum - Set the FileNum of this MCDwarfLoc.
108   void setFileNum(unsigned fileNum) { FileNum = fileNum; }
109
110   /// setLine - Set the Line of this MCDwarfLoc.
111   void setLine(unsigned line) { Line = line; }
112
113   /// setColumn - Set the Column of this MCDwarfLoc.
114   void setColumn(unsigned column) { Column = column; }
115
116   /// setFlags - Set the Flags of this MCDwarfLoc.
117   void setFlags(unsigned flags) { Flags = flags; }
118
119   /// setIsa - Set the Isa of this MCDwarfLoc.
120   void setIsa(unsigned isa) { Isa = isa; }
121
122   /// setDiscriminator - Set the Discriminator of this MCDwarfLoc.
123   void setDiscriminator(unsigned discriminator) {
124     Discriminator = discriminator;
125   }
126 };
127
128 /// MCLineEntry - Instances of this class represent the line information for
129 /// the dwarf line table entries.  Which is created after a machine
130 /// instruction is assembled and uses an address from a temporary label
131 /// created at the current address in the current section and the info from
132 /// the last .loc directive seen as stored in the context.
133 class MCLineEntry : public MCDwarfLoc {
134   MCSymbol *Label;
135
136 private:
137   // Allow the default copy constructor and assignment operator to be used
138   // for an MCLineEntry object.
139
140 public:
141   // Constructor to create an MCLineEntry given a symbol and the dwarf loc.
142   MCLineEntry(MCSymbol *label, const MCDwarfLoc loc)
143       : MCDwarfLoc(loc), Label(label) {}
144
145   MCSymbol *getLabel() const { return Label; }
146
147   // This is called when an instruction is assembled into the specified
148   // section and if there is information from the last .loc directive that
149   // has yet to have a line entry made for it is made.
150   static void Make(MCStreamer *MCOS, const MCSection *Section);
151 };
152
153 /// MCLineSection - Instances of this class represent the line information
154 /// for a compile unit where machine instructions have been assembled after seeing
155 /// .loc directives.  This is the information used to build the dwarf line
156 /// table for a section.
157 class MCLineSection {
158 public:
159   // addLineEntry - adds an entry to this MCLineSection's line entries
160   void addLineEntry(const MCLineEntry &LineEntry, const MCSection *Sec) {
161     MCLineDivisions[Sec].push_back(LineEntry);
162   }
163
164   typedef std::vector<MCLineEntry> MCLineEntryCollection;
165   typedef MCLineEntryCollection::iterator iterator;
166   typedef MCLineEntryCollection::const_iterator const_iterator;
167   typedef MapVector<const MCSection *, MCLineEntryCollection> MCLineDivisionMap;
168
169 private:
170   // A collection of MCLineEntry for each section.
171   MCLineDivisionMap MCLineDivisions;
172
173 public:
174   // Returns the collection of MCLineEntry for a given Compile Unit ID.
175   const MCLineDivisionMap &getMCLineEntries() const {
176     return MCLineDivisions;
177   }
178 };
179
180 struct MCDwarfLineTableHeader {
181   MCSymbol *Label;
182   SmallVector<std::string, 3> MCDwarfDirs;
183   SmallVector<MCDwarfFile, 3> MCDwarfFiles;
184   StringMap<unsigned> SourceIdMap;
185   StringRef CompilationDir;
186
187   MCDwarfLineTableHeader() : Label(nullptr) {}
188   unsigned getFile(StringRef &Directory, StringRef &FileName,
189                    unsigned FileNumber = 0);
190   std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const;
191   std::pair<MCSymbol *, MCSymbol *>
192   Emit(MCStreamer *MCOS, ArrayRef<char> SpecialOpcodeLengths) const;
193 };
194
195 class MCDwarfDwoLineTable {
196   MCDwarfLineTableHeader Header;
197 public:
198   void setCompilationDir(StringRef CompilationDir) {
199     Header.CompilationDir = CompilationDir;
200   }
201   unsigned getFile(StringRef Directory, StringRef FileName) {
202     return Header.getFile(Directory, FileName);
203   }
204   void Emit(MCStreamer &MCOS) const;
205 };
206
207 class MCDwarfLineTable {
208   MCDwarfLineTableHeader Header;
209   MCLineSection MCLineSections;
210
211 public:
212   // This emits the Dwarf file and the line tables for all Compile Units.
213   static void Emit(MCStreamer *MCOS);
214
215   // This emits the Dwarf file and the line tables for a given Compile Unit.
216   void EmitCU(MCStreamer *MCOS) const;
217
218   unsigned getFile(StringRef &Directory, StringRef &FileName,
219                    unsigned FileNumber = 0);
220
221   MCSymbol *getLabel() const {
222     return Header.Label;
223   }
224
225   void setLabel(MCSymbol *Label) {
226     Header.Label = Label;
227   }
228
229   void setCompilationDir(StringRef CompilationDir) {
230     Header.CompilationDir = CompilationDir;
231   }
232
233   const SmallVectorImpl<std::string> &getMCDwarfDirs() const {
234     return Header.MCDwarfDirs;
235   }
236
237   SmallVectorImpl<std::string> &getMCDwarfDirs() {
238     return Header.MCDwarfDirs;
239   }
240
241   const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() const {
242     return Header.MCDwarfFiles;
243   }
244
245   SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles() {
246     return Header.MCDwarfFiles;
247   }
248
249   const MCLineSection &getMCLineSections() const {
250     return MCLineSections;
251   }
252   MCLineSection &getMCLineSections() {
253     return MCLineSections;
254   }
255 };
256
257 class MCDwarfLineAddr {
258 public:
259   /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
260   static void Encode(MCContext &Context, int64_t LineDelta, uint64_t AddrDelta,
261                      raw_ostream &OS);
262
263   /// Utility function to emit the encoding to a streamer.
264   static void Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta);
265 };
266
267 class MCGenDwarfInfo {
268 public:
269   //
270   // When generating dwarf for assembly source files this emits the Dwarf
271   // sections.
272   //
273   static void Emit(MCStreamer *MCOS);
274 };
275
276 // When generating dwarf for assembly source files this is the info that is
277 // needed to be gathered for each symbol that will have a dwarf label.
278 class MCGenDwarfLabelEntry {
279 private:
280   // Name of the symbol without a leading underbar, if any.
281   StringRef Name;
282   // The dwarf file number this symbol is in.
283   unsigned FileNumber;
284   // The line number this symbol is at.
285   unsigned LineNumber;
286   // The low_pc for the dwarf label is taken from this symbol.
287   MCSymbol *Label;
288
289 public:
290   MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber,
291                        MCSymbol *label)
292       : Name(name), FileNumber(fileNumber), LineNumber(lineNumber),
293         Label(label) {}
294
295   StringRef getName() const { return Name; }
296   unsigned getFileNumber() const { return FileNumber; }
297   unsigned getLineNumber() const { return LineNumber; }
298   MCSymbol *getLabel() const { return Label; }
299
300   // This is called when label is created when we are generating dwarf for
301   // assembly source files.
302   static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr,
303                    SMLoc &Loc);
304 };
305
306 class MCCFIInstruction {
307 public:
308   enum OpType {
309     OpSameValue,
310     OpRememberState,
311     OpRestoreState,
312     OpOffset,
313     OpDefCfaRegister,
314     OpDefCfaOffset,
315     OpDefCfa,
316     OpRelOffset,
317     OpAdjustCfaOffset,
318     OpEscape,
319     OpRestore,
320     OpUndefined,
321     OpRegister,
322     OpWindowSave
323   };
324
325 private:
326   OpType Operation;
327   MCSymbol *Label;
328   unsigned Register;
329   union {
330     int Offset;
331     unsigned Register2;
332   };
333   std::vector<char> Values;
334
335   MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
336       : Operation(Op), Label(L), Register(R), Offset(O),
337         Values(V.begin(), V.end()) {
338     assert(Op != OpRegister);
339   }
340
341   MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2)
342       : Operation(Op), Label(L), Register(R1), Register2(R2) {
343     assert(Op == OpRegister);
344   }
345
346 public:
347   /// \brief .cfi_def_cfa defines a rule for computing CFA as: take address from
348   /// Register and add Offset to it.
349   static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
350                                        int Offset) {
351     return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
352   }
353
354   /// \brief .cfi_def_cfa_register modifies a rule for computing CFA. From now
355   /// on Register will be used instead of the old one. Offset remains the same.
356   static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register) {
357     return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
358   }
359
360   /// \brief .cfi_def_cfa_offset modifies a rule for computing CFA. Register
361   /// remains the same, but offset is new. Note that it is the absolute offset
362   /// that will be added to a defined register to the compute CFA address.
363   static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
364     return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
365   }
366
367   /// \brief .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
368   /// Offset is a relative value that is added/subtracted from the previous
369   /// offset.
370   static MCCFIInstruction createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
371     return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
372   }
373
374   /// \brief .cfi_offset Previous value of Register is saved at offset Offset
375   /// from CFA.
376   static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register,
377                                        int Offset) {
378     return MCCFIInstruction(OpOffset, L, Register, Offset, "");
379   }
380
381   /// \brief .cfi_rel_offset Previous value of Register is saved at offset
382   /// Offset from the current CFA register. This is transformed to .cfi_offset
383   /// using the known displacement of the CFA register from the CFA.
384   static MCCFIInstruction createRelOffset(MCSymbol *L, unsigned Register,
385                                           int Offset) {
386     return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
387   }
388
389   /// \brief .cfi_register Previous value of Register1 is saved in
390   /// register Register2.
391   static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1,
392                                          unsigned Register2) {
393     return MCCFIInstruction(OpRegister, L, Register1, Register2);
394   }
395
396   /// \brief .cfi_window_save SPARC register window is saved.
397   static MCCFIInstruction createWindowSave(MCSymbol *L) {
398     return MCCFIInstruction(OpWindowSave, L, 0, 0, "");
399   }
400
401   /// \brief .cfi_restore says that the rule for Register is now the same as it
402   /// was at the beginning of the function, after all initial instructions added
403   /// by .cfi_startproc were executed.
404   static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
405     return MCCFIInstruction(OpRestore, L, Register, 0, "");
406   }
407
408   /// \brief .cfi_undefined From now on the previous value of Register can't be
409   /// restored anymore.
410   static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
411     return MCCFIInstruction(OpUndefined, L, Register, 0, "");
412   }
413
414   /// \brief .cfi_same_value Current value of Register is the same as in the
415   /// previous frame. I.e., no restoration is needed.
416   static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
417     return MCCFIInstruction(OpSameValue, L, Register, 0, "");
418   }
419
420   /// \brief .cfi_remember_state Save all current rules for all registers.
421   static MCCFIInstruction createRememberState(MCSymbol *L) {
422     return MCCFIInstruction(OpRememberState, L, 0, 0, "");
423   }
424
425   /// \brief .cfi_restore_state Restore the previously saved state.
426   static MCCFIInstruction createRestoreState(MCSymbol *L) {
427     return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
428   }
429
430   /// \brief .cfi_escape Allows the user to add arbitrary bytes to the unwind
431   /// info.
432   static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
433     return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
434   }
435
436   OpType getOperation() const { return Operation; }
437   MCSymbol *getLabel() const { return Label; }
438
439   unsigned getRegister() const {
440     assert(Operation == OpDefCfa || Operation == OpOffset ||
441            Operation == OpRestore || Operation == OpUndefined ||
442            Operation == OpSameValue || Operation == OpDefCfaRegister ||
443            Operation == OpRelOffset || Operation == OpRegister);
444     return Register;
445   }
446
447   unsigned getRegister2() const {
448     assert(Operation == OpRegister);
449     return Register2;
450   }
451
452   int getOffset() const {
453     assert(Operation == OpDefCfa || Operation == OpOffset ||
454            Operation == OpRelOffset || Operation == OpDefCfaOffset ||
455            Operation == OpAdjustCfaOffset);
456     return Offset;
457   }
458
459   const StringRef getValues() const {
460     assert(Operation == OpEscape);
461     return StringRef(&Values[0], Values.size());
462   }
463 };
464
465 struct MCDwarfFrameInfo {
466   MCDwarfFrameInfo()
467     : Begin(nullptr), End(nullptr), Personality(nullptr), Lsda(nullptr),
468       Function(nullptr), Instructions(), PersonalityEncoding(), LsdaEncoding(0),
469       CompactUnwindEncoding(0), IsSignalFrame(false), IsSimple(false) {}
470   MCSymbol *Begin;
471   MCSymbol *End;
472   const MCSymbol *Personality;
473   const MCSymbol *Lsda;
474   const MCSymbol *Function;
475   std::vector<MCCFIInstruction> Instructions;
476   unsigned PersonalityEncoding;
477   unsigned LsdaEncoding;
478   uint32_t CompactUnwindEncoding;
479   bool IsSignalFrame;
480   bool IsSimple;
481 };
482
483 class MCDwarfFrameEmitter {
484 public:
485   //
486   // This emits the frame info section.
487   //
488   static void Emit(MCStreamer &streamer, MCAsmBackend *MAB,
489                    bool usingCFI, bool isEH);
490   static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
491   static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
492                                raw_ostream &OS);
493 };
494 } // end namespace llvm
495
496 #endif