Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
Line
Count
Source (jump to first uncovered line)
1
//===-- llvm/CodeGen/DwarfUnit.h - Dwarf Compile Unit ---*- 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 dwarf compile unit.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFUNIT_H
15
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFUNIT_H
16
17
#include "DwarfDebug.h"
18
#include "llvm/ADT/DenseMap.h"
19
#include "llvm/ADT/Optional.h"
20
#include "llvm/ADT/StringMap.h"
21
#include "llvm/CodeGen/AsmPrinter.h"
22
#include "llvm/CodeGen/DIE.h"
23
#include "llvm/IR/DIBuilder.h"
24
#include "llvm/IR/DebugInfo.h"
25
#include "llvm/MC/MCDwarf.h"
26
#include "llvm/MC/MCExpr.h"
27
#include "llvm/MC/MCSection.h"
28
29
namespace llvm {
30
31
class MachineLocation;
32
class MachineOperand;
33
class ConstantInt;
34
class ConstantFP;
35
class DbgVariable;
36
class DwarfCompileUnit;
37
38
// Data structure to hold a range for range lists.
39
class RangeSpan {
40
public:
41
55.2k
  RangeSpan(MCSymbol *S, MCSymbol *E) : Start(S), End(E) {}
42
68.3k
  const MCSymbol *getStart() const { return Start; }
43
71.8k
  const MCSymbol *getEnd() const { return End; }
44
8.29k
  void setEnd(const MCSymbol *E) { End = E; }
45
46
private:
47
  const MCSymbol *Start, *End;
48
};
49
50
class RangeSpanList {
51
private:
52
  // Index for locating within the debug_range section this particular span.
53
  MCSymbol *RangeSym;
54
  // List of ranges.
55
  SmallVector<RangeSpan, 2> Ranges;
56
57
public:
58
  RangeSpanList(MCSymbol *Sym, SmallVector<RangeSpan, 2> Ranges)
59
8.68k
      : RangeSym(Sym), Ranges(std::move(Ranges)) {}
60
17.3k
  MCSymbol *getSym() const { return RangeSym; }
61
8.68k
  const SmallVectorImpl<RangeSpan> &getRanges() const { return Ranges; }
62
0
  void addRange(RangeSpan Range) { Ranges.push_back(Range); }
63
};
64
65
//===----------------------------------------------------------------------===//
66
/// This dwarf writer support class manages information associated with a
67
/// source file.
68
class DwarfUnit : public DIEUnit {
69
protected:
70
  /// MDNode for the compile unit.
71
  const DICompileUnit *CUNode;
72
73
  // All DIEValues are allocated through this allocator.
74
  BumpPtrAllocator DIEValueAllocator;
75
76
  /// Target of Dwarf emission.
77
  AsmPrinter *Asm;
78
79
  // Holders for some common dwarf information.
80
  DwarfDebug *DD;
81
  DwarfFile *DU;
82
83
  /// An anonymous type for index type.  Owned by DIEUnit.
84
  DIE *IndexTyDie;
85
86
  /// Tracks the mapping of unit level debug information variables to debug
87
  /// information entries.
88
  DenseMap<const MDNode *, DIE *> MDNodeToDieMap;
89
90
  /// A list of all the DIEBlocks in use.
91
  std::vector<DIEBlock *> DIEBlocks;
92
93
  /// A list of all the DIELocs in use.
94
  std::vector<DIELoc *> DIELocs;
95
96
  /// This map is used to keep track of subprogram DIEs that need
97
  /// DW_AT_containing_type attribute. This attribute points to a DIE that
98
  /// corresponds to the MDNode mapped with the subprogram DIE.
99
  DenseMap<DIE *, const DINode *> ContainingTypeMap;
100
101
  DwarfUnit(dwarf::Tag, const DICompileUnit *CU, AsmPrinter *A, DwarfDebug *DW,
102
            DwarfFile *DWU);
103
104
  bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie);
105
106
  bool shareAcrossDWOCUs() const;
107
  bool isShareableAcrossCUs(const DINode *D) const;
108
109
public:
110
  // Accessors.
111
0
  AsmPrinter* getAsmPrinter() const { return Asm; }
112
1.51k
  uint16_t getLanguage() const { return CUNode->getSourceLanguage(); }
113
137k
  const DICompileUnit *getCUNode() const { return CUNode; }
114
115
  /// Return true if this compile unit has something to write out.
116
0
  bool hasContent() const { return getUnitDie().hasChildren(); }
117
118
  /// Get string containing language specific context for a global name.
119
  ///
120
  /// Walks the metadata parent chain in a language specific manner (using the
121
  /// compile unit language) and returns it as a string. This is done at the
122
  /// metadata level because DIEs may not currently have been added to the
123
  /// parent context and walking the DIEs looking for names is more expensive
124
  /// than walking the metadata.
125
  std::string getParentContextString(const DIScope *Context) const;
126
127
  /// Add a new global name to the compile unit.
128
  virtual void addGlobalName(StringRef Name, const DIE &Die,
129
                             const DIScope *Context) = 0;
130
131
  /// Add a new global type to the compile unit.
132
  virtual void addGlobalType(const DIType *Ty, const DIE &Die,
133
                             const DIScope *Context) = 0;
134
135
  /// Returns the DIE map slot for the specified debug variable.
136
  ///
137
  /// We delegate the request to DwarfDebug when the MDNode can be part of the
138
  /// type system, since DIEs for the type system can be shared across CUs and
139
  /// the mappings are kept in DwarfDebug.
140
  DIE *getDIE(const DINode *D) const;
141
142
  /// Returns a fresh newly allocated DIELoc.
143
20
  DIELoc *getDIELoc() { return new (DIEValueAllocator) DIELoc; }
144
145
  /// Insert DIE into the map.
146
  ///
147
  /// We delegate the request to DwarfDebug when the MDNode can be part of the
148
  /// type system, since DIEs for the type system can be shared across CUs and
149
  /// the mappings are kept in DwarfDebug.
150
  void insertDIE(const DINode *Desc, DIE *D);
151
152
  /// Add a flag that is true to the DIE.
153
  void addFlag(DIE &Die, dwarf::Attribute Attribute);
154
155
  /// Add an unsigned integer attribute data and value.
156
  void addUInt(DIEValueList &Die, dwarf::Attribute Attribute,
157
               Optional<dwarf::Form> Form, uint64_t Integer);
158
159
  void addUInt(DIEValueList &Block, dwarf::Form Form, uint64_t Integer);
160
161
  /// Add an signed integer attribute data and value.
162
  void addSInt(DIEValueList &Die, dwarf::Attribute Attribute,
163
               Optional<dwarf::Form> Form, int64_t Integer);
164
165
  void addSInt(DIELoc &Die, Optional<dwarf::Form> Form, int64_t Integer);
166
167
  /// Add a string attribute data and value.
168
  ///
169
  /// We always emit a reference to the string pool instead of immediate
170
  /// strings so that DIEs have more predictable sizes. In the case of split
171
  /// dwarf we emit an index into another table which gets us the static offset
172
  /// into the string table.
173
  void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str);
