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