1 //===-- llvm/CodeGen/DwarfUnit.h - Dwarf Compile Unit ---*- C++ -*--===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains support for writing dwarf compile unit.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFUNIT_H
14 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFUNIT_H
16 #include "DwarfDebug.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/CodeGen/AsmPrinter.h"
20 #include "llvm/CodeGen/DIE.h"
21 #include "llvm/Target/TargetMachine.h"
28 class DwarfCompileUnit
;
29 class MCDwarfDwoLineTable
;
32 //===----------------------------------------------------------------------===//
33 /// This dwarf writer support class manages information associated with a
35 class DwarfUnit
: public DIEUnit
{
37 /// MDNode for the compile unit.
38 const DICompileUnit
*CUNode
;
40 // All DIEValues are allocated through this allocator.
41 BumpPtrAllocator DIEValueAllocator
;
43 /// Target of Dwarf emission.
46 /// Emitted at the end of the CU and used to compute the CU Length field.
47 MCSymbol
*EndLabel
= nullptr;
49 // Holders for some common dwarf information.
53 /// An anonymous type for index type. Owned by DIEUnit.
54 DIE
*IndexTyDie
= nullptr;
56 /// Tracks the mapping of unit level debug information variables to debug
57 /// information entries.
58 DenseMap
<const MDNode
*, DIE
*> MDNodeToDieMap
;
60 /// A list of all the DIEBlocks in use.
61 std::vector
<DIEBlock
*> DIEBlocks
;
63 /// A list of all the DIELocs in use.
64 std::vector
<DIELoc
*> DIELocs
;
66 /// This map is used to keep track of subprogram DIEs that need
67 /// DW_AT_containing_type attribute. This attribute points to a DIE that
68 /// corresponds to the MDNode mapped with the subprogram DIE.
69 DenseMap
<DIE
*, const DINode
*> ContainingTypeMap
;
71 DwarfUnit(dwarf::Tag
, const DICompileUnit
*Node
, AsmPrinter
*A
, DwarfDebug
*DW
,
74 bool applySubprogramDefinitionAttributes(const DISubprogram
*SP
, DIE
&SPDie
, bool Minimal
);
76 bool isShareableAcrossCUs(const DINode
*D
) const;
79 void addAttribute(DIEValueList
&Die
, dwarf::Attribute Attribute
,
80 dwarf::Form Form
, T
&&Value
) {
81 // For strict DWARF mode, only generate attributes available to current
83 // Attribute 0 is used when emitting form-encoded values in blocks, which
84 // don't have attributes (only forms) so we cannot detect their DWARF
85 // version compatibility here and assume they are compatible.
86 if (Attribute
!= 0 && Asm
->TM
.Options
.DebugStrictDwarf
&&
87 DD
->getDwarfVersion() < dwarf::AttributeVersion(Attribute
))
90 Die
.addValue(DIEValueAllocator
,
91 DIEValue(Attribute
, Form
, std::forward
<T
>(Value
)));
96 AsmPrinter
* getAsmPrinter() const { return Asm
; }
97 MCSymbol
*getEndLabel() const { return EndLabel
; }
98 uint16_t getLanguage() const { return CUNode
->getSourceLanguage(); }
99 const DICompileUnit
*getCUNode() const { return CUNode
; }
100 DwarfDebug
&getDwarfDebug() const { return *DD
; }
102 /// Return true if this compile unit has something to write out.
103 bool hasContent() const { return getUnitDie().hasChildren(); }
105 /// Get string containing language specific context for a global name.
107 /// Walks the metadata parent chain in a language specific manner (using the
108 /// compile unit language) and returns it as a string. This is done at the
109 /// metadata level because DIEs may not currently have been added to the
110 /// parent context and walking the DIEs looking for names is more expensive
111 /// than walking the metadata.
112 std::string
getParentContextString(const DIScope
*Context
) const;
114 /// Add a new global name to the compile unit.
115 virtual void addGlobalName(StringRef Name
, const DIE
&Die
,
116 const DIScope
*Context
) = 0;
118 /// Add a new global type to the compile unit.
119 virtual void addGlobalType(const DIType
*Ty
, const DIE
&Die
,
120 const DIScope
*Context
) = 0;
122 /// Returns the DIE map slot for the specified debug variable.
124 /// We delegate the request to DwarfDebug when the MDNode can be part of the
125 /// type system, since DIEs for the type system can be shared across CUs and
126 /// the mappings are kept in DwarfDebug.
127 DIE
*getDIE(const DINode
*D
) const;
129 /// Returns a fresh newly allocated DIELoc.
130 DIELoc
*getDIELoc() { return new (DIEValueAllocator
) DIELoc
; }
132 /// Insert DIE into the map.
134 /// We delegate the request to DwarfDebug when the MDNode can be part of the
135 /// type system, since DIEs for the type system can be shared across CUs and
136 /// the mappings are kept in DwarfDebug.
137 void insertDIE(const DINode
*Desc
, DIE
*D
);
139 void insertDIE(DIE
*D
);
141 /// Add a flag that is true to the DIE.
142 void addFlag(DIE
&Die
, dwarf::Attribute Attribute
);
144 /// Add an unsigned integer attribute data and value.
145 void addUInt(DIEValueList
&Die
, dwarf::Attribute Attribute
,
146 Optional
<dwarf::Form
> Form
, uint64_t Integer
);
148 void addUInt(DIEValueList
&Block
, dwarf::Form Form
, uint64_t Integer
);
150 /// Add an signed integer attribute data and value.
151 void addSInt(DIEValueList
&Die
, dwarf::Attribute Attribute
,
152 Optional
<dwarf::Form
> Form
, int64_t Integer
);
154 void addSInt(DIELoc
&Die
, Optional
<dwarf::Form
> Form
, int64_t Integer
);
156 /// Add a string attribute data and value.
158 /// We always emit a reference to the string pool instead of immediate
159 /// strings so that DIEs have more predictable sizes. In the case of split
160 /// dwarf we emit an index into another table which gets us the static offset
161 /// into the string table.
162 void addString(DIE
&Die
, dwarf::Attribute Attribute
, StringRef Str
);
164 /// Add a Dwarf label attribute data and value.
165 void addLabel(DIEValueList
&Die
, dwarf::Attribute Attribute
, dwarf::Form Form
,
166 const MCSymbol
*Label
);
168 void addLabel(DIELoc
&Die
, dwarf::Form Form
, const MCSymbol
*Label
);
170 /// Add an offset into a section attribute data and value.
171 void addSectionOffset(DIE
&Die
, dwarf::Attribute Attribute
, uint64_t Integer
);
173 /// Add a dwarf op address data and value using the form given and an
174 /// op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
175 void addOpAddress(DIELoc
&Die
, const MCSymbol
*Sym
);
176 void addPoolOpAddress(DIEValueList
&Die
, const MCSymbol
*Label
);
178 /// Add a label delta attribute data and value.
179 void addLabelDelta(DIEValueList
&Die
, dwarf::Attribute Attribute
,
180 const MCSymbol
*Hi
, const MCSymbol
*Lo
);
182 /// Add a DIE attribute data and value.
183 void addDIEEntry(DIE
&Die
, dwarf::Attribute Attribute
, DIE
&Entry
);
185 /// Add a DIE attribute data and value.
186 void addDIEEntry(DIE
&Die
, dwarf::Attribute Attribute
, DIEEntry Entry
);
188 /// Add a type's DW_AT_signature and set the declaration flag.
189 void addDIETypeSignature(DIE
&Die
, uint64_t Signature
);
192 void addBlock(DIE
&Die
, dwarf::Attribute Attribute
, DIELoc
*Loc
);
195 void addBlock(DIE
&Die
, dwarf::Attribute Attribute
, DIEBlock
*Block
);
196 void addBlock(DIE
&Die
, dwarf::Attribute Attribute
, dwarf::Form Form
,
199 /// Add location information to specified debug information entry.
200 void addSourceLine(DIE
&Die
, unsigned Line
, const DIFile
*File
);
201 void addSourceLine(DIE
&Die
, const DILocalVariable
*V
);
202 void addSourceLine(DIE
&Die
, const DIGlobalVariable
*G
);
203 void addSourceLine(DIE
&Die
, const DISubprogram
*SP
);
204 void addSourceLine(DIE
&Die
, const DILabel
*L
);
205 void addSourceLine(DIE
&Die
, const DIType
*Ty
);
206 void addSourceLine(DIE
&Die
, const DIObjCProperty
*Ty
);
208 /// Add constant value entry in variable DIE.
209 void addConstantValue(DIE
&Die
, const ConstantInt
*CI
, const DIType
*Ty
);
210 void addConstantValue(DIE
&Die
, const APInt
&Val
, const DIType
*Ty
);
211 void addConstantValue(DIE
&Die
, const APInt
&Val
, bool Unsigned
);
212 void addConstantValue(DIE
&Die
, uint64_t Val
, const DIType
*Ty
);
213 void addConstantValue(DIE
&Die
, bool Unsigned
, uint64_t Val
);
215 /// Add constant value entry in variable DIE.
216 void addConstantFPValue(DIE
&Die
, const ConstantFP
*CFP
);
218 /// Add a linkage name, if it isn't empty.
219 void addLinkageName(DIE
&Die
, StringRef LinkageName
);
221 /// Add template parameters in buffer.
222 void addTemplateParams(DIE
&Buffer
, DINodeArray TParams
);
224 /// Add thrown types.
225 void addThrownTypes(DIE
&Die
, DINodeArray ThrownTypes
);
227 /// Add the accessibility attribute.
228 void addAccess(DIE
&Die
, DINode::DIFlags Flags
);
230 /// Add a new type attribute to the specified entity.
232 /// This takes and attribute parameter because DW_AT_friend attributes are
233 /// also type references.
234 void addType(DIE
&Entity
, const DIType
*Ty
,
235 dwarf::Attribute Attribute
= dwarf::DW_AT_type
);
237 DIE
*getOrCreateNameSpace(const DINamespace
*NS
);
238 DIE
*getOrCreateModule(const DIModule
*M
);
239 DIE
*getOrCreateSubprogramDIE(const DISubprogram
*SP
, bool Minimal
= false);
241 void applySubprogramAttributes(const DISubprogram
*SP
, DIE
&SPDie
,
242 bool SkipSPAttributes
= false);
244 /// Creates type DIE with specific context.
245 DIE
*createTypeDIE(const DIScope
*Context
, DIE
&ContextDIE
, const DIType
*Ty
);
247 /// Find existing DIE or create new DIE for the given type.
248 DIE
*getOrCreateTypeDIE(const MDNode
*TyNode
);
250 /// Get context owner's DIE.
251 DIE
*getOrCreateContextDIE(const DIScope
*Context
);
253 /// Construct DIEs for types that contain vtables.
254 void constructContainingTypeDIEs();
256 /// Construct function argument DIEs.
257 void constructSubprogramArguments(DIE
&Buffer
, DITypeRefArray Args
);
259 /// Create a DIE with the given Tag, add the DIE to its parent, and
260 /// call insertDIE if MD is not null.
261 DIE
&createAndAddDIE(dwarf::Tag Tag
, DIE
&Parent
, const DINode
*N
= nullptr);
263 bool useSegmentedStringOffsetsTable() const {
264 return DD
->useSegmentedStringOffsetsTable();
267 /// Compute the size of a header for this unit, not including the initial
269 virtual unsigned getHeaderSize() const {
270 return sizeof(int16_t) + // DWARF version number
271 Asm
->getDwarfOffsetByteSize() + // Offset Into Abbrev. Section
272 sizeof(int8_t) + // Pointer Size (in bytes)
273 (DD
->getDwarfVersion() >= 5 ? sizeof(int8_t)
274 : 0); // DWARF v5 unit type
277 /// Emit the header for this unit, not including the initial length field.
278 virtual void emitHeader(bool UseOffsets
) = 0;
280 /// Add the DW_AT_str_offsets_base attribute to the unit DIE.
281 void addStringOffsetsStart();
283 /// Add the DW_AT_rnglists_base attribute to the unit DIE.
284 void addRnglistsBase();
286 virtual DwarfCompileUnit
&getCU() = 0;
288 void constructTypeDIE(DIE
&Buffer
, const DICompositeType
*CTy
);
290 /// addSectionDelta - Add a label delta attribute data and value.
291 void addSectionDelta(DIE
&Die
, dwarf::Attribute Attribute
, const MCSymbol
*Hi
,
294 /// Add a Dwarf section label attribute data and value.
295 void addSectionLabel(DIE
&Die
, dwarf::Attribute Attribute
,
296 const MCSymbol
*Label
, const MCSymbol
*Sec
);
298 /// Add DW_TAG_LLVM_annotation.
299 void addAnnotation(DIE
&Buffer
, DINodeArray Annotations
);
301 /// Get context owner's DIE.
302 DIE
*createTypeDIE(const DICompositeType
*Ty
);
307 /// Create new static data member DIE.
308 DIE
*getOrCreateStaticMemberDIE(const DIDerivedType
*DT
);
310 /// Look up the source ID for the given file. If none currently exists,
311 /// create a new ID and insert it in the line table.
312 virtual unsigned getOrCreateSourceID(const DIFile
*File
) = 0;
314 /// Emit the common part of the header for this unit.
315 void emitCommonHeader(bool UseOffsets
, dwarf::UnitType UT
);
318 void constructTypeDIE(DIE
&Buffer
, const DIBasicType
*BTy
);
319 void constructTypeDIE(DIE
&Buffer
, const DIStringType
*BTy
);
320 void constructTypeDIE(DIE
&Buffer
, const DIDerivedType
*DTy
);
321 void constructTypeDIE(DIE
&Buffer
, const DISubroutineType
*CTy
);
322 void constructSubrangeDIE(DIE
&Buffer
, const DISubrange
*SR
, DIE
*IndexTy
);
323 void constructGenericSubrangeDIE(DIE
&Buffer
, const DIGenericSubrange
*SR
,
325 void constructArrayTypeDIE(DIE
&Buffer
, const DICompositeType
*CTy
);
326 void constructEnumTypeDIE(DIE
&Buffer
, const DICompositeType
*CTy
);
327 DIE
&constructMemberDIE(DIE
&Buffer
, const DIDerivedType
*DT
);
328 void constructTemplateTypeParameterDIE(DIE
&Buffer
,
329 const DITemplateTypeParameter
*TP
);
330 void constructTemplateValueParameterDIE(DIE
&Buffer
,
331 const DITemplateValueParameter
*TVP
);
333 /// Return the default lower bound for an array.
335 /// If the DWARF version doesn't handle the language, return -1.
336 int64_t getDefaultLowerBound() const;
338 /// Get an anonymous type for index type.
339 DIE
*getIndexTyDie();
341 /// Set D as anonymous type for index which can be reused later.
342 void setIndexTyDie(DIE
*D
) { IndexTyDie
= D
; }
344 virtual void finishNonUnitTypeDIE(DIE
& D
, const DICompositeType
*CTy
) = 0;
346 /// If this is a named finished type then include it in the list of types for
347 /// the accelerator tables.
348 void updateAcceleratorTables(const DIScope
*Context
, const DIType
*Ty
,
351 virtual bool isDwoUnit() const = 0;
352 const MCSymbol
*getCrossSectionRelativeBaseAddress() const override
;
355 class DwarfTypeUnit final
: public DwarfUnit
{
356 uint64_t TypeSignature
;
358 DwarfCompileUnit
&CU
;
359 MCDwarfDwoLineTable
*SplitLineTable
;
360 bool UsedLineTable
= false;
362 unsigned getOrCreateSourceID(const DIFile
*File
) override
;
363 void finishNonUnitTypeDIE(DIE
& D
, const DICompositeType
*CTy
) override
;
364 bool isDwoUnit() const override
;
367 DwarfTypeUnit(DwarfCompileUnit
&CU
, AsmPrinter
*A
, DwarfDebug
*DW
,
368 DwarfFile
*DWU
, MCDwarfDwoLineTable
*SplitLineTable
= nullptr);
370 void setTypeSignature(uint64_t Signature
) { TypeSignature
= Signature
; }
371 void setType(const DIE
*Ty
) { this->Ty
= Ty
; }
373 /// Emit the header for this unit, not including the initial length field.
374 void emitHeader(bool UseOffsets
) override
;
375 unsigned getHeaderSize() const override
{
376 return DwarfUnit::getHeaderSize() + sizeof(uint64_t) + // Type Signature
377 Asm
->getDwarfOffsetByteSize(); // Type DIE Offset
379 void addGlobalName(StringRef Name
, const DIE
&Die
,
380 const DIScope
*Context
) override
;
381 void addGlobalType(const DIType
*Ty
, const DIE
&Die
,
382 const DIScope
*Context
) override
;
383 DwarfCompileUnit
&getCU() override
{ return CU
; }
385 } // end llvm namespace