diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 765 |
1 files changed, 765 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h new file mode 100644 index 000000000000..c8c511f67c2a --- /dev/null +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -0,0 +1,765 @@ +//===- llvm/CodeGen/DwarfDebug.h - Dwarf Debug Framework --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains support for writing dwarf debug info into asm files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H +#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H + +#include "AddressPool.h" +#include "DebugLocStream.h" +#include "DebugLocEntry.h" +#include "DwarfFile.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/CodeGen/AccelTable.h" +#include "llvm/CodeGen/DbgEntityHistoryCalculator.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/IR/Metadata.h" +#include "llvm/MC/MCDwarf.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Target/TargetOptions.h" +#include <cassert> +#include <cstdint> +#include <limits> +#include <memory> +#include <utility> +#include <vector> + +namespace llvm { + +class AsmPrinter; +class ByteStreamer; +class DebugLocEntry; +class DIE; +class DwarfCompileUnit; +class DwarfExpression; +class DwarfTypeUnit; +class DwarfUnit; +class LexicalScope; +class MachineFunction; +class MCSection; +class MCSymbol; +class MDNode; +class Module; + +//===----------------------------------------------------------------------===// +/// This class is defined as the common parent of DbgVariable and DbgLabel +/// such that it could levarage polymorphism to extract common code for +/// DbgVariable and DbgLabel. +class DbgEntity { + const DINode *Entity; + const DILocation *InlinedAt; + DIE *TheDIE = nullptr; + unsigned SubclassID; + +public: + enum DbgEntityKind { + DbgVariableKind, + DbgLabelKind + }; + + DbgEntity(const DINode *N, const DILocation *IA, unsigned ID) + : Entity(N), InlinedAt(IA), SubclassID(ID) {} + virtual ~DbgEntity() {} + + /// Accessors. + /// @{ + const DINode *getEntity() const { return Entity; } + const DILocation *getInlinedAt() const { return InlinedAt; } + DIE *getDIE() const { return TheDIE; } + unsigned getDbgEntityID() const { return SubclassID; } + /// @} + + void setDIE(DIE &D) { TheDIE = &D; } + + static bool classof(const DbgEntity *N) { + switch (N->getDbgEntityID()) { + default: + return false; + case DbgVariableKind: + case DbgLabelKind: + return true; + } + } +}; + +//===----------------------------------------------------------------------===// +/// This class is used to track local variable information. +/// +/// Variables can be created from allocas, in which case they're generated from +/// the MMI table. Such variables can have multiple expressions and frame +/// indices. +/// +/// Variables can be created from \c DBG_VALUE instructions. Those whose +/// location changes over time use \a DebugLocListIndex, while those with a +/// single location use \a ValueLoc and (optionally) a single entry of \a Expr. +/// +/// Variables that have been optimized out use none of these fields. +class DbgVariable : public DbgEntity { + /// Offset in DebugLocs. + unsigned DebugLocListIndex = ~0u; + /// Single value location description. + std::unique_ptr<DbgValueLoc> ValueLoc = nullptr; + + struct FrameIndexExpr { + int FI; + const DIExpression *Expr; + }; + mutable SmallVector<FrameIndexExpr, 1> + FrameIndexExprs; /// Frame index + expression. + +public: + /// Construct a DbgVariable. + /// + /// Creates a variable without any DW_AT_location. Call \a initializeMMI() + /// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions. + DbgVariable(const DILocalVariable *V, const DILocation *IA) + : DbgEntity(V, IA, DbgVariableKind) {} + + /// Initialize from the MMI table. + void initializeMMI(const DIExpression *E, int FI) { + assert(FrameIndexExprs.empty() && "Already initialized?"); + assert(!ValueLoc.get() && "Already initialized?"); + + assert((!E || E->isValid()) && "Expected valid expression"); + assert(FI != std::numeric_limits<int>::max() && "Expected valid index"); + + FrameIndexExprs.push_back({FI, E}); + } + + // Initialize variable's location. + void initializeDbgValue(DbgValueLoc Value) { + assert(FrameIndexExprs.empty() && "Already initialized?"); + assert(!ValueLoc && "Already initialized?"); + assert(!Value.getExpression()->isFragment() && "Fragments not supported."); + + ValueLoc = std::make_unique<DbgValueLoc>(Value); + if (auto *E = ValueLoc->getExpression()) + if (E->getNumElements()) + FrameIndexExprs.push_back({0, E}); + } + + /// Initialize from a DBG_VALUE instruction. + void initializeDbgValue(const MachineInstr *DbgValue); + + // Accessors. + const DILocalVariable *getVariable() const { + return cast<DILocalVariable>(getEntity()); + } + + const DIExpression *getSingleExpression() const { + assert(ValueLoc.get() && FrameIndexExprs.size() <= 1); + return FrameIndexExprs.size() ? FrameIndexExprs[0].Expr : nullptr; + } + + void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; } + unsigned getDebugLocListIndex() const { return DebugLocListIndex; } + StringRef getName() const { return getVariable()->getName(); } + const DbgValueLoc *getValueLoc() const { return ValueLoc.get(); } + /// Get the FI entries, sorted by fragment offset. + ArrayRef<FrameIndexExpr> getFrameIndexExprs() const; + bool hasFrameIndexExprs() const { return !FrameIndexExprs.empty(); } + void addMMIEntry(const DbgVariable &V); + + // Translate tag to proper Dwarf tag. + dwarf::Tag getTag() const { + // FIXME: Why don't we just infer this tag and store it all along? + if (getVariable()->isParameter()) + return dwarf::DW_TAG_formal_parameter; + + return dwarf::DW_TAG_variable; + } + + /// Return true if DbgVariable is artificial. + bool isArtificial() const { + if (getVariable()->isArtificial()) + return true; + if (getType()->isArtificial()) + return true; + return false; + } + + bool isObjectPointer() const { + if (getVariable()->isObjectPointer()) + return true; + if (getType()->isObjectPointer()) + return true; + return false; + } + + bool hasComplexAddress() const { + assert(ValueLoc.get() && "Expected DBG_VALUE, not MMI variable"); + assert((FrameIndexExprs.empty() || + (FrameIndexExprs.size() == 1 && + FrameIndexExprs[0].Expr->getNumElements())) && + "Invalid Expr for DBG_VALUE"); + return !FrameIndexExprs.empty(); + } + + const DIType *getType() const; + + static bool classof(const DbgEntity *N) { + return N->getDbgEntityID() == DbgVariableKind; + } +}; + +//===----------------------------------------------------------------------===// +/// This class is used to track label information. +/// +/// Labels are collected from \c DBG_LABEL instructions. +class DbgLabel : public DbgEntity { + const MCSymbol *Sym; /// Symbol before DBG_LABEL instruction. + +public: + /// We need MCSymbol information to generate DW_AT_low_pc. + DbgLabel(const DILabel *L, const DILocation *IA, const MCSymbol *Sym = nullptr) + : DbgEntity(L, IA, DbgLabelKind), Sym(Sym) {} + + /// Accessors. + /// @{ + const DILabel *getLabel() const { return cast<DILabel>(getEntity()); } + const MCSymbol *getSymbol() const { return Sym; } + + StringRef getName() const { return getLabel()->getName(); } + /// @} + + /// Translate tag to proper Dwarf tag. + dwarf::Tag getTag() const { + return dwarf::DW_TAG_label; + } + + static bool classof(const DbgEntity *N) { + return N->getDbgEntityID() == DbgLabelKind; + } +}; + +/// Used for tracking debug info about call site parameters. +class DbgCallSiteParam { +private: + unsigned Register; ///< Parameter register at the callee entry point. + DbgValueLoc Value; ///< Corresponding location for the parameter value at + ///< the call site. +public: + DbgCallSiteParam(unsigned Reg, DbgValueLoc Val) + : Register(Reg), Value(Val) { + assert(Reg && "Parameter register cannot be undef"); + } + + unsigned getRegister() const { return Register; } + DbgValueLoc getValue() const { return Value; } +}; + +/// Collection used for storing debug call site parameters. +using ParamSet = SmallVector<DbgCallSiteParam, 4>; + +/// Helper used to pair up a symbol and its DWARF compile unit. +struct SymbolCU { + SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {} + + const MCSymbol *Sym; + DwarfCompileUnit *CU; +}; + +/// The kind of accelerator tables we should emit. +enum class AccelTableKind { + Default, ///< Platform default. + None, ///< None. + Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc. + Dwarf, ///< DWARF v5 .debug_names. +}; + +/// Collects and handles dwarf debug information. +class DwarfDebug : public DebugHandlerBase { + /// All DIEValues are allocated through this allocator. + BumpPtrAllocator DIEValueAllocator; + + /// Maps MDNode with its corresponding DwarfCompileUnit. + MapVector<const MDNode *, DwarfCompileUnit *> CUMap; + + /// Maps a CU DIE with its corresponding DwarfCompileUnit. + DenseMap<const DIE *, DwarfCompileUnit *> CUDieMap; + + /// List of all labels used in aranges generation. + std::vector<SymbolCU> ArangeLabels; + + /// Size of each symbol emitted (for those symbols that have a specific size). + DenseMap<const MCSymbol *, uint64_t> SymSize; + + /// Collection of abstract variables/labels. + SmallVector<std::unique_ptr<DbgEntity>, 64> ConcreteEntities; + + /// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists + /// can refer to them in spite of insertions into this list. + DebugLocStream DebugLocs; + + /// This is a collection of subprogram MDNodes that are processed to + /// create DIEs. + SetVector<const DISubprogram *, SmallVector<const DISubprogram *, 16>, + SmallPtrSet<const DISubprogram *, 16>> + ProcessedSPNodes; + + /// If nonnull, stores the current machine function we're processing. + const MachineFunction *CurFn = nullptr; + + /// If nonnull, stores the CU in which the previous subprogram was contained. + const DwarfCompileUnit *PrevCU; + + /// As an optimization, there is no need to emit an entry in the directory + /// table for the same directory as DW_AT_comp_dir. + StringRef CompilationDir; + + /// Holder for the file specific debug information. + DwarfFile InfoHolder; + + /// Holders for the various debug information flags that we might need to + /// have exposed. See accessor functions below for description. + + /// Map from MDNodes for user-defined types to their type signatures. Also + /// used to keep track of which types we have emitted type units for. + DenseMap<const MDNode *, uint64_t> TypeSignatures; + + DenseMap<const MCSection *, const MCSymbol *> SectionLabels; + + SmallVector< + std::pair<std::unique_ptr<DwarfTypeUnit>, const DICompositeType *>, 1> + TypeUnitsUnderConstruction; + + /// Whether to use the GNU TLS opcode (instead of the standard opcode). + bool UseGNUTLSOpcode; + + /// Whether to use DWARF 2 bitfields (instead of the DWARF 4 format). + bool UseDWARF2Bitfields; + + /// Whether to emit all linkage names, or just abstract subprograms. + bool UseAllLinkageNames; + + /// Use inlined strings. + bool UseInlineStrings = false; + + /// Allow emission of .debug_ranges section. + bool UseRangesSection = true; + + /// True if the sections itself must be used as references and don't create + /// temp symbols inside DWARF sections. + bool UseSectionsAsReferences = false; + + ///Allow emission of the .debug_loc section. + bool UseLocSection = true; + + /// Generate DWARF v4 type units. + bool GenerateTypeUnits; + + /// DWARF5 Experimental Options + /// @{ + AccelTableKind TheAccelTableKind; + bool HasAppleExtensionAttributes; + bool HasSplitDwarf; + + /// Whether to generate the DWARF v5 string offsets table. + /// It consists of a series of contributions, each preceded by a header. + /// The pre-DWARF v5 string offsets table for split dwarf is, in contrast, + /// a monolithic sequence of string offsets. + bool UseSegmentedStringOffsetsTable; + + /// Separated Dwarf Variables + /// In general these will all be for bits that are left in the + /// original object file, rather than things that are meant + /// to be in the .dwo sections. + + /// Holder for the skeleton information. + DwarfFile SkeletonHolder; + + /// Store file names for type units under fission in a line table + /// header that will be emitted into debug_line.dwo. + // FIXME: replace this with a map from comp_dir to table so that we + // can emit multiple tables during LTO each of which uses directory + // 0, referencing the comp_dir of all the type units that use it. + MCDwarfDwoLineTable SplitTypeUnitFileTable; + /// @} + + /// True iff there are multiple CUs in this module. + bool SingleCU; + bool IsDarwin; + + AddressPool AddrPool; + + /// Accelerator tables. + AccelTable<DWARF5AccelTableData> AccelDebugNames; + AccelTable<AppleAccelTableOffsetData> AccelNames; + AccelTable<AppleAccelTableOffsetData> AccelObjC; + AccelTable<AppleAccelTableOffsetData> AccelNamespace; + AccelTable<AppleAccelTableTypeData> AccelTypes; + + // Identify a debugger for "tuning" the debug info. + DebuggerKind DebuggerTuning = DebuggerKind::Default; + + MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); + + const SmallVectorImpl<std::unique_ptr<DwarfCompileUnit>> &getUnits() { + return InfoHolder.getUnits(); + } + + using InlinedEntity = DbgValueHistoryMap::InlinedEntity; + + void ensureAbstractEntityIsCreated(DwarfCompileUnit &CU, + const DINode *Node, + const MDNode *Scope); + void ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU, + const DINode *Node, + const MDNode *Scope); + + DbgEntity *createConcreteEntity(DwarfCompileUnit &TheCU, + LexicalScope &Scope, + const DINode *Node, + const DILocation *Location, + const MCSymbol *Sym = nullptr); + + /// Construct a DIE for this abstract scope. + void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope); + + /// Construct DIEs for call site entries describing the calls in \p MF. + void constructCallSiteEntryDIEs(const DISubprogram &SP, DwarfCompileUnit &CU, + DIE &ScopeDIE, const MachineFunction &MF); + + template <typename DataT> + void addAccelNameImpl(const DICompileUnit &CU, AccelTable<DataT> &AppleAccel, + StringRef Name, const DIE &Die); + + void finishEntityDefinitions(); + + void finishSubprogramDefinitions(); + + /// Finish off debug information after all functions have been + /// processed. + void finalizeModuleInfo(); + + /// Emit the debug info section. + void emitDebugInfo(); + + /// Emit the abbreviation section. + void emitAbbreviations(); + + /// Emit the string offsets table header. + void emitStringOffsetsTableHeader(); + + /// Emit a specified accelerator table. + template <typename AccelTableT> + void emitAccel(AccelTableT &Accel, MCSection *Section, StringRef TableName); + + /// Emit DWARF v5 accelerator table. + void emitAccelDebugNames(); + + /// Emit visible names into a hashed accelerator table section. + void emitAccelNames(); + + /// Emit objective C classes and categories into a hashed + /// accelerator table section. + void emitAccelObjC(); + + /// Emit namespace dies into a hashed accelerator table. + void emitAccelNamespaces(); + + /// Emit type dies into a hashed accelerator table. + void emitAccelTypes(); + + /// Emit visible names and types into debug pubnames and pubtypes sections. + void emitDebugPubSections(); + + void emitDebugPubSection(bool GnuStyle, StringRef Name, + DwarfCompileUnit *TheU, + const StringMap<const DIE *> &Globals); + + /// Emit null-terminated strings into a debug str section. + void emitDebugStr(); + + /// Emit variable locations into a debug loc section. + void emitDebugLoc(); + + /// Emit variable locations into a debug loc dwo section. + void emitDebugLocDWO(); + + /// Emit address ranges into a debug aranges section. + void emitDebugARanges(); + + /// Emit address ranges into a debug ranges section. + void emitDebugRanges(); + void emitDebugRangesDWO(); + + /// Emit macros into a debug macinfo section. + void emitDebugMacinfo(); + void emitMacro(DIMacro &M); + void emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U); + void handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U); + + /// DWARF 5 Experimental Split Dwarf Emitters + + /// Initialize common features of skeleton units. + void initSkeletonUnit(const DwarfUnit &U, DIE &Die, + std::unique_ptr<DwarfCompileUnit> NewU); + + /// Construct the split debug info compile unit for the debug info section. + /// In DWARF v5, the skeleton unit DIE may have the following attributes: + /// DW_AT_addr_base, DW_AT_comp_dir, DW_AT_dwo_name, DW_AT_high_pc, + /// DW_AT_low_pc, DW_AT_ranges, DW_AT_stmt_list, and DW_AT_str_offsets_base. + /// Prior to DWARF v5 it may also have DW_AT_GNU_dwo_id. DW_AT_GNU_dwo_name + /// is used instead of DW_AT_dwo_name, Dw_AT_GNU_addr_base instead of + /// DW_AT_addr_base, and DW_AT_GNU_ranges_base instead of DW_AT_rnglists_base. + DwarfCompileUnit &constructSkeletonCU(const DwarfCompileUnit &CU); + + /// Emit the debug info dwo section. + void emitDebugInfoDWO(); + + /// Emit the debug abbrev dwo section. + void emitDebugAbbrevDWO(); + + /// Emit the debug line dwo section. + void emitDebugLineDWO(); + + /// Emit the dwo stringoffsets table header. + void emitStringOffsetsTableHeaderDWO(); + + /// Emit the debug str dwo section. + void emitDebugStrDWO(); + + /// Emit DWO addresses. + void emitDebugAddr(); + + /// Flags to let the linker know we have emitted new style pubnames. Only + /// emit it here if we don't have a skeleton CU for split dwarf. + void addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const; + + /// Create new DwarfCompileUnit for the given metadata node with tag + /// DW_TAG_compile_unit. + DwarfCompileUnit &getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit); + void finishUnitAttributes(const DICompileUnit *DIUnit, + DwarfCompileUnit &NewCU); + + /// Construct imported_module or imported_declaration DIE. + void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, + const DIImportedEntity *N); + + /// Register a source line with debug info. Returns the unique + /// label that was emitted and which provides correspondence to the + /// source line list. + void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope, + unsigned Flags); + + /// Populate LexicalScope entries with variables' info. + void collectEntityInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, + DenseSet<InlinedEntity> &ProcessedVars); + + /// Build the location list for all DBG_VALUEs in the + /// function that describe the same variable. If the resulting + /// list has only one entry that is valid for entire variable's + /// scope return true. + bool buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc, + const DbgValueHistoryMap::Entries &Entries); + + /// Collect variable information from the side table maintained by MF. + void collectVariableInfoFromMFTable(DwarfCompileUnit &TheCU, + DenseSet<InlinedEntity> &P); + + /// Emit the reference to the section. + void emitSectionReference(const DwarfCompileUnit &CU); + +protected: + /// Gather pre-function debug information. + void beginFunctionImpl(const MachineFunction *MF) override; + + /// Gather and emit post-function debug information. + void endFunctionImpl(const MachineFunction *MF) override; + + void skippedNonDebugFunction() override; + +public: + //===--------------------------------------------------------------------===// + // Main entry points. + // + DwarfDebug(AsmPrinter *A, Module *M); + + ~DwarfDebug() override; + + /// Emit all Dwarf sections that should come prior to the + /// content. + void beginModule(); + + /// Emit all Dwarf sections that should come after the content. + void endModule() override; + + /// Emits inital debug location directive. + DebugLoc emitInitialLocDirective(const MachineFunction &MF, unsigned CUID); + + /// Process beginning of an instruction. + void beginInstruction(const MachineInstr *MI) override; + + /// Perform an MD5 checksum of \p Identifier and return the lower 64 bits. + static uint64_t makeTypeSignature(StringRef Identifier); + + /// Add a DIE to the set of types that we're going to pull into + /// type units. + void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, + DIE &Die, const DICompositeType *CTy); + + friend class NonTypeUnitContext; + class NonTypeUnitContext { + DwarfDebug *DD; + decltype(DwarfDebug::TypeUnitsUnderConstruction) TypeUnitsUnderConstruction; + friend class DwarfDebug; + NonTypeUnitContext(DwarfDebug *DD); + public: + NonTypeUnitContext(NonTypeUnitContext&&) = default; + ~NonTypeUnitContext(); + }; + + NonTypeUnitContext enterNonTypeUnitContext(); + + /// Add a label so that arange data can be generated for it. + void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); } + + /// For symbols that have a size designated (e.g. common symbols), + /// this tracks that size. + void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override { + SymSize[Sym] = Size; + } + + /// Returns whether we should emit all DW_AT_[MIPS_]linkage_name. + /// If not, we still might emit certain cases. + bool useAllLinkageNames() const { return UseAllLinkageNames; } + + /// Returns whether to use DW_OP_GNU_push_tls_address, instead of the + /// standard DW_OP_form_tls_address opcode + bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; } + + /// Returns whether to use the DWARF2 format for bitfields instyead of the + /// DWARF4 format. + bool useDWARF2Bitfields() const { return UseDWARF2Bitfields; } + + /// Returns whether to use inline strings. + bool useInlineStrings() const { return UseInlineStrings; } + + /// Returns whether ranges section should be emitted. + bool useRangesSection() const { return UseRangesSection; } + + /// Returns whether to use sections as labels rather than temp symbols. + bool useSectionsAsReferences() const { + return UseSectionsAsReferences; + } + + /// Returns whether .debug_loc section should be emitted. + bool useLocSection() const { return UseLocSection; } + + /// Returns whether to generate DWARF v4 type units. + bool generateTypeUnits() const { return GenerateTypeUnits; } + + // Experimental DWARF5 features. + + /// Returns what kind (if any) of accelerator tables to emit. + AccelTableKind getAccelTableKind() const { return TheAccelTableKind; } + + bool useAppleExtensionAttributes() const { + return HasAppleExtensionAttributes; + } + + /// Returns whether or not to change the current debug info for the + /// split dwarf proposal support. + bool useSplitDwarf() const { return HasSplitDwarf; } + + /// Returns whether to generate a string offsets table with (possibly shared) + /// contributions from each CU and type unit. This implies the use of + /// DW_FORM_strx* indirect references with DWARF v5 and beyond. Note that + /// DW_FORM_GNU_str_index is also an indirect reference, but it is used with + /// a pre-DWARF v5 implementation of split DWARF sections, which uses a + /// monolithic string offsets table. + bool useSegmentedStringOffsetsTable() const { + return UseSegmentedStringOffsetsTable; + } + + bool shareAcrossDWOCUs() const; + + /// Returns the Dwarf Version. + uint16_t getDwarfVersion() const; + + /// Returns the previous CU that was being updated + const DwarfCompileUnit *getPrevCU() const { return PrevCU; } + void setPrevCU(const DwarfCompileUnit *PrevCU) { this->PrevCU = PrevCU; } + + /// Returns the entries for the .debug_loc section. + const DebugLocStream &getDebugLocs() const { return DebugLocs; } + + /// Emit an entry for the debug loc section. This can be used to + /// handle an entry that's going to be emitted into the debug loc section. + void emitDebugLocEntry(ByteStreamer &Streamer, + const DebugLocStream::Entry &Entry, + const DwarfCompileUnit *CU); + + /// Emit the location for a debug loc entry, including the size header. + void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, + const DwarfCompileUnit *CU); + + void addSubprogramNames(const DICompileUnit &CU, const DISubprogram *SP, + DIE &Die); + + AddressPool &getAddressPool() { return AddrPool; } + + void addAccelName(const DICompileUnit &CU, StringRef Name, const DIE &Die); + + void addAccelObjC(const DICompileUnit &CU, StringRef Name, const DIE &Die); + + void addAccelNamespace(const DICompileUnit &CU, StringRef Name, + const DIE &Die); + + void addAccelType(const DICompileUnit &CU, StringRef Name, const DIE &Die, + char Flags); + + const MachineFunction *getCurrentFunction() const { return CurFn; } + + /// A helper function to check whether the DIE for a given Scope is + /// going to be null. + bool isLexicalScopeDIENull(LexicalScope *Scope); + + /// Find the matching DwarfCompileUnit for the given CU DIE. + DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); } + const DwarfCompileUnit *lookupCU(const DIE *Die) const { + return CUDieMap.lookup(Die); + } + + /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger. + /// + /// Returns whether we are "tuning" for a given debugger. + /// @{ + bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; } + bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } + bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } + /// @} + + void addSectionLabel(const MCSymbol *Sym); + const MCSymbol *getSectionLabel(const MCSection *S); + + static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, + const DbgValueLoc &Value, + DwarfExpression &DwarfExpr); +}; + +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H |