174
175
  /// Add a Dwarf label attribute data and value.
176
  DIEValueList::value_iterator addLabel(DIEValueList &Die,
177
                                        dwarf::Attribute Attribute,
178
                                        dwarf::Form Form,
179
                                        const MCSymbol *Label);
180
181
  void addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label);
182
183
  /// Add an offset into a section attribute data and value.
184
  void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer);
185
186
  /// Add a dwarf op address data and value using the form given and an
187
  /// op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
188
  void addOpAddress(DIELoc &Die, const MCSymbol *Label);
189
190
  /// Add a label delta attribute data and value.
191
  void addLabelDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
192
                     const MCSymbol *Lo);
193
194
  /// Add a DIE attribute data and value.
195
  void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry);
196
197
  /// Add a DIE attribute data and value.
198
  void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry Entry);
199
200
  /// Add a type's DW_AT_signature and set the  declaration flag.
201
  void addDIETypeSignature(DIE &Die, uint64_t Signature);
202
203
  /// Add block data.
204
  void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Block);
205
206
  /// Add block data.
207
  void addBlock(DIE &Die, dwarf::Attribute Attribute, DIEBlock *Block);
208
209
  /// Add location information to specified debug information entry.
210
  void addSourceLine(DIE &Die, unsigned Line, StringRef File,
211
                     StringRef Directory);
212
  void addSourceLine(DIE &Die, const DILocalVariable *V);
213
  void addSourceLine(DIE &Die, const DIGlobalVariable *G);
