Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
35271 views
//===- llvm/CodeGen/DwarfCompileUnit.h - Dwarf Compile Unit -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains support for writing dwarf compile unit.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H13#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H1415#include "DwarfDebug.h"16#include "DwarfUnit.h"17#include "llvm/ADT/ArrayRef.h"18#include "llvm/ADT/DenseMap.h"19#include "llvm/ADT/SmallVector.h"20#include "llvm/ADT/StringMap.h"21#include "llvm/ADT/StringRef.h"22#include "llvm/BinaryFormat/Dwarf.h"23#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"24#include "llvm/CodeGen/LexicalScopes.h"25#include "llvm/IR/DebugInfoMetadata.h"26#include "llvm/Support/Casting.h"27#include <cstdint>28#include <memory>2930namespace llvm {3132class AsmPrinter;33class DIE;34class DIELoc;35class DIEValueList;36class DwarfFile;37class GlobalVariable;38class MCExpr;39class MCSymbol;40class MDNode;4142enum class UnitKind { Skeleton, Full };4344class DwarfCompileUnit final : public DwarfUnit {45bool HasRangeLists = false;4647/// The start of the unit line section, this is also48/// reused in appyStmtList.49MCSymbol *LineTableStartSym;5051/// Skeleton unit associated with this unit.52DwarfCompileUnit *Skeleton = nullptr;5354/// The start of the unit macro info within macro section.55MCSymbol *MacroLabelBegin;5657/// GlobalNames - A map of globally visible named entities for this unit.58StringMap<const DIE *> GlobalNames;5960/// GlobalTypes - A map of globally visible types for this unit.61StringMap<const DIE *> GlobalTypes;6263// List of ranges for a given compile unit.64SmallVector<RangeSpan, 2> CURanges;6566// The base address of this unit, if any. Used for relative references in67// ranges/locs.68const MCSymbol *BaseAddress = nullptr;6970using MDNodeSetVector =71SetVector<const MDNode *, SmallVector<const MDNode *, 4>,72SmallPtrSet<const MDNode *, 4>>;7374// List of entities (either static locals, types or imports) that75// belong to subprograms within this CU.76MDNodeSetVector DeferredLocalDecls;7778// List of concrete lexical block scopes belong to subprograms within this CU.79DenseMap<const DILocalScope *, DIE *> LexicalBlockDIEs;8081// List of abstract local scopes (either DISubprogram or DILexicalBlock).82DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;8384DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;8586/// DWO ID for correlating skeleton and split units.87uint64_t DWOId = 0;8889const DIFile *LastFile = nullptr;90unsigned LastFileID;9192/// \anchor applyConcreteDbgVariableAttribute93/// \name applyConcreteDbgVariableAttribute94/// Overload set which applies attributes to \c VariableDie based on95/// the active variant of \c DV, which is passed as the first argument.96///@{9798/// See \ref applyConcreteDbgVariableAttribute99void applyConcreteDbgVariableAttributes(const Loc::Single &Single,100const DbgVariable &DV,101DIE &VariableDie);102/// See \ref applyConcreteDbgVariableAttribute103void applyConcreteDbgVariableAttributes(const Loc::Multi &Multi,104const DbgVariable &DV,105DIE &VariableDie);106/// See \ref applyConcreteDbgVariableAttribute107void applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,108const DbgVariable &DV,109DIE &VariableDie);110/// See \ref applyConcreteDbgVariableAttribute111void applyConcreteDbgVariableAttributes(const Loc::EntryValue &EntryValue,112const DbgVariable &DV,113DIE &VariableDie);114/// See \ref applyConcreteDbgVariableAttribute115void applyConcreteDbgVariableAttributes(const std::monostate &,116const DbgVariable &DV,117DIE &VariableDie);118119///@}120121bool isDwoUnit() const override;122123DenseMap<const DILocalScope *, DIE *> &getAbstractScopeDIEs() {124if (isDwoUnit() && !DD->shareAcrossDWOCUs())125return AbstractLocalScopeDIEs;126return DU->getAbstractScopeDIEs();127}128129DenseMap<const DINode *, std::unique_ptr<DbgEntity>> &getAbstractEntities() {130if (isDwoUnit() && !DD->shareAcrossDWOCUs())131return AbstractEntities;132return DU->getAbstractEntities();133}134135void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override;136137/// Add info for Wasm-global-based relocation.138void addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,139uint64_t GlobalIndex);140141public:142DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,143DwarfDebug *DW, DwarfFile *DWU,144UnitKind Kind = UnitKind::Full);145146bool hasRangeLists() const { return HasRangeLists; }147148DwarfCompileUnit *getSkeleton() const {149return Skeleton;150}151152bool includeMinimalInlineScopes() const;153154void initStmtList();155156/// Apply the DW_AT_stmt_list from this compile unit to the specified DIE.157void applyStmtList(DIE &D);158159/// Get line table start symbol for this unit.160MCSymbol *getLineTableStartSym() const { return LineTableStartSym; }161162/// A pair of GlobalVariable and DIExpression.163struct GlobalExpr {164const GlobalVariable *Var;165const DIExpression *Expr;166};167168struct BaseTypeRef {169BaseTypeRef(unsigned BitSize, dwarf::TypeKind Encoding) :170BitSize(BitSize), Encoding(Encoding) {}171unsigned BitSize;172dwarf::TypeKind Encoding;173DIE *Die = nullptr;174};175176std::vector<BaseTypeRef> ExprRefedBaseTypes;177178/// Get or create global variable DIE.179DIE *180getOrCreateGlobalVariableDIE(const DIGlobalVariable *GV,181ArrayRef<GlobalExpr> GlobalExprs);182183DIE *getOrCreateCommonBlock(const DICommonBlock *CB,184ArrayRef<GlobalExpr> GlobalExprs);185186void addLocationAttribute(DIE *ToDIE, const DIGlobalVariable *GV,187ArrayRef<GlobalExpr> GlobalExprs);188189/// addLabelAddress - Add a dwarf label attribute data and value using190/// either DW_FORM_addr or DW_FORM_GNU_addr_index.191void addLabelAddress(DIE &Die, dwarf::Attribute Attribute,192const MCSymbol *Label);193194/// addLocalLabelAddress - Add a dwarf label attribute data and value using195/// DW_FORM_addr only.196void addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute,197const MCSymbol *Label);198199DwarfCompileUnit &getCU() override { return *this; }200201unsigned getOrCreateSourceID(const DIFile *File) override;202203/// addRange - Add an address range to the list of ranges for this unit.204void addRange(RangeSpan Range);205206void attachLowHighPC(DIE &D, const MCSymbol *Begin, const MCSymbol *End);207208/// Find DIE for the given subprogram and attach appropriate209/// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global210/// variables in this scope then create and insert DIEs for these211/// variables.212DIE &updateSubprogramScopeDIE(const DISubprogram *SP);213214void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE);215216/// A helper function to construct a RangeSpanList for a given217/// lexical scope.218void addScopeRangeList(DIE &ScopeDIE, SmallVector<RangeSpan, 2> Range);219220void attachRangesOrLowHighPC(DIE &D, SmallVector<RangeSpan, 2> Ranges);221222void attachRangesOrLowHighPC(DIE &D,223const SmallVectorImpl<InsnRange> &Ranges);224225/// This scope represents an inlined body of a function. Construct a226/// DIE to represent this concrete inlined copy of the function.227DIE *constructInlinedScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE);228229/// Construct new DW_TAG_lexical_block for this scope and230/// attach DW_AT_low_pc/DW_AT_high_pc labels.231DIE *constructLexicalScopeDIE(LexicalScope *Scope);232233/// Get a DIE for the given DILexicalBlock.234/// Note that this function assumes that the DIE has been already created235/// and it's an error, if it hasn't.236DIE *getLexicalBlockDIE(const DILexicalBlock *LB);237238/// Construct a DIE for the given DbgVariable.239DIE *constructVariableDIE(DbgVariable &DV, bool Abstract = false);240241/// Convenience overload which writes the DIE pointer into an out variable242/// ObjectPointer in addition to returning it.243DIE *constructVariableDIE(DbgVariable &DV, const LexicalScope &Scope,244DIE *&ObjectPointer);245246/// Construct a DIE for the given DbgLabel.247DIE *constructLabelDIE(DbgLabel &DL, const LexicalScope &Scope);248249void createBaseTypeDIEs();250251/// Construct a DIE for a given scope.252/// This instance of 'getOrCreateContextDIE()' can handle DILocalScope.253DIE *getOrCreateContextDIE(const DIScope *Ty) override;254255/// Construct a DIE for this subprogram scope.256DIE &constructSubprogramScopeDIE(const DISubprogram *Sub,257LexicalScope *Scope);258259DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE);260261void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);262263/// Whether to use the GNU analog for a DWARF5 tag, attribute, or location264/// atom. Only applicable when emitting otherwise DWARF4-compliant debug info.265bool useGNUAnalogForDwarf5Feature() const;266267/// This takes a DWARF 5 tag and returns it or a GNU analog.268dwarf::Tag getDwarf5OrGNUTag(dwarf::Tag Tag) const;269270/// This takes a DWARF 5 attribute and returns it or a GNU analog.271dwarf::Attribute getDwarf5OrGNUAttr(dwarf::Attribute Attr) const;272273/// This takes a DWARF 5 location atom and either returns it or a GNU analog.274dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const;275276/// Construct a call site entry DIE describing a call within \p Scope to a277/// callee described by \p CalleeSP.278/// \p IsTail specifies whether the call is a tail call.279/// \p PCAddr points to the PC value after the call instruction.280/// \p CallAddr points to the PC value at the call instruction (or is null).281/// \p CallReg is a register location for an indirect call. For direct calls282/// the \p CallReg is set to 0.283DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,284bool IsTail, const MCSymbol *PCAddr,285const MCSymbol *CallAddr, unsigned CallReg);286/// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params287/// were collected by the \ref collectCallSiteParameters.288/// Note: The order of parameters does not matter, since debuggers recognize289/// call site parameters by the DW_AT_location attribute.290void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE,291SmallVector<DbgCallSiteParam, 4> &Params);292293/// Get or create a DIE for an imported entity.294DIE *getOrCreateImportedEntityDIE(const DIImportedEntity *IE);295DIE *constructImportedEntityDIE(const DIImportedEntity *IE);296297void finishSubprogramDefinition(const DISubprogram *SP);298void finishEntityDefinition(const DbgEntity *Entity);299300/// Find abstract variable associated with Var.301using InlinedEntity = DbgValueHistoryMap::InlinedEntity;302DbgEntity *getExistingAbstractEntity(const DINode *Node);303void createAbstractEntity(const DINode *Node, LexicalScope *Scope);304305/// Set the skeleton unit associated with this unit.306void setSkeleton(DwarfCompileUnit &Skel) { Skeleton = &Skel; }307308unsigned getHeaderSize() const override {309// DWARF v5 added the DWO ID to the header for split/skeleton units.310unsigned DWOIdSize =311DD->getDwarfVersion() >= 5 && DD->useSplitDwarf() ? sizeof(uint64_t)312: 0;313return DwarfUnit::getHeaderSize() + DWOIdSize;314}315unsigned getLength() {316return Asm->getUnitLengthFieldByteSize() + // Length field317getHeaderSize() + getUnitDie().getSize();318}319320void emitHeader(bool UseOffsets) override;321322/// Add the DW_AT_addr_base attribute to the unit DIE.323void addAddrTableBase();324325MCSymbol *getMacroLabelBegin() const {326return MacroLabelBegin;327}328329/// Add a new global name to the compile unit.330void addGlobalName(StringRef Name, const DIE &Die,331const DIScope *Context) override;332333/// Add a new global name present in a type unit to this compile unit.334void addGlobalNameForTypeUnit(StringRef Name, const DIScope *Context);335336/// Add a new global type to the compile unit.337void addGlobalTypeImpl(const DIType *Ty, const DIE &Die,338const DIScope *Context) override;339340/// Add a new global type present in a type unit to this compile unit.341void addGlobalTypeUnitType(const DIType *Ty, const DIScope *Context);342343const StringMap<const DIE *> &getGlobalNames() const { return GlobalNames; }344const StringMap<const DIE *> &getGlobalTypes() const { return GlobalTypes; }345346/// Add DW_AT_location attribute for a DbgVariable based on provided347/// MachineLocation.348void addVariableAddress(const DbgVariable &DV, DIE &Die,349MachineLocation Location);350/// Add an address attribute to a die based on the location provided.351void addAddress(DIE &Die, dwarf::Attribute Attribute,352const MachineLocation &Location);353354/// Start with the address based on the location provided, and generate the355/// DWARF information necessary to find the actual variable (navigating the356/// extra location information encoded in the type) based on the starting357/// location. Add the DWARF information to the die.358void addComplexAddress(const DIExpression *DIExpr, DIE &Die,359dwarf::Attribute Attribute,360const MachineLocation &Location);361362/// Add a Dwarf loclistptr attribute data and value.363void addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index);364365/// Add attributes to \p Var which reflect the common attributes of \p366/// VariableDie, namely those which are not dependant on the active variant.367void applyCommonDbgVariableAttributes(const DbgVariable &Var,368DIE &VariableDie);369370/// Add a Dwarf expression attribute data and value.371void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr);372373void applySubprogramAttributesToDefinition(const DISubprogram *SP,374DIE &SPDie);375376void applyLabelAttributes(const DbgLabel &Label, DIE &LabelDie);377378/// getRanges - Get the list of ranges for this unit.379const SmallVectorImpl<RangeSpan> &getRanges() const { return CURanges; }380SmallVector<RangeSpan, 2> takeRanges() { return std::move(CURanges); }381382void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; }383const MCSymbol *getBaseAddress() const { return BaseAddress; }384385uint64_t getDWOId() const { return DWOId; }386void setDWOId(uint64_t DwoId) { DWOId = DwoId; }387388bool hasDwarfPubSections() const;389390void addBaseTypeRef(DIEValueList &Die, int64_t Idx);391392MDNodeSetVector &getDeferredLocalDecls() { return DeferredLocalDecls; }393};394395} // end namespace llvm396397#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H398399400