1 //===- DIContext.h ----------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines DIContext, an abstract data structure that holds
11 // debug information data.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_DEBUGINFO_DICONTEXT_H
16 #define LLVM_DEBUGINFO_DICONTEXT_H
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Object/ObjectFile.h"
31 /// DILineInfo - a format-neutral container for source line information.
34 std::string FunctionName;
37 uint32_t StartLine = 0;
40 uint32_t Discriminator = 0;
42 DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {}
44 bool operator==(const DILineInfo &RHS) const {
45 return Line == RHS.Line && Column == RHS.Column &&
46 FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
47 StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
49 bool operator!=(const DILineInfo &RHS) const {
50 return !(*this == RHS);
52 bool operator<(const DILineInfo &RHS) const {
53 return std::tie(FileName, FunctionName, Line, Column, StartLine,
55 std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
56 RHS.StartLine, RHS.Discriminator);
60 using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
62 /// DIInliningInfo - a format-neutral container for inlined code description.
63 class DIInliningInfo {
64 SmallVector<DILineInfo, 4> Frames;
67 DIInliningInfo() = default;
69 DILineInfo getFrame(unsigned Index) const {
70 assert(Index < Frames.size());
74 DILineInfo *getMutableFrame(unsigned Index) {
75 assert(Index < Frames.size());
76 return &Frames[Index];
79 uint32_t getNumberOfFrames() const {
83 void addFrame(const DILineInfo &Frame) {
84 Frames.push_back(Frame);
88 /// DIGlobal - container for description of a global variable.
94 DIGlobal() : Name("<invalid>") {}
97 /// A DINameKind is passed to name search methods to specify a
98 /// preference regarding the type of name resolution the caller wants.
99 enum class DINameKind { None, ShortName, LinkageName };
101 /// DILineInfoSpecifier - controls which fields of DILineInfo container
102 /// should be filled with data.
103 struct DILineInfoSpecifier {
104 enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
105 using FunctionNameKind = DINameKind;
107 FileLineInfoKind FLIKind;
108 FunctionNameKind FNKind;
110 DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
111 FunctionNameKind FNKind = FunctionNameKind::None)
112 : FLIKind(FLIKind), FNKind(FNKind) {}
115 /// Selects which debug sections get dumped.
143 DIDT_AppleNamespaces,
150 /// Container for dump options that control which debug information will be
152 struct DIDumpOptions {
153 DIDumpType DumpType = DIDT_All;
155 bool SummarizeTypes = false;
166 DIContext(DIContextKind K) : Kind(K) {}
167 virtual ~DIContext() = default;
169 DIContextKind getKind() const { return Kind; }
171 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
173 virtual bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) {
174 // No verifier? Just say things went well.
178 virtual DILineInfo getLineInfoForAddress(uint64_t Address,
179 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
180 virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
181 uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
182 virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
183 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
186 const DIContextKind Kind;
189 /// An inferface for inquiring the load address of a loaded object file
190 /// to be used by the DIContext implementations when applying relocations
192 class LoadedObjectInfo {
194 LoadedObjectInfo() = default;
195 LoadedObjectInfo(const LoadedObjectInfo &) = default;
198 virtual ~LoadedObjectInfo() = default;
200 /// Obtain the Load Address of a section by SectionRef.
202 /// Calculate the address of the given section.
203 /// The section need not be present in the local address space. The addresses
204 /// need to be consistent with the addresses used to query the DIContext and
205 /// the output of this function should be deterministic, i.e. repeated calls with
206 /// the same Sec should give the same address.
207 virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const {
211 /// If conveniently available, return the content of the given Section.
213 /// When the section is available in the local address space, in relocated (loaded)
214 /// form, e.g. because it was relocated by a JIT for execution, this function
215 /// should provide the contents of said section in `Data`. If the loaded section
216 /// is not available, or the cost of retrieving it would be prohibitive, this
217 /// function should return false. In that case, relocations will be read from the
218 /// local (unrelocated) object file and applied on the fly. Note that this method
219 /// is used purely for optimzation purposes in the common case of JITting in the
220 /// local address space, so returning false should always be correct.
221 virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
222 StringRef &Data) const {
226 // FIXME: This is untested and unused anywhere in the LLVM project, it's
227 // used/needed by Julia (an external project). It should have some coverage
228 // (at least tests, but ideally example functionality).
229 /// Obtain a copy of this LoadedObjectInfo.
230 virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
233 template <typename Derived, typename Base = LoadedObjectInfo>
234 struct LoadedObjectInfoHelper : Base {
236 LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
237 LoadedObjectInfoHelper() = default;
240 template <typename... Ts>
241 LoadedObjectInfoHelper(Ts &&... Args) : Base(std::forward<Ts>(Args)...) {}
243 std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
244 return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
248 } // end namespace llvm
250 #endif // LLVM_DEBUGINFO_DICONTEXT_H