214
  void addSourceLine(DIE &Die, const DISubprogram *SP);
215
  void addSourceLine(DIE &Die, const DIType *Ty);
216
  void addSourceLine(DIE &Die, const DIObjCProperty *Ty);
217
218
  /// Add constant value entry in variable DIE.
219
  void addConstantValue(DIE &Die, const MachineOperand &MO, const DIType *Ty);
220
  void addConstantValue(DIE &Die, const ConstantInt *CI, const DIType *Ty);
221
  void addConstantValue(DIE &Die, const APInt &Val, const DIType *Ty);
222
  void addConstantValue(DIE &Die, const APInt &Val, bool Unsigned);
223
  void addConstantValue(DIE &Die, bool Unsigned, uint64_t Val);
224
225
  /// Add constant value entry in variable DIE.
226
  void addConstantFPValue(DIE &Die, const MachineOperand &MO);
227
  void addConstantFPValue(DIE &Die, const ConstantFP *CFP);
228
229
  /// Add a linkage name, if it isn't empty.
230
  void addLinkageName(DIE &Die, StringRef LinkageName);
231
232
  /// Add template parameters in buffer.
233
  void addTemplateParams(DIE &Buffer, DINodeArray TParams);
234
235
  /// Add thrown types.
236
  void addThrownTypes(DIE &Die, DINodeArray ThrownTypes);
237
238
  // FIXME: Should be reformulated in terms of addComplexAddress.
239
  /// Start with the address based on the location provided, and generate the
240
  /// DWARF information necessary to find the actual Block variable (navigating
241
  /// the Block struct) based on the starting location.  Add the DWARF
242
  /// information to the die.  Obsolete, please use addComplexAddress instead.
243
  void addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
244
                            dwarf::Attribute Attribute,
245
                            const MachineLocation &Location);
246
247
  /// Add a new type attribute to the specified entity.
248
  ///
249
  /// This takes and attribute parameter because DW_AT_friend attributes are
250
  /// also type references.
251
  void addType(DIE &Entity, const DIType *Ty,
252
               dwarf::Attribute Attribute = dwarf::DW_AT_type);
253
254
  DIE *getOrCreateNameSpace(const DINamespace *NS);
255
  DIE *getOrCreateModule(const DIModule *M);
256
  DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false);
257
258
  void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
259
                                 bool SkipSPAttributes = false);
260
261
  /// Find existing DIE or create new DIE for the given type.
262
  DIE *getOrCreateTypeDIE(const MDNode *N);
263
264
  /// Get context owner's DIE.
265
  DIE *getOrCreateContextDIE(const DIScope *Context);
266
267
  /// Construct DIEs for types that contain vtables.
268
  void constructContainingTypeDIEs();
269
270
  /// Construct function argument DIEs.
271
  void constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args);
272
273
  /// Create a DIE with the given Tag, add the DIE to its parent, and
274
  /// call insertDIE if MD is not null.
275
  DIE &createAndAddDIE(unsigned Tag, DIE &Parent, const DINode *N = nullptr);
276
277
  /// Compute the size of a header for this unit, not including the initial
278
  /// length field.
279
3.05k
  virtual unsigned getHeaderSize() const {
280
3.05k
    return sizeof(int16_t) + // DWARF version number
281
3.05k
           sizeof(int32_t) + // Offset Into Abbrev. Section
282
3.05k
           sizeof(int8_t) +  // Pointer Size (in bytes)
283
24
           (DD->getDwarfVersion() >= 5 ? sizeof(int8_t)
284
3.03k
                                       : 0); // DWARF v5 unit type
285
3.05k
  }
286
287
  /// Emit the header for this unit, not including the initial length field.
288
  virtual void emitHeader(bool UseOffsets) = 0;
289
290
  virtual DwarfCompileUnit &getCU() = 0;
291
292
  void constructTypeDIE(DIE &Buffer, const DICompositeType *CTy);
293
294
  /// addSectionDelta - Add a label delta attribute data and value.
295
  DIE::value_iterator addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
296
                                      const MCSymbol *Hi, const MCSymbol *Lo);
297
298
  /// Add a Dwarf section label attribute data and value.
299
  DIE::value_iterator addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
300
                                      const MCSymbol *Label,
301
                                      const MCSymbol *Sec);
302
303
protected:
304
  ~DwarfUnit();
