[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / include / llvm / DebugInfo / DIContext.h
blobd2a5318179eb6d61cf3a6ad612008fd2c23817d5
1 //===- DIContext.h ----------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines DIContext, an abstract data structure that holds
10 // debug information data.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_DEBUGINFO_DICONTEXT_H
15 #define LLVM_DEBUGINFO_DICONTEXT_H
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/Object/ObjectFile.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include <cassert>
21 #include <cstdint>
22 #include <memory>
23 #include <string>
24 #include <tuple>
25 #include <utility>
27 namespace llvm {
29 /// A format-neutral container for source line information.
30 struct DILineInfo {
31 std::string FileName;
32 std::string FunctionName;
33 Optional<StringRef> Source;
34 uint32_t Line = 0;
35 uint32_t Column = 0;
36 uint32_t StartLine = 0;
38 // DWARF-specific.
39 uint32_t Discriminator = 0;
41 DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {}
43 bool operator==(const DILineInfo &RHS) const {
44 return Line == RHS.Line && Column == RHS.Column &&
45 FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
46 StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
49 bool operator!=(const DILineInfo &RHS) const {
50 return !(*this == RHS);
53 bool operator<(const DILineInfo &RHS) const {
54 return std::tie(FileName, FunctionName, Line, Column, StartLine,
55 Discriminator) <
56 std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
57 RHS.StartLine, RHS.Discriminator);
60 explicit operator bool() const { return *this != DILineInfo(); }
62 void dump(raw_ostream &OS) {
63 OS << "Line info: ";
64 if (FileName != "<invalid>")
65 OS << "file '" << FileName << "', ";
66 if (FunctionName != "<invalid>")
67 OS << "function '" << FunctionName << "', ";
68 OS << "line " << Line << ", ";
69 OS << "column " << Column << ", ";
70 OS << "start line " << StartLine << '\n';
74 using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
76 /// A format-neutral container for inlined code description.
77 class DIInliningInfo {
78 SmallVector<DILineInfo, 4> Frames;
80 public:
81 DIInliningInfo() = default;
83 const DILineInfo & getFrame(unsigned Index) const {
84 assert(Index < Frames.size());
85 return Frames[Index];
88 DILineInfo *getMutableFrame(unsigned Index) {
89 assert(Index < Frames.size());
90 return &Frames[Index];
93 uint32_t getNumberOfFrames() const {
94 return Frames.size();
97 void addFrame(const DILineInfo &Frame) {
98 Frames.push_back(Frame);
101 void resize(unsigned i) {
102 Frames.resize(i);
106 /// Container for description of a global variable.
107 struct DIGlobal {
108 std::string Name;
109 uint64_t Start = 0;
110 uint64_t Size = 0;
112 DIGlobal() : Name("<invalid>") {}
115 struct DILocal {
116 std::string FunctionName;
117 std::string Name;
118 std::string DeclFile;
119 uint64_t DeclLine = 0;
120 Optional<int64_t> FrameOffset;
121 Optional<uint64_t> Size;
122 Optional<uint64_t> TagOffset;
125 /// A DINameKind is passed to name search methods to specify a
126 /// preference regarding the type of name resolution the caller wants.
127 enum class DINameKind { None, ShortName, LinkageName };
129 /// Controls which fields of DILineInfo container should be filled
130 /// with data.
131 struct DILineInfoSpecifier {
132 enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
133 using FunctionNameKind = DINameKind;
135 FileLineInfoKind FLIKind;
136 FunctionNameKind FNKind;
138 DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
139 FunctionNameKind FNKind = FunctionNameKind::None)
140 : FLIKind(FLIKind), FNKind(FNKind) {}
143 /// This is just a helper to programmatically construct DIDumpType.
144 enum DIDumpTypeCounter {
145 #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
146 DIDT_ID_##ENUM_NAME,
147 #include "llvm/BinaryFormat/Dwarf.def"
148 #undef HANDLE_DWARF_SECTION
149 DIDT_ID_UUID,
150 DIDT_ID_Count
152 static_assert(DIDT_ID_Count <= 32, "section types overflow storage");
154 /// Selects which debug sections get dumped.
155 enum DIDumpType : unsigned {
156 DIDT_Null,
157 DIDT_All = ~0U,
158 #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
159 DIDT_##ENUM_NAME = 1U << DIDT_ID_##ENUM_NAME,
160 #include "llvm/BinaryFormat/Dwarf.def"
161 #undef HANDLE_DWARF_SECTION
162 DIDT_UUID = 1 << DIDT_ID_UUID,
165 /// Container for dump options that control which debug information will be
166 /// dumped.
167 struct DIDumpOptions {
168 unsigned DumpType = DIDT_All;
169 unsigned ChildRecurseDepth = -1U;
170 unsigned ParentRecurseDepth = -1U;
171 uint16_t Version = 0; // DWARF version to assume when extracting.
172 uint8_t AddrSize = 4; // Address byte size to assume when extracting.
173 bool ShowAddresses = true;
174 bool ShowChildren = false;
175 bool ShowParents = false;
176 bool ShowForm = false;
177 bool SummarizeTypes = false;
178 bool Verbose = false;
179 bool DisplayRawContents = false;
181 /// Return default option set for printing a single DIE without children.
182 static DIDumpOptions getForSingleDIE() {
183 DIDumpOptions Opts;
184 Opts.ChildRecurseDepth = 0;
185 Opts.ParentRecurseDepth = 0;
186 return Opts;
189 /// Return the options with RecurseDepth set to 0 unless explicitly required.
190 DIDumpOptions noImplicitRecursion() const {
191 DIDumpOptions Opts = *this;
192 if (ChildRecurseDepth == -1U && !ShowChildren)
193 Opts.ChildRecurseDepth = 0;
194 if (ParentRecurseDepth == -1U && !ShowParents)
195 Opts.ParentRecurseDepth = 0;
196 return Opts;
200 class DIContext {
201 public:
202 enum DIContextKind {
203 CK_DWARF,
204 CK_PDB
207 DIContext(DIContextKind K) : Kind(K) {}
208 virtual ~DIContext() = default;
210 DIContextKind getKind() const { return Kind; }
212 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
214 virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
215 // No verifier? Just say things went well.
216 return true;
219 virtual DILineInfo getLineInfoForAddress(
220 object::SectionedAddress Address,
221 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
222 virtual DILineInfoTable getLineInfoForAddressRange(
223 object::SectionedAddress Address, uint64_t Size,
224 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
225 virtual DIInliningInfo getInliningInfoForAddress(
226 object::SectionedAddress Address,
227 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
229 virtual std::vector<DILocal>
230 getLocalsForAddress(object::SectionedAddress Address) = 0;
232 private:
233 const DIContextKind Kind;
236 /// An inferface for inquiring the load address of a loaded object file
237 /// to be used by the DIContext implementations when applying relocations
238 /// on the fly.
239 class LoadedObjectInfo {
240 protected:
241 LoadedObjectInfo() = default;
242 LoadedObjectInfo(const LoadedObjectInfo &) = default;
244 public:
245 virtual ~LoadedObjectInfo() = default;
247 /// Obtain the Load Address of a section by SectionRef.
249 /// Calculate the address of the given section.
250 /// The section need not be present in the local address space. The addresses
251 /// need to be consistent with the addresses used to query the DIContext and
252 /// the output of this function should be deterministic, i.e. repeated calls
253 /// with the same Sec should give the same address.
254 virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const {
255 return 0;
258 /// If conveniently available, return the content of the given Section.
260 /// When the section is available in the local address space, in relocated
261 /// (loaded) form, e.g. because it was relocated by a JIT for execution, this
262 /// function should provide the contents of said section in `Data`. If the
263 /// loaded section is not available, or the cost of retrieving it would be
264 /// prohibitive, this function should return false. In that case, relocations
265 /// will be read from the local (unrelocated) object file and applied on the
266 /// fly. Note that this method is used purely for optimzation purposes in the
267 /// common case of JITting in the local address space, so returning false
268 /// should always be correct.
269 virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
270 StringRef &Data) const {
271 return false;
274 // FIXME: This is untested and unused anywhere in the LLVM project, it's
275 // used/needed by Julia (an external project). It should have some coverage
276 // (at least tests, but ideally example functionality).
277 /// Obtain a copy of this LoadedObjectInfo.
278 virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
281 template <typename Derived, typename Base = LoadedObjectInfo>
282 struct LoadedObjectInfoHelper : Base {
283 protected:
284 LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
285 LoadedObjectInfoHelper() = default;
287 public:
288 template <typename... Ts>
289 LoadedObjectInfoHelper(Ts &&... Args) : Base(std::forward<Ts>(Args)...) {}
291 std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
292 return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
296 } // end namespace llvm
298 #endif // LLVM_DEBUGINFO_DICONTEXT_H