/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 |