305
306
  /// Create new static data member DIE.
307
  DIE *getOrCreateStaticMemberDIE(const DIDerivedType *DT);
308
309
  /// Look up the source ID with the given directory and source file names. If
310
  /// none currently exists, create a new ID and insert it in the line table.
311
  virtual unsigned getOrCreateSourceID(StringRef File, StringRef Directory) = 0;
312
313
  /// Look in the DwarfDebug map for the MDNode that corresponds to the
314
  /// reference.
315
28.6k
  template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
316
28.6k
    return Ref.resolve();
317
28.6k
  }
llvm::DIScope* llvm::DwarfUnit::resolve<llvm::DIScope>(llvm::TypedDINodeRef<llvm::DIScope>) const
Line
Count
Source
315
25.2k
  template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
316
25.2k
    return Ref.resolve();
317
25.2k
  }
llvm::DINode* llvm::DwarfUnit::resolve<llvm::DINode>(llvm::TypedDINodeRef<llvm::DINode>) const
Line
Count
Source
315
36
  template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
316
36
    return Ref.resolve();
317
36
  }
llvm::DIType* llvm::DwarfUnit::resolve<llvm::DIType>(llvm::TypedDINodeRef<llvm::DIType>) const
Line
Count
Source
315
3.30k
  template <typename T> T *resolve(TypedDINodeRef<T> Ref) const {
316
3.30k
    return Ref.resolve();
317
3.30k
  }
318
319
  /// If this is a named finished type then include it in the list of types for
320
  /// the accelerator tables.
321
  void updateAcceleratorTables(const DIScope *Context, const DIType *Ty,
322
                               const DIE &TyDIE);
323
324
  /// Emit the common part of the header for this unit.
325
  void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT);
326
327
private:
328
  void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy);
329
  void constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy);
330
  void constructTypeDIE(DIE &Buffer, const DISubroutineType *DTy);
331
  void constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, DIE *IndexTy);
332
  void constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy);
333
  void constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy);
334
  void constructMemberDIE(DIE &Buffer, const DIDerivedType *DT);
335
  void constructTemplateTypeParameterDIE(DIE &Buffer,
336
                                         const DITemplateTypeParameter *TP);
337
  void constructTemplateValueParameterDIE(DIE &Buffer,
338
                                          const DITemplateValueParameter *TVP);
339
340
  /// Return the default lower bound for an array.
341
  ///
342
  /// If the DWARF version doesn't handle the language, return -1.
343
  int64_t getDefaultLowerBound() const;
344
345
  /// Get an anonymous type for index type.
346
  DIE *getIndexTyDie();
347
348
  /// Set D as anonymous type for index which can be reused later.
349
0
  void setIndexTyDie(DIE *D) { IndexTyDie = D; }
350
351
  virtual bool isDwoUnit() const = 0;
352
  const MCSymbol *getCrossSectionRelativeBaseAddress() const override;
353
};
354
355
class DwarfTypeUnit final : public DwarfUnit {
356
  uint64_t TypeSignature;
357
  const DIE *Ty;
358
  DwarfCompileUnit &CU;
359
  MCDwarfDwoLineTable *SplitLineTable;
360
361
  unsigned getOrCreateSourceID(StringRef File, StringRef Directory) override;
362
  bool isDwoUnit() const override;
363
364
public:
365
  DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW,
366
                DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable = nullptr);
367
368
38
  void setTypeSignature(uint64_t Signature) { TypeSignature = Signature; }
369
38
  void setType(const DIE *Ty) { this->Ty = Ty; }
370
371
  /// Get context owner's DIE.
372
  DIE *createTypeDIE(const DICompositeType *Ty);
373
374
  /// Emit the header for this unit, not including the initial length field.
375
  void emitHeader(bool UseOffsets) override;
376
54
  unsigned getHeaderSize() const override {
377
54
    return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + // Type Signature
378
54
           sizeof(uint32_t);                               // Type DIE Offset
379
54
  }
380
  void addGlobalName(StringRef Name, const DIE &Die,
381
                     const DIScope *Context) override;
382
  void addGlobalType(const DIType *Ty, const DIE &Die,
383
                     const DIScope *Context) override;
384
123
  DwarfCompileUnit &getCU() override { return CU; }
385
};
386
} // end llvm namespace
387
#endif