1 //===- llvm/CodeGen/DwarfCompileUnit.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_DWARFCOMPILEUNIT_H
14 #define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
16 #include "DwarfDebug.h"
17 #include "DwarfUnit.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/BinaryFormat/Dwarf.h"
24 #include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
25 #include "llvm/CodeGen/LexicalScopes.h"
26 #include "llvm/IR/DebugInfoMetadata.h"
27 #include "llvm/Support/Casting.h"
43 enum class UnitKind
{ Skeleton
, Full
};
45 class DwarfCompileUnit final
: public DwarfUnit
{
46 bool HasRangeLists
= false;
48 /// The start of the unit line section, this is also
49 /// reused in appyStmtList.
50 MCSymbol
*LineTableStartSym
;
52 /// Skeleton unit associated with this unit.
53 DwarfCompileUnit
*Skeleton
= nullptr;
55 /// The start of the unit macro info within macro section.
56 MCSymbol
*MacroLabelBegin
;
58 /// GlobalNames - A map of globally visible named entities for this unit.
59 StringMap
<const DIE
*> GlobalNames
;
61 /// GlobalTypes - A map of globally visible types for this unit.
62 StringMap
<const DIE
*> GlobalTypes
;
64 // List of ranges for a given compile unit.
65 SmallVector
<RangeSpan
, 2> CURanges
;
67 // The base address of this unit, if any. Used for relative references in
69 const MCSymbol
*BaseAddress
= nullptr;
71 using MDNodeSetVector
=
72 SetVector
<const MDNode
*, SmallVector
<const MDNode
*, 4>,
73 SmallPtrSet
<const MDNode
*, 4>>;
75 // List of entities (either static locals, types or imports) that
76 // belong to subprograms within this CU.
77 MDNodeSetVector DeferredLocalDecls
;
79 // List of concrete lexical block scopes belong to subprograms within this CU.
80 DenseMap
<const DILocalScope
*, DIE
*> LexicalBlockDIEs
;
82 // List of abstract local scopes (either DISubprogram or DILexicalBlock).
83 DenseMap
<const DILocalScope
*, DIE
*> AbstractLocalScopeDIEs
;
85 DenseMap
<const DINode
*, std::unique_ptr
<DbgEntity
>> AbstractEntities
;
87 /// DWO ID for correlating skeleton and split units.
90 const DIFile
*LastFile
= nullptr;
93 /// \anchor applyConcreteDbgVariableAttribute
94 /// \name applyConcreteDbgVariableAttribute
95 /// Overload set which applies attributes to \c VariableDie based on
96 /// the active variant of \c DV, which is passed as the first argument.
99 /// See \ref applyConcreteDbgVariableAttribute
100 void applyConcreteDbgVariableAttributes(const Loc::Single
&Single
,
101 const DbgVariable
&DV
,
103 /// See \ref applyConcreteDbgVariableAttribute
104 void applyConcreteDbgVariableAttributes(const Loc::Multi
&Multi
,
105 const DbgVariable
&DV
,
107 /// See \ref applyConcreteDbgVariableAttribute
108 void applyConcreteDbgVariableAttributes(const Loc::MMI
&MMI
,
109 const DbgVariable
&DV
,
111 /// See \ref applyConcreteDbgVariableAttribute
112 void applyConcreteDbgVariableAttributes(const Loc::EntryValue
&EntryValue
,
113 const DbgVariable
&DV
,
115 /// See \ref applyConcreteDbgVariableAttribute
116 void applyConcreteDbgVariableAttributes(const std::monostate
&,
117 const DbgVariable
&DV
,
122 bool isDwoUnit() const override
;
124 DenseMap
<const DILocalScope
*, DIE
*> &getAbstractScopeDIEs() {
125 if (isDwoUnit() && !DD
->shareAcrossDWOCUs())
126 return AbstractLocalScopeDIEs
;
127 return DU
->getAbstractScopeDIEs();
130 DenseMap
<const DINode
*, std::unique_ptr
<DbgEntity
>> &getAbstractEntities() {
131 if (isDwoUnit() && !DD
->shareAcrossDWOCUs())
132 return AbstractEntities
;
133 return DU
->getAbstractEntities();
136 void finishNonUnitTypeDIE(DIE
& D
, const DICompositeType
*CTy
) override
;
138 /// Add info for Wasm-global-based relocation.
139 void addWasmRelocBaseGlobal(DIELoc
*Loc
, StringRef GlobalName
,
140 uint64_t GlobalIndex
);
143 DwarfCompileUnit(unsigned UID
, const DICompileUnit
*Node
, AsmPrinter
*A
,
144 DwarfDebug
*DW
, DwarfFile
*DWU
,
145 UnitKind Kind
= UnitKind::Full
);
147 bool hasRangeLists() const { return HasRangeLists
; }
149 DwarfCompileUnit
*getSkeleton() const {
153 bool includeMinimalInlineScopes() const;
157 /// Apply the DW_AT_stmt_list from this compile unit to the specified DIE.
158 void applyStmtList(DIE
&D
);
160 /// Get line table start symbol for this unit.
161 MCSymbol
*getLineTableStartSym() const { return LineTableStartSym
; }
163 /// A pair of GlobalVariable and DIExpression.
165 const GlobalVariable
*Var
;
166 const DIExpression
*Expr
;
170 BaseTypeRef(unsigned BitSize
, dwarf::TypeKind Encoding
) :
171 BitSize(BitSize
), Encoding(Encoding
) {}
173 dwarf::TypeKind Encoding
;
177 std::vector
<BaseTypeRef
> ExprRefedBaseTypes
;
179 /// Get or create global variable DIE.
181 getOrCreateGlobalVariableDIE(const DIGlobalVariable
*GV
,
182 ArrayRef
<GlobalExpr
> GlobalExprs
);
184 DIE
*getOrCreateCommonBlock(const DICommonBlock
*CB
,
185 ArrayRef
<GlobalExpr
> GlobalExprs
);
187 void addLocationAttribute(DIE
*ToDIE
, const DIGlobalVariable
*GV
,
188 ArrayRef
<GlobalExpr
> GlobalExprs
);
190 /// addLabelAddress - Add a dwarf label attribute data and value using
191 /// either DW_FORM_addr or DW_FORM_GNU_addr_index.
192 void addLabelAddress(DIE
&Die
, dwarf::Attribute Attribute
,
193 const MCSymbol
*Label
);
195 /// addLocalLabelAddress - Add a dwarf label attribute data and value using
196 /// DW_FORM_addr only.
197 void addLocalLabelAddress(DIE
&Die
, dwarf::Attribute Attribute
,
198 const MCSymbol
*Label
);
200 DwarfCompileUnit
&getCU() override
{ return *this; }
202 unsigned getOrCreateSourceID(const DIFile
*File
) override
;
204 /// addRange - Add an address range to the list of ranges for this unit.
205 void addRange(RangeSpan Range
);
207 void attachLowHighPC(DIE
&D
, const MCSymbol
*Begin
, const MCSymbol
*End
);
209 /// Find DIE for the given subprogram and attach appropriate
210 /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global
211 /// variables in this scope then create and insert DIEs for these
213 DIE
&updateSubprogramScopeDIE(const DISubprogram
*SP
);
215 void constructScopeDIE(LexicalScope
*Scope
, DIE
&ParentScopeDIE
);
217 /// A helper function to construct a RangeSpanList for a given
219 void addScopeRangeList(DIE
&ScopeDIE
, SmallVector
<RangeSpan
, 2> Range
);
221 void attachRangesOrLowHighPC(DIE
&D
, SmallVector
<RangeSpan
, 2> Ranges
);
223 void attachRangesOrLowHighPC(DIE
&D
,
224 const SmallVectorImpl
<InsnRange
> &Ranges
);
226 /// This scope represents an inlined body of a function. Construct a
227 /// DIE to represent this concrete inlined copy of the function.
228 DIE
*constructInlinedScopeDIE(LexicalScope
*Scope
, DIE
&ParentScopeDIE
);
230 /// Construct new DW_TAG_lexical_block for this scope and
231 /// attach DW_AT_low_pc/DW_AT_high_pc labels.
232 DIE
*constructLexicalScopeDIE(LexicalScope
*Scope
);
234 /// Get a DIE for the given DILexicalBlock.
235 /// Note that this function assumes that the DIE has been already created
236 /// and it's an error, if it hasn't.
237 DIE
*getLexicalBlockDIE(const DILexicalBlock
*LB
);
239 /// Construct a DIE for the given DbgVariable.
240 DIE
*constructVariableDIE(DbgVariable
&DV
, bool Abstract
= false);
242 /// Convenience overload which writes the DIE pointer into an out variable
243 /// ObjectPointer in addition to returning it.
244 DIE
*constructVariableDIE(DbgVariable
&DV
, const LexicalScope
&Scope
,
245 DIE
*&ObjectPointer
);
247 /// Construct a DIE for the given DbgLabel.
248 DIE
*constructLabelDIE(DbgLabel
&DL
, const LexicalScope
&Scope
);
250 void createBaseTypeDIEs();
252 /// Construct a DIE for a given scope.
253 /// This instance of 'getOrCreateContextDIE()' can handle DILocalScope.
254 DIE
*getOrCreateContextDIE(const DIScope
*Ty
) override
;
256 /// Construct a DIE for this subprogram scope.
257 DIE
&constructSubprogramScopeDIE(const DISubprogram
*Sub
,
258 LexicalScope
*Scope
);
260 DIE
*createAndAddScopeChildren(LexicalScope
*Scope
, DIE
&ScopeDIE
);
262 void constructAbstractSubprogramScopeDIE(LexicalScope
*Scope
);
264 /// Whether to use the GNU analog for a DWARF5 tag, attribute, or location
265 /// atom. Only applicable when emitting otherwise DWARF4-compliant debug info.
266 bool useGNUAnalogForDwarf5Feature() const;
268 /// This takes a DWARF 5 tag and returns it or a GNU analog.
269 dwarf::Tag
getDwarf5OrGNUTag(dwarf::Tag Tag
) const;
271 /// This takes a DWARF 5 attribute and returns it or a GNU analog.
272 dwarf::Attribute
getDwarf5OrGNUAttr(dwarf::Attribute Attr
) const;
274 /// This takes a DWARF 5 location atom and either returns it or a GNU analog.
275 dwarf::LocationAtom
getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc
) const;
277 /// Construct a call site entry DIE describing a call within \p Scope to a
278 /// callee described by \p CalleeSP.
279 /// \p IsTail specifies whether the call is a tail call.
280 /// \p PCAddr points to the PC value after the call instruction.
281 /// \p CallAddr points to the PC value at the call instruction (or is null).
282 /// \p CallReg is a register location for an indirect call. For direct calls
283 /// the \p CallReg is set to 0.
284 DIE
&constructCallSiteEntryDIE(DIE
&ScopeDIE
, const DISubprogram
*CalleeSP
,
285 bool IsTail
, const MCSymbol
*PCAddr
,
286 const MCSymbol
*CallAddr
, unsigned CallReg
);
287 /// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params
288 /// were collected by the \ref collectCallSiteParameters.
289 /// Note: The order of parameters does not matter, since debuggers recognize
290 /// call site parameters by the DW_AT_location attribute.
291 void constructCallSiteParmEntryDIEs(DIE
&CallSiteDIE
,
292 SmallVector
<DbgCallSiteParam
, 4> &Params
);
294 /// Get or create a DIE for an imported entity.
295 DIE
*getOrCreateImportedEntityDIE(const DIImportedEntity
*IE
);
296 DIE
*constructImportedEntityDIE(const DIImportedEntity
*IE
);
298 void finishSubprogramDefinition(const DISubprogram
*SP
);
299 void finishEntityDefinition(const DbgEntity
*Entity
);
301 /// Find abstract variable associated with Var.
302 using InlinedEntity
= DbgValueHistoryMap::InlinedEntity
;
303 DbgEntity
*getExistingAbstractEntity(const DINode
*Node
);
304 void createAbstractEntity(const DINode
*Node
, LexicalScope
*Scope
);
306 /// Set the skeleton unit associated with this unit.
307 void setSkeleton(DwarfCompileUnit
&Skel
) { Skeleton
= &Skel
; }
309 unsigned getHeaderSize() const override
{
310 // DWARF v5 added the DWO ID to the header for split/skeleton units.
312 DD
->getDwarfVersion() >= 5 && DD
->useSplitDwarf() ? sizeof(uint64_t)
314 return DwarfUnit::getHeaderSize() + DWOIdSize
;
316 unsigned getLength() {
317 return Asm
->getUnitLengthFieldByteSize() + // Length field
318 getHeaderSize() + getUnitDie().getSize();
321 void emitHeader(bool UseOffsets
) override
;
323 /// Add the DW_AT_addr_base attribute to the unit DIE.
324 void addAddrTableBase();
326 MCSymbol
*getMacroLabelBegin() const {
327 return MacroLabelBegin
;
330 /// Add a new global name to the compile unit.
331 void addGlobalName(StringRef Name
, const DIE
&Die
,
332 const DIScope
*Context
) override
;
334 /// Add a new global name present in a type unit to this compile unit.
335 void addGlobalNameForTypeUnit(StringRef Name
, const DIScope
*Context
);
337 /// Add a new global type to the compile unit.
338 void addGlobalTypeImpl(const DIType
*Ty
, const DIE
&Die
,
339 const DIScope
*Context
) override
;
341 /// Add a new global type present in a type unit to this compile unit.
342 void addGlobalTypeUnitType(const DIType
*Ty
, const DIScope
*Context
);
344 const StringMap
<const DIE
*> &getGlobalNames() const { return GlobalNames
; }
345 const StringMap
<const DIE
*> &getGlobalTypes() const { return GlobalTypes
; }
347 /// Add DW_AT_location attribute for a DbgVariable based on provided
349 void addVariableAddress(const DbgVariable
&DV
, DIE
&Die
,
350 MachineLocation Location
);
351 /// Add an address attribute to a die based on the location provided.
352 void addAddress(DIE
&Die
, dwarf::Attribute Attribute
,
353 const MachineLocation
&Location
);
355 /// Start with the address based on the location provided, and generate the
356 /// DWARF information necessary to find the actual variable (navigating the
357 /// extra location information encoded in the type) based on the starting
358 /// location. Add the DWARF information to the die.
359 void addComplexAddress(const DIExpression
*DIExpr
, DIE
&Die
,
360 dwarf::Attribute Attribute
,
361 const MachineLocation
&Location
);
363 /// Add a Dwarf loclistptr attribute data and value.
364 void addLocationList(DIE
&Die
, dwarf::Attribute Attribute
, unsigned Index
);
366 /// Add attributes to \p Var which reflect the common attributes of \p
367 /// VariableDie, namely those which are not dependant on the active variant.
368 void applyCommonDbgVariableAttributes(const DbgVariable
&Var
,
371 /// Add a Dwarf expression attribute data and value.
372 void addExpr(DIELoc
&Die
, dwarf::Form Form
, const MCExpr
*Expr
);
374 void applySubprogramAttributesToDefinition(const DISubprogram
*SP
,
377 void applyLabelAttributes(const DbgLabel
&Label
, DIE
&LabelDie
);
379 /// getRanges - Get the list of ranges for this unit.
380 const SmallVectorImpl
<RangeSpan
> &getRanges() const { return CURanges
; }
381 SmallVector
<RangeSpan
, 2> takeRanges() { return std::move(CURanges
); }
383 void setBaseAddress(const MCSymbol
*Base
) { BaseAddress
= Base
; }
384 const MCSymbol
*getBaseAddress() const { return BaseAddress
; }
386 uint64_t getDWOId() const { return DWOId
; }
387 void setDWOId(uint64_t DwoId
) { DWOId
= DwoId
; }
389 bool hasDwarfPubSections() const;
391 void addBaseTypeRef(DIEValueList
&Die
, int64_t Idx
);
393 MDNodeSetVector
&getDeferredLocalDecls() { return DeferredLocalDecls
; }
396 } // end namespace llvm
398 #endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H