Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
35271 views
//===- llvm/CodeGen/DwarfDebug.h - Dwarf Debug Framework --------*- 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 debug info into asm files.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H13#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H1415#include "AddressPool.h"16#include "DebugLocEntry.h"17#include "DebugLocStream.h"18#include "DwarfFile.h"19#include "llvm/ADT/DenseMap.h"20#include "llvm/ADT/DenseSet.h"21#include "llvm/ADT/MapVector.h"22#include "llvm/ADT/SetVector.h"23#include "llvm/ADT/SmallPtrSet.h"24#include "llvm/ADT/SmallVector.h"25#include "llvm/ADT/StringMap.h"26#include "llvm/ADT/StringRef.h"27#include "llvm/BinaryFormat/Dwarf.h"28#include "llvm/CodeGen/AccelTable.h"29#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"30#include "llvm/CodeGen/DebugHandlerBase.h"31#include "llvm/IR/DebugInfoMetadata.h"32#include "llvm/IR/DebugLoc.h"33#include "llvm/IR/Metadata.h"34#include "llvm/MC/MCDwarf.h"35#include "llvm/Support/Allocator.h"36#include "llvm/Target/TargetOptions.h"37#include <cassert>38#include <cstdint>39#include <limits>40#include <memory>41#include <utility>42#include <variant>43#include <vector>4445namespace llvm {4647class AsmPrinter;48class ByteStreamer;49class DIE;50class DwarfCompileUnit;51class DwarfExpression;52class DwarfTypeUnit;53class DwarfUnit;54class LexicalScope;55class MachineFunction;56class MCSection;57class MCSymbol;58class Module;5960//===----------------------------------------------------------------------===//61/// This class is defined as the common parent of DbgVariable and DbgLabel62/// such that it could levarage polymorphism to extract common code for63/// DbgVariable and DbgLabel.64class DbgEntity {65public:66enum DbgEntityKind {67DbgVariableKind,68DbgLabelKind69};7071private:72const DINode *Entity;73const DILocation *InlinedAt;74DIE *TheDIE = nullptr;75const DbgEntityKind SubclassID;7677public:78DbgEntity(const DINode *N, const DILocation *IA, DbgEntityKind ID)79: Entity(N), InlinedAt(IA), SubclassID(ID) {}80virtual ~DbgEntity() = default;8182/// Accessors.83/// @{84const DINode *getEntity() const { return Entity; }85const DILocation *getInlinedAt() const { return InlinedAt; }86DIE *getDIE() const { return TheDIE; }87DbgEntityKind getDbgEntityID() const { return SubclassID; }88/// @}8990void setDIE(DIE &D) { TheDIE = &D; }9192static bool classof(const DbgEntity *N) {93switch (N->getDbgEntityID()) {94case DbgVariableKind:95case DbgLabelKind:96return true;97}98llvm_unreachable("Invalid DbgEntityKind");99}100};101102class DbgVariable;103104bool operator<(const struct FrameIndexExpr &LHS,105const struct FrameIndexExpr &RHS);106bool operator<(const struct EntryValueInfo &LHS,107const struct EntryValueInfo &RHS);108109/// Proxy for one MMI entry.110struct FrameIndexExpr {111int FI;112const DIExpression *Expr;113114/// Operator enabling sorting based on fragment offset.115friend bool operator<(const FrameIndexExpr &LHS, const FrameIndexExpr &RHS);116};117118/// Represents an entry-value location, or a fragment of one.119struct EntryValueInfo {120MCRegister Reg;121const DIExpression &Expr;122123/// Operator enabling sorting based on fragment offset.124friend bool operator<(const EntryValueInfo &LHS, const EntryValueInfo &RHS);125};126127// Namespace for alternatives of a DbgVariable.128namespace Loc {129/// Single value location description.130class Single {131std::unique_ptr<DbgValueLoc> ValueLoc;132const DIExpression *Expr;133134public:135explicit Single(DbgValueLoc ValueLoc);136explicit Single(const MachineInstr *DbgValue);137const DbgValueLoc &getValueLoc() const { return *ValueLoc; }138const DIExpression *getExpr() const { return Expr; }139};140/// Multi-value location description.141class Multi {142/// Index of the entry list in DebugLocs.143unsigned DebugLocListIndex;144/// DW_OP_LLVM_tag_offset value from DebugLocs.145std::optional<uint8_t> DebugLocListTagOffset;146147public:148explicit Multi(unsigned DebugLocListIndex,149std::optional<uint8_t> DebugLocListTagOffset)150: DebugLocListIndex(DebugLocListIndex),151DebugLocListTagOffset(DebugLocListTagOffset) {}152unsigned getDebugLocListIndex() const { return DebugLocListIndex; }153std::optional<uint8_t> getDebugLocListTagOffset() const {154return DebugLocListTagOffset;155}156};157/// Single location defined by (potentially multiple) MMI entries.158struct MMI {159std::set<FrameIndexExpr> FrameIndexExprs;160161public:162explicit MMI(const DIExpression *E, int FI) : FrameIndexExprs({{FI, E}}) {163assert((!E || E->isValid()) && "Expected valid expression");164assert(FI != std::numeric_limits<int>::max() && "Expected valid index");165}166void addFrameIndexExpr(const DIExpression *Expr, int FI);167/// Get the FI entries, sorted by fragment offset.168const std::set<FrameIndexExpr> &getFrameIndexExprs() const;169};170/// Single location defined by (potentially multiple) EntryValueInfo.171struct EntryValue {172std::set<EntryValueInfo> EntryValues;173explicit EntryValue(MCRegister Reg, const DIExpression &Expr) {174addExpr(Reg, Expr);175};176// Add the pair Reg, Expr to the list of entry values describing the variable.177// If multiple expressions are added, it is the callers responsibility to178// ensure they are all non-overlapping fragments.179void addExpr(MCRegister Reg, const DIExpression &Expr) {180std::optional<const DIExpression *> NonVariadicExpr =181DIExpression::convertToNonVariadicExpression(&Expr);182assert(NonVariadicExpr && *NonVariadicExpr);183184EntryValues.insert({Reg, **NonVariadicExpr});185}186};187/// Alias for the std::variant specialization base class of DbgVariable.188using Variant = std::variant<std::monostate, Loc::Single, Loc::Multi, Loc::MMI,189Loc::EntryValue>;190} // namespace Loc191192//===----------------------------------------------------------------------===//193/// This class is used to track local variable information.194///195/// Variables that have been optimized out hold the \c monostate alternative.196/// This is not distinguished from the case of a constructed \c DbgVariable197/// which has not be initialized yet.198///199/// Variables can be created from allocas, in which case they're generated from200/// the MMI table. Such variables hold the \c Loc::MMI alternative which can201/// have multiple expressions and frame indices.202///203/// Variables can be created from the entry value of registers, in which case204/// they're generated from the MMI table. Such variables hold the \c205/// EntryValueLoc alternative which can either have a single expression or206/// multiple *fragment* expressions.207///208/// Variables can be created from \c DBG_VALUE instructions. Those whose209/// location changes over time hold a \c Loc::Multi alternative which uses \c210/// DebugLocListIndex and (optionally) \c DebugLocListTagOffset, while those211/// with a single location hold a \c Loc::Single alternative which use \c212/// ValueLoc and (optionally) a single \c Expr.213class DbgVariable : public DbgEntity, public Loc::Variant {214215public:216/// To workaround P2162R0 https://github.com/cplusplus/papers/issues/873 the217/// base class subobject needs to be passed directly to std::visit, so expose218/// it directly here.219Loc::Variant &asVariant() { return *static_cast<Loc::Variant *>(this); }220const Loc::Variant &asVariant() const {221return *static_cast<const Loc::Variant *>(this);222}223/// Member shorthand for std::holds_alternative224template <typename T> bool holds() const {225return std::holds_alternative<T>(*this);226}227/// Asserting, noexcept member alternative to std::get228template <typename T> auto &get() noexcept {229assert(holds<T>());230return *std::get_if<T>(this);231}232/// Asserting, noexcept member alternative to std::get233template <typename T> const auto &get() const noexcept {234assert(holds<T>());235return *std::get_if<T>(this);236}237238/// Construct a DbgVariable.239///240/// Creates a variable without any DW_AT_location.241DbgVariable(const DILocalVariable *V, const DILocation *IA)242: DbgEntity(V, IA, DbgVariableKind) {}243244// Accessors.245const DILocalVariable *getVariable() const {246return cast<DILocalVariable>(getEntity());247}248249StringRef getName() const { return getVariable()->getName(); }250251// Translate tag to proper Dwarf tag.252dwarf::Tag getTag() const {253// FIXME: Why don't we just infer this tag and store it all along?254if (getVariable()->isParameter())255return dwarf::DW_TAG_formal_parameter;256257return dwarf::DW_TAG_variable;258}259260/// Return true if DbgVariable is artificial.261bool isArtificial() const {262if (getVariable()->isArtificial())263return true;264if (getType()->isArtificial())265return true;266return false;267}268269bool isObjectPointer() const {270if (getVariable()->isObjectPointer())271return true;272if (getType()->isObjectPointer())273return true;274return false;275}276277const DIType *getType() const;278279static bool classof(const DbgEntity *N) {280return N->getDbgEntityID() == DbgVariableKind;281}282};283284//===----------------------------------------------------------------------===//285/// This class is used to track label information.286///287/// Labels are collected from \c DBG_LABEL instructions.288class DbgLabel : public DbgEntity {289const MCSymbol *Sym; /// Symbol before DBG_LABEL instruction.290291public:292/// We need MCSymbol information to generate DW_AT_low_pc.293DbgLabel(const DILabel *L, const DILocation *IA, const MCSymbol *Sym = nullptr)294: DbgEntity(L, IA, DbgLabelKind), Sym(Sym) {}295296/// Accessors.297/// @{298const DILabel *getLabel() const { return cast<DILabel>(getEntity()); }299const MCSymbol *getSymbol() const { return Sym; }300301StringRef getName() const { return getLabel()->getName(); }302/// @}303304/// Translate tag to proper Dwarf tag.305dwarf::Tag getTag() const {306return dwarf::DW_TAG_label;307}308309static bool classof(const DbgEntity *N) {310return N->getDbgEntityID() == DbgLabelKind;311}312};313314/// Used for tracking debug info about call site parameters.315class DbgCallSiteParam {316private:317unsigned Register; ///< Parameter register at the callee entry point.318DbgValueLoc Value; ///< Corresponding location for the parameter value at319///< the call site.320public:321DbgCallSiteParam(unsigned Reg, DbgValueLoc Val)322: Register(Reg), Value(Val) {323assert(Reg && "Parameter register cannot be undef");324}325326unsigned getRegister() const { return Register; }327DbgValueLoc getValue() const { return Value; }328};329330/// Collection used for storing debug call site parameters.331using ParamSet = SmallVector<DbgCallSiteParam, 4>;332333/// Helper used to pair up a symbol and its DWARF compile unit.334struct SymbolCU {335SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {}336337const MCSymbol *Sym;338DwarfCompileUnit *CU;339};340341/// The kind of accelerator tables we should emit.342enum class AccelTableKind {343Default, ///< Platform default.344None, ///< None.345Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.346Dwarf, ///< DWARF v5 .debug_names.347};348349/// Collects and handles dwarf debug information.350class DwarfDebug : public DebugHandlerBase {351/// All DIEValues are allocated through this allocator.352BumpPtrAllocator DIEValueAllocator;353354/// Maps MDNode with its corresponding DwarfCompileUnit.355MapVector<const MDNode *, DwarfCompileUnit *> CUMap;356357/// Maps a CU DIE with its corresponding DwarfCompileUnit.358DenseMap<const DIE *, DwarfCompileUnit *> CUDieMap;359360/// List of all labels used in aranges generation.361std::vector<SymbolCU> ArangeLabels;362363/// Size of each symbol emitted (for those symbols that have a specific size).364DenseMap<const MCSymbol *, uint64_t> SymSize;365366/// Collection of abstract variables/labels.367SmallVector<std::unique_ptr<DbgEntity>, 64> ConcreteEntities;368369/// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists370/// can refer to them in spite of insertions into this list.371DebugLocStream DebugLocs;372373/// This is a collection of subprogram MDNodes that are processed to374/// create DIEs.375SmallSetVector<const DISubprogram *, 16> ProcessedSPNodes;376377/// Map function-local imported entities to their parent local scope378/// (either DILexicalBlock or DISubprogram) for a processed function379/// (including inlined subprograms).380using MDNodeSet = SetVector<const MDNode *, SmallVector<const MDNode *, 2>,381SmallPtrSet<const MDNode *, 2>>;382DenseMap<const DILocalScope *, MDNodeSet> LocalDeclsPerLS;383384/// If nonnull, stores the current machine function we're processing.385const MachineFunction *CurFn = nullptr;386387/// If nonnull, stores the CU in which the previous subprogram was contained.388const DwarfCompileUnit *PrevCU = nullptr;389390/// As an optimization, there is no need to emit an entry in the directory391/// table for the same directory as DW_AT_comp_dir.392StringRef CompilationDir;393394/// Holder for the file specific debug information.395DwarfFile InfoHolder;396397/// Holders for the various debug information flags that we might need to398/// have exposed. See accessor functions below for description.399400/// Map from MDNodes for user-defined types to their type signatures. Also401/// used to keep track of which types we have emitted type units for.402DenseMap<const MDNode *, uint64_t> TypeSignatures;403404DenseMap<const MCSection *, const MCSymbol *> SectionLabels;405406SmallVector<407std::pair<std::unique_ptr<DwarfTypeUnit>, const DICompositeType *>, 1>408TypeUnitsUnderConstruction;409410/// Used to set a uniqe ID for a Type Unit.411/// This counter represents number of DwarfTypeUnits created, not necessarily412/// number of type units that will be emitted.413unsigned NumTypeUnitsCreated = 0;414415/// Whether to use the GNU TLS opcode (instead of the standard opcode).416bool UseGNUTLSOpcode;417418/// Whether to use DWARF 2 bitfields (instead of the DWARF 4 format).419bool UseDWARF2Bitfields;420421/// Whether to emit all linkage names, or just abstract subprograms.422bool UseAllLinkageNames;423424/// Use inlined strings.425bool UseInlineStrings = false;426427/// Allow emission of .debug_ranges section.428bool UseRangesSection = true;429430/// True if the sections itself must be used as references and don't create431/// temp symbols inside DWARF sections.432bool UseSectionsAsReferences = false;433434///Allow emission of the .debug_loc section.435bool UseLocSection = true;436437/// Generate DWARF v4 type units.438bool GenerateTypeUnits;439440/// Emit a .debug_macro section instead of .debug_macinfo.441bool UseDebugMacroSection;442443/// Avoid using DW_OP_convert due to consumer incompatibilities.444bool EnableOpConvert;445446public:447enum class MinimizeAddrInV5 {448Default,449Disabled,450Ranges,451Expressions,452Form,453};454455enum class DWARF5AccelTableKind {456CU = 0,457TU = 1,458};459460private:461/// Force the use of DW_AT_ranges even for single-entry range lists.462MinimizeAddrInV5 MinimizeAddr = MinimizeAddrInV5::Disabled;463464/// DWARF5 Experimental Options465/// @{466AccelTableKind TheAccelTableKind;467bool HasAppleExtensionAttributes;468bool HasSplitDwarf;469470/// Whether to generate the DWARF v5 string offsets table.471/// It consists of a series of contributions, each preceded by a header.472/// The pre-DWARF v5 string offsets table for split dwarf is, in contrast,473/// a monolithic sequence of string offsets.474bool UseSegmentedStringOffsetsTable;475476/// Enable production of call site parameters needed to print the debug entry477/// values. Useful for testing purposes when a debugger does not support the478/// feature yet.479bool EmitDebugEntryValues;480481/// Separated Dwarf Variables482/// In general these will all be for bits that are left in the483/// original object file, rather than things that are meant484/// to be in the .dwo sections.485486/// Holder for the skeleton information.487DwarfFile SkeletonHolder;488489/// Store file names for type units under fission in a line table490/// header that will be emitted into debug_line.dwo.491// FIXME: replace this with a map from comp_dir to table so that we492// can emit multiple tables during LTO each of which uses directory493// 0, referencing the comp_dir of all the type units that use it.494MCDwarfDwoLineTable SplitTypeUnitFileTable;495/// @}496497/// True iff there are multiple CUs in this module.498bool SingleCU;499bool IsDarwin;500501/// Map for tracking Fortran deferred CHARACTER lengths.502DenseMap<const DIStringType *, unsigned> StringTypeLocMap;503504AddressPool AddrPool;505506/// Accelerator tables.507DWARF5AccelTable AccelDebugNames;508DWARF5AccelTable AccelTypeUnitsDebugNames;509/// Used to hide which DWARF5AccelTable we are using now.510DWARF5AccelTable *CurrentDebugNames = &AccelDebugNames;511AccelTable<AppleAccelTableOffsetData> AccelNames;512AccelTable<AppleAccelTableOffsetData> AccelObjC;513AccelTable<AppleAccelTableOffsetData> AccelNamespace;514AccelTable<AppleAccelTableTypeData> AccelTypes;515516/// Identify a debugger for "tuning" the debug info.517///518/// The "tuning" should be used to set defaults for individual feature flags519/// in DwarfDebug; if a given feature has a more specific command-line option,520/// that option should take precedence over the tuning.521DebuggerKind DebuggerTuning = DebuggerKind::Default;522523MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &);524525const SmallVectorImpl<std::unique_ptr<DwarfCompileUnit>> &getUnits() {526return InfoHolder.getUnits();527}528529using InlinedEntity = DbgValueHistoryMap::InlinedEntity;530531void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,532const DINode *Node,533const MDNode *Scope);534535DbgEntity *createConcreteEntity(DwarfCompileUnit &TheCU,536LexicalScope &Scope,537const DINode *Node,538const DILocation *Location,539const MCSymbol *Sym = nullptr);540541/// Construct a DIE for this abstract scope.542void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);543544/// Construct DIEs for call site entries describing the calls in \p MF.545void constructCallSiteEntryDIEs(const DISubprogram &SP, DwarfCompileUnit &CU,546DIE &ScopeDIE, const MachineFunction &MF);547548template <typename DataT>549void addAccelNameImpl(const DwarfUnit &Unit,550const DICompileUnit::DebugNameTableKind NameTableKind,551AccelTable<DataT> &AppleAccel, StringRef Name,552const DIE &Die);553554void finishEntityDefinitions();555556void finishSubprogramDefinitions();557558/// Finish off debug information after all functions have been559/// processed.560void finalizeModuleInfo();561562/// Emit the debug info section.563void emitDebugInfo();564565/// Emit the abbreviation section.566void emitAbbreviations();567568/// Emit the string offsets table header.569void emitStringOffsetsTableHeader();570571/// Emit a specified accelerator table.572template <typename AccelTableT>573void emitAccel(AccelTableT &Accel, MCSection *Section, StringRef TableName);574575/// Emit DWARF v5 accelerator table.576void emitAccelDebugNames();577578/// Emit visible names into a hashed accelerator table section.579void emitAccelNames();580581/// Emit objective C classes and categories into a hashed582/// accelerator table section.583void emitAccelObjC();584585/// Emit namespace dies into a hashed accelerator table.586void emitAccelNamespaces();587588/// Emit type dies into a hashed accelerator table.589void emitAccelTypes();590591/// Emit visible names and types into debug pubnames and pubtypes sections.592void emitDebugPubSections();593594void emitDebugPubSection(bool GnuStyle, StringRef Name,595DwarfCompileUnit *TheU,596const StringMap<const DIE *> &Globals);597598/// Emit null-terminated strings into a debug str section.599void emitDebugStr();600601/// Emit variable locations into a debug loc section.602void emitDebugLoc();603604/// Emit variable locations into a debug loc dwo section.605void emitDebugLocDWO();606607void emitDebugLocImpl(MCSection *Sec);608609/// Emit address ranges into a debug aranges section.610void emitDebugARanges();611612/// Emit address ranges into a debug ranges section.613void emitDebugRanges();614void emitDebugRangesDWO();615void emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section);616617/// Emit macros into a debug macinfo section.618void emitDebugMacinfo();619/// Emit macros into a debug macinfo.dwo section.620void emitDebugMacinfoDWO();621void emitDebugMacinfoImpl(MCSection *Section);622void emitMacro(DIMacro &M);623void emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U);624void emitMacroFileImpl(DIMacroFile &F, DwarfCompileUnit &U,625unsigned StartFile, unsigned EndFile,626StringRef (*MacroFormToString)(unsigned Form));627void handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U);628629/// DWARF 5 Experimental Split Dwarf Emitters630631/// Initialize common features of skeleton units.632void initSkeletonUnit(const DwarfUnit &U, DIE &Die,633std::unique_ptr<DwarfCompileUnit> NewU);634635/// Construct the split debug info compile unit for the debug info section.636/// In DWARF v5, the skeleton unit DIE may have the following attributes:637/// DW_AT_addr_base, DW_AT_comp_dir, DW_AT_dwo_name, DW_AT_high_pc,638/// DW_AT_low_pc, DW_AT_ranges, DW_AT_stmt_list, and DW_AT_str_offsets_base.639/// Prior to DWARF v5 it may also have DW_AT_GNU_dwo_id. DW_AT_GNU_dwo_name640/// is used instead of DW_AT_dwo_name, Dw_AT_GNU_addr_base instead of641/// DW_AT_addr_base, and DW_AT_GNU_ranges_base instead of DW_AT_rnglists_base.642DwarfCompileUnit &constructSkeletonCU(const DwarfCompileUnit &CU);643644/// Emit the debug info dwo section.645void emitDebugInfoDWO();646647/// Emit the debug abbrev dwo section.648void emitDebugAbbrevDWO();649650/// Emit the debug line dwo section.651void emitDebugLineDWO();652653/// Emit the dwo stringoffsets table header.654void emitStringOffsetsTableHeaderDWO();655656/// Emit the debug str dwo section.657void emitDebugStrDWO();658659/// Emit DWO addresses.660void emitDebugAddr();661662/// Flags to let the linker know we have emitted new style pubnames. Only663/// emit it here if we don't have a skeleton CU for split dwarf.664void addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const;665666/// Create new DwarfCompileUnit for the given metadata node with tag667/// DW_TAG_compile_unit.668DwarfCompileUnit &getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit);669void finishUnitAttributes(const DICompileUnit *DIUnit,670DwarfCompileUnit &NewCU);671672/// Register a source line with debug info. Returns the unique673/// label that was emitted and which provides correspondence to the674/// source line list.675void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope,676unsigned Flags);677678/// Populate LexicalScope entries with variables' info.679void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP,680DenseSet<InlinedEntity> &ProcessedVars);681682/// Build the location list for all DBG_VALUEs in the683/// function that describe the same variable. If the resulting684/// list has only one entry that is valid for entire variable's685/// scope return true.686bool buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,687const DbgValueHistoryMap::Entries &Entries);688689/// Collect variable information from the side table maintained by MF.690void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU,691DenseSet<InlinedEntity> &P);692693/// Emit the reference to the section.694void emitSectionReference(const DwarfCompileUnit &CU);695696protected:697/// Gather pre-function debug information.698void beginFunctionImpl(const MachineFunction *MF) override;699700/// Gather and emit post-function debug information.701void endFunctionImpl(const MachineFunction *MF) override;702703/// Get Dwarf compile unit ID for line table.704unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU);705706void skippedNonDebugFunction() override;707708public:709//===--------------------------------------------------------------------===//710// Main entry points.711//712DwarfDebug(AsmPrinter *A);713714~DwarfDebug() override;715716/// Emit all Dwarf sections that should come prior to the717/// content.718void beginModule(Module *M) override;719720/// Emit all Dwarf sections that should come after the content.721void endModule() override;722723/// Emits inital debug location directive.724DebugLoc emitInitialLocDirective(const MachineFunction &MF, unsigned CUID);725726/// Process beginning of an instruction.727void beginInstruction(const MachineInstr *MI) override;728729/// Perform an MD5 checksum of \p Identifier and return the lower 64 bits.730static uint64_t makeTypeSignature(StringRef Identifier);731732/// Add a DIE to the set of types that we're going to pull into733/// type units.734void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier,735DIE &Die, const DICompositeType *CTy);736737/// Add a label so that arange data can be generated for it.738void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }739740/// For symbols that have a size designated (e.g. common symbols),741/// this tracks that size.742void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {743SymSize[Sym] = Size;744}745746/// Returns whether we should emit all DW_AT_[MIPS_]linkage_name.747/// If not, we still might emit certain cases.748bool useAllLinkageNames() const { return UseAllLinkageNames; }749750/// Returns whether to use DW_OP_GNU_push_tls_address, instead of the751/// standard DW_OP_form_tls_address opcode752bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; }753754/// Returns whether to use the DWARF2 format for bitfields instyead of the755/// DWARF4 format.756bool useDWARF2Bitfields() const { return UseDWARF2Bitfields; }757758/// Returns whether to use inline strings.759bool useInlineStrings() const { return UseInlineStrings; }760761/// Returns whether ranges section should be emitted.762bool useRangesSection() const { return UseRangesSection; }763764/// Returns whether range encodings should be used for single entry range765/// lists.766bool alwaysUseRanges(const DwarfCompileUnit &) const;767768// Returns whether novel exprloc addrx+offset encodings should be used to769// reduce debug_addr size.770bool useAddrOffsetExpressions() const {771return MinimizeAddr == MinimizeAddrInV5::Expressions;772}773774// Returns whether addrx+offset LLVM extension form should be used to reduce775// debug_addr size.776bool useAddrOffsetForm() const {777return MinimizeAddr == MinimizeAddrInV5::Form;778}779780/// Returns whether to use sections as labels rather than temp symbols.781bool useSectionsAsReferences() const {782return UseSectionsAsReferences;783}784785/// Returns whether .debug_loc section should be emitted.786bool useLocSection() const { return UseLocSection; }787788/// Returns whether to generate DWARF v4 type units.789bool generateTypeUnits() const { return GenerateTypeUnits; }790791// Experimental DWARF5 features.792793/// Returns what kind (if any) of accelerator tables to emit.794AccelTableKind getAccelTableKind() const { return TheAccelTableKind; }795796/// Seet TheAccelTableKind797void setTheAccelTableKind(AccelTableKind K) { TheAccelTableKind = K; };798799bool useAppleExtensionAttributes() const {800return HasAppleExtensionAttributes;801}802803/// Returns whether or not to change the current debug info for the804/// split dwarf proposal support.805bool useSplitDwarf() const { return HasSplitDwarf; }806807/// Returns whether to generate a string offsets table with (possibly shared)808/// contributions from each CU and type unit. This implies the use of809/// DW_FORM_strx* indirect references with DWARF v5 and beyond. Note that810/// DW_FORM_GNU_str_index is also an indirect reference, but it is used with811/// a pre-DWARF v5 implementation of split DWARF sections, which uses a812/// monolithic string offsets table.813bool useSegmentedStringOffsetsTable() const {814return UseSegmentedStringOffsetsTable;815}816817bool emitDebugEntryValues() const {818return EmitDebugEntryValues;819}820821bool useOpConvert() const {822return EnableOpConvert;823}824825bool shareAcrossDWOCUs() const;826827/// Returns the Dwarf Version.828uint16_t getDwarfVersion() const;829830/// Returns a suitable DWARF form to represent a section offset, i.e.831/// * DW_FORM_sec_offset for DWARF version >= 4;832/// * DW_FORM_data8 for 64-bit DWARFv3;833/// * DW_FORM_data4 for 32-bit DWARFv3 and DWARFv2.834dwarf::Form getDwarfSectionOffsetForm() const;835836/// Returns the previous CU that was being updated837const DwarfCompileUnit *getPrevCU() const { return PrevCU; }838void setPrevCU(const DwarfCompileUnit *PrevCU) { this->PrevCU = PrevCU; }839840/// Terminate the line table by adding the last range label.841void terminateLineTable(const DwarfCompileUnit *CU);842843/// Returns the entries for the .debug_loc section.844const DebugLocStream &getDebugLocs() const { return DebugLocs; }845846/// Emit an entry for the debug loc section. This can be used to847/// handle an entry that's going to be emitted into the debug loc section.848void emitDebugLocEntry(ByteStreamer &Streamer,849const DebugLocStream::Entry &Entry,850const DwarfCompileUnit *CU);851852/// Emit the location for a debug loc entry, including the size header.853void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry,854const DwarfCompileUnit *CU);855856void addSubprogramNames(const DwarfUnit &Unit,857const DICompileUnit::DebugNameTableKind NameTableKind,858const DISubprogram *SP, DIE &Die);859860AddressPool &getAddressPool() { return AddrPool; }861862void addAccelName(const DwarfUnit &Unit,863const DICompileUnit::DebugNameTableKind NameTableKind,864StringRef Name, const DIE &Die);865866void addAccelObjC(const DwarfUnit &Unit,867const DICompileUnit::DebugNameTableKind NameTableKind,868StringRef Name, const DIE &Die);869870void addAccelNamespace(const DwarfUnit &Unit,871const DICompileUnit::DebugNameTableKind NameTableKind,872StringRef Name, const DIE &Die);873874void addAccelType(const DwarfUnit &Unit,875const DICompileUnit::DebugNameTableKind NameTableKind,876StringRef Name, const DIE &Die, char Flags);877878const MachineFunction *getCurrentFunction() const { return CurFn; }879880/// A helper function to check whether the DIE for a given Scope is881/// going to be null.882bool isLexicalScopeDIENull(LexicalScope *Scope);883884/// Find the matching DwarfCompileUnit for the given CU DIE.885DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); }886const DwarfCompileUnit *lookupCU(const DIE *Die) const {887return CUDieMap.lookup(Die);888}889890unsigned getStringTypeLoc(const DIStringType *ST) const {891return StringTypeLocMap.lookup(ST);892}893894void addStringTypeLoc(const DIStringType *ST, unsigned Loc) {895assert(ST);896if (Loc)897StringTypeLocMap[ST] = Loc;898}899900/// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger.901///902/// Returns whether we are "tuning" for a given debugger.903/// @{904bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; }905bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; }906bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; }907bool tuneForDBX() const { return DebuggerTuning == DebuggerKind::DBX; }908/// @}909910const MCSymbol *getSectionLabel(const MCSection *S);911void insertSectionLabel(const MCSymbol *S);912913static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,914const DbgValueLoc &Value,915DwarfExpression &DwarfExpr);916917/// If the \p File has an MD5 checksum, return it as an MD5Result918/// allocated in the MCContext.919std::optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const;920921MDNodeSet &getLocalDeclsForScope(const DILocalScope *S) {922return LocalDeclsPerLS[S];923}924925/// Sets the current DWARF5AccelTable to use.926void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind) {927switch (Kind) {928case DWARF5AccelTableKind::CU:929CurrentDebugNames = &AccelDebugNames;930break;931case DWARF5AccelTableKind::TU:932CurrentDebugNames = &AccelTypeUnitsDebugNames;933}934}935/// Returns either CU or TU DWARF5AccelTable.936DWARF5AccelTable &getCurrentDWARF5AccelTable() { return *CurrentDebugNames; }937};938939} // end namespace llvm940941#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H942943944