diff options
Diffstat (limited to 'include/llvm/DebugInfo/DIContext.h')
| -rw-r--r-- | include/llvm/DebugInfo/DIContext.h | 127 |
1 files changed, 74 insertions, 53 deletions
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 936813dc6abc..abace9378607 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdint> #include <memory> @@ -26,9 +27,7 @@ namespace llvm { -class raw_ostream; - -/// DILineInfo - a format-neutral container for source line information. +/// A format-neutral container for source line information. struct DILineInfo { std::string FileName; std::string FunctionName; @@ -46,20 +45,35 @@ struct DILineInfo { FileName == RHS.FileName && FunctionName == RHS.FunctionName && StartLine == RHS.StartLine && Discriminator == RHS.Discriminator; } + bool operator!=(const DILineInfo &RHS) const { return !(*this == RHS); } + bool operator<(const DILineInfo &RHS) const { return std::tie(FileName, FunctionName, Line, Column, StartLine, Discriminator) < std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column, RHS.StartLine, RHS.Discriminator); } + + explicit operator bool() const { return *this != DILineInfo(); } + + void dump(raw_ostream &OS) { + OS << "Line info: "; + if (FileName != "<invalid>") + OS << "file '" << FileName << "', "; + if (FunctionName != "<invalid>") + OS << "function '" << FunctionName << "', "; + OS << "line " << Line << ", "; + OS << "column " << Column << ", "; + OS << "start line " << StartLine << '\n'; + } }; using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>; -/// DIInliningInfo - a format-neutral container for inlined code description. +/// A format-neutral container for inlined code description. class DIInliningInfo { SmallVector<DILineInfo, 4> Frames; @@ -85,7 +99,7 @@ public: } }; -/// DIGlobal - container for description of a global variable. +/// Container for description of a global variable. struct DIGlobal { std::string Name; uint64_t Start = 0; @@ -98,8 +112,8 @@ struct DIGlobal { /// preference regarding the type of name resolution the caller wants. enum class DINameKind { None, ShortName, LinkageName }; -/// DILineInfoSpecifier - controls which fields of DILineInfo container -/// should be filled with data. +/// Controls which fields of DILineInfo container should be filled +/// with data. struct DILineInfoSpecifier { enum class FileLineInfoKind { None, Default, AbsoluteFilePath }; using FunctionNameKind = DINameKind; @@ -112,48 +126,54 @@ struct DILineInfoSpecifier { : FLIKind(FLIKind), FNKind(FNKind) {} }; +/// This is just a helper to programmatically construct DIDumpType. +enum DIDumpTypeCounter { +#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \ + DIDT_ID_##ENUM_NAME, +#include "llvm/BinaryFormat/Dwarf.def" +#undef HANDLE_DWARF_SECTION + DIDT_ID_UUID, + DIDT_ID_Count +}; +static_assert(DIDT_ID_Count <= 32, "section types overflow storage"); + /// Selects which debug sections get dumped. -enum DIDumpType { +enum DIDumpType : unsigned { DIDT_Null, - DIDT_All, - DIDT_Abbrev, - DIDT_AbbrevDwo, - DIDT_Aranges, - DIDT_Frames, - DIDT_Info, - DIDT_InfoDwo, - DIDT_Types, - DIDT_TypesDwo, - DIDT_Line, - DIDT_LineDwo, - DIDT_Loc, - DIDT_LocDwo, - DIDT_Macro, - DIDT_Ranges, - DIDT_Pubnames, - DIDT_Pubtypes, - DIDT_GnuPubnames, - DIDT_GnuPubtypes, - DIDT_Str, - DIDT_StrOffsets, - DIDT_StrDwo, - DIDT_StrOffsetsDwo, - DIDT_AppleNames, - DIDT_AppleTypes, - DIDT_AppleNamespaces, - DIDT_AppleObjC, - DIDT_CUIndex, - DIDT_GdbIndex, - DIDT_TUIndex, + DIDT_All = ~0U, +#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \ + DIDT_##ENUM_NAME = 1U << DIDT_ID_##ENUM_NAME, +#include "llvm/BinaryFormat/Dwarf.def" +#undef HANDLE_DWARF_SECTION + DIDT_UUID = 1 << DIDT_ID_UUID, }; /// Container for dump options that control which debug information will be /// dumped. struct DIDumpOptions { - DIDumpType DumpType = DIDT_All; - bool DumpEH = false; - bool SummarizeTypes = false; - bool Brief = false; + unsigned DumpType = DIDT_All; + unsigned RecurseDepth = -1U; + bool ShowAddresses = true; + bool ShowChildren = false; + bool ShowParents = false; + bool ShowForm = false; + bool SummarizeTypes = false; + bool Verbose = false; + + /// Return default option set for printing a single DIE without children. + static DIDumpOptions getForSingleDIE() { + DIDumpOptions Opts; + Opts.RecurseDepth = 0; + return Opts; + } + + /// Return the options with RecurseDepth set to 0 unless explicitly required. + DIDumpOptions noImplicitRecursion() const { + DIDumpOptions Opts = *this; + if (RecurseDepth == -1U && !ShowChildren) + Opts.RecurseDepth = 0; + return Opts; + } }; class DIContext { @@ -170,7 +190,7 @@ public: virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0; - virtual bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) { + virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) { // No verifier? Just say things went well. return true; } @@ -202,22 +222,23 @@ public: /// Calculate the address of the given section. /// The section need not be present in the local address space. The addresses /// need to be consistent with the addresses used to query the DIContext and - /// the output of this function should be deterministic, i.e. repeated calls with - /// the same Sec should give the same address. + /// the output of this function should be deterministic, i.e. repeated calls + /// with the same Sec should give the same address. virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const { return 0; } /// If conveniently available, return the content of the given Section. /// - /// When the section is available in the local address space, in relocated (loaded) - /// form, e.g. because it was relocated by a JIT for execution, this function - /// should provide the contents of said section in `Data`. If the loaded section - /// is not available, or the cost of retrieving it would be prohibitive, this - /// function should return false. In that case, relocations will be read from the - /// local (unrelocated) object file and applied on the fly. Note that this method - /// is used purely for optimzation purposes in the common case of JITting in the - /// local address space, so returning false should always be correct. + /// When the section is available in the local address space, in relocated + /// (loaded) form, e.g. because it was relocated by a JIT for execution, this + /// function should provide the contents of said section in `Data`. If the + /// loaded section is not available, or the cost of retrieving it would be + /// prohibitive, this function should return false. In that case, relocations + /// will be read from the local (unrelocated) object file and applied on the + /// fly. Note that this method is used purely for optimzation purposes in the + /// common case of JITting in the local address space, so returning false + /// should always be correct. virtual bool getLoadedSectionContents(const object::SectionRef &Sec, StringRef &Data) const { return false; |
