1//===-- LVObject.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 the LVObject class, which is used to describe a debug
10// information object.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
15#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
16
17#include "llvm/BinaryFormat/Dwarf.h"
18#include "llvm/DebugInfo/CodeView/CodeView.h"
19#include "llvm/DebugInfo/CodeView/TypeIndex.h"
20#include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
21#include <limits>
22#include <list>
23#include <string>
24
25namespace llvm {
26namespace dwarf {
27// Support for CodeView ModifierOptions::Unaligned.
28constexpr Tag DW_TAG_unaligned = Tag(dwarf::DW_TAG_hi_user + 1);
29} // namespace dwarf
30} // namespace llvm
31
32namespace llvm {
33namespace logicalview {
34
35using LVSectionIndex = uint64_t;
36using LVAddress = uint64_t;
37using LVHalf = uint16_t;
38using LVLevel = uint32_t;
39using LVOffset = uint64_t;
40using LVSigned = int64_t;
41using LVUnsigned = uint64_t;
42using LVSmall = uint8_t;
43
44class LVElement;
45class LVLine;
46class LVLocation;
47class LVLocationSymbol;
48class LVObject;
49class LVOperation;
50class LVScope;
51class LVSymbol;
52class LVType;
53
54class LVOptions;
55class LVPatterns;
56
57StringRef typeNone();
58StringRef typeVoid();
59StringRef typeInt();
60StringRef typeUnknown();
61StringRef emptyString();
62
63using LVElementSetFunction = void (LVElement::*)();
64using LVElementGetFunction = bool (LVElement::*)() const;
65using LVLineSetFunction = void (LVLine::*)();
66using LVLineGetFunction = bool (LVLine::*)() const;
67using LVObjectSetFunction = void (LVObject::*)();
68using LVObjectGetFunction = bool (LVObject::*)() const;
69using LVScopeSetFunction = void (LVScope::*)();
70using LVScopeGetFunction = bool (LVScope::*)() const;
71using LVSymbolSetFunction = void (LVSymbol::*)();
72using LVSymbolGetFunction = bool (LVSymbol::*)() const;
73using LVTypeSetFunction = void (LVType::*)();
74using LVTypeGetFunction = bool (LVType::*)() const;
75
76using LVElements = SmallVector<LVElement *, 8>;
77using LVLines = SmallVector<LVLine *, 8>;
78using LVLocations = SmallVector<LVLocation *, 8>;
79using LVOperations = SmallVector<LVOperation *, 8>;
80using LVScopes = SmallVector<LVScope *, 8>;
81using LVSymbols = SmallVector<LVSymbol *, 8>;
82using LVTypes = SmallVector<LVType *, 8>;
83
84using LVOffsets = SmallVector<LVOffset, 8>;
85
86const LVAddress MaxAddress = std::numeric_limits<uint64_t>::max();
87
88enum class LVBinaryType { NONE, ELF, COFF };
89enum class LVComparePass { Missing, Added };
90
91// Validate functions.
92using LVValidLocation = bool (LVLocation::*)();
93
94// Keep counters of objects.
95struct LVCounter {
96 unsigned Lines = 0;
97 unsigned Scopes = 0;
98 unsigned Symbols = 0;
99 unsigned Types = 0;
100 void reset() {
101 Lines = 0;
102 Scopes = 0;
103 Symbols = 0;
104 Types = 0;
105 }
106};
107
108class LVObject {
109 enum class Property {
110 IsLocation, // Location.
111 IsGlobalReference, // This object is being referenced from another CU.
112 IsGeneratedName, // The Object name was generated.
113 IsResolved, // Object has been resolved.
114 IsResolvedName, // Object name has been resolved.
115 IsDiscarded, // Object has been stripped by the linker.
116 IsOptimized, // Object has been optimized by the compiler.
117 IsAdded, // Object has been 'added'.
118 IsMatched, // Object has been matched to a given pattern.
119 IsMissing, // Object is 'missing'.
120 IsMissingLink, // Object is indirectly 'missing'.
121 IsInCompare, // In 'compare' mode.
122 IsFileFromReference, // File ID from specification.
123 IsLineFromReference, // Line No from specification.
124 HasMoved, // The object was moved from 'target' to 'reference'.
125 HasPattern, // The object has a pattern.
126 IsFinalized, // CodeView object is finalized.
127 IsReferenced, // CodeView object being referenced.
128 HasCodeViewLocation, // CodeView object with debug location.
129 LastEntry
130 };
131 // Typed bitvector with properties for this object.
132 LVProperties<Property> Properties;
133
134 LVOffset Offset = 0;
135 uint32_t LineNumber = 0;
136 LVLevel ScopeLevel = 0;
137 union {
138 dwarf::Tag Tag;
139 dwarf::Attribute Attr;
140 LVSmall Opcode;
141 } TagAttrOpcode = {.Tag: dwarf::DW_TAG_null};
142
143 // The parent of this object (nullptr if the root scope). For locations,
144 // the parent is a symbol object; otherwise it is a scope object.
145 union {
146 LVElement *Element;
147 LVScope *Scope;
148 LVSymbol *Symbol;
149 } Parent = {.Element: nullptr};
150
151 // We do not support any object duplication, as they are created by parsing
152 // the debug information. There is only the case where we need a very basic
153 // object, to manipulate its offset, line number and scope level. Allow the
154 // copy constructor to create that object; it is used to print a reference
155 // to another object and in the case of templates, to print its encoded args.
156 LVObject(const LVObject &Object) {
157#ifndef NDEBUG
158 incID();
159#endif
160 Properties = Object.Properties;
161 Offset = Object.Offset;
162 LineNumber = Object.LineNumber;
163 ScopeLevel = Object.ScopeLevel;
164 TagAttrOpcode = Object.TagAttrOpcode;
165 Parent = Object.Parent;
166 }
167
168#ifndef NDEBUG
169 // This is an internal ID used for debugging logical elements. It is used
170 // for cases where an unique offset within the binary input file is not
171 // available.
172 static uint64_t GID;
173 uint64_t ID = 0;
174
175 void incID() {
176 ++GID;
177 ID = GID;
178 }
179#endif
180
181protected:
182 // Get a string representation for the given number and discriminator.
183 std::string lineAsString(uint32_t LineNumber, LVHalf Discriminator,
184 bool ShowZero) const;
185
186 // Get a string representation for the given number.
187 std::string referenceAsString(uint32_t LineNumber, bool Spaces) const;
188
189 // Print the Filename or Pathname.
190 // Empty implementation for those objects that do not have any user
191 // source file references, such as debug locations.
192 virtual void printFileIndex(raw_ostream &OS, bool Full = true) const {}
193
194public:
195 LVObject() {
196#ifndef NDEBUG
197 incID();
198#endif
199 };
200 LVObject &operator=(const LVObject &) = delete;
201 virtual ~LVObject() = default;
202
203 PROPERTY(Property, IsLocation);
204 PROPERTY(Property, IsGlobalReference);
205 PROPERTY(Property, IsGeneratedName);
206 PROPERTY(Property, IsResolved);
207 PROPERTY(Property, IsResolvedName);
208 PROPERTY(Property, IsDiscarded);
209 PROPERTY(Property, IsOptimized);
210 PROPERTY(Property, IsAdded);
211 PROPERTY(Property, IsMatched);
212 PROPERTY(Property, IsMissing);
213 PROPERTY(Property, IsMissingLink);
214 PROPERTY(Property, IsInCompare);
215 PROPERTY(Property, IsFileFromReference);
216 PROPERTY(Property, IsLineFromReference);
217 PROPERTY(Property, HasMoved);
218 PROPERTY(Property, HasPattern);
219 PROPERTY(Property, IsFinalized);
220 PROPERTY(Property, IsReferenced);
221 PROPERTY(Property, HasCodeViewLocation);
222
223 // True if the scope has been named or typed or with line number.
224 virtual bool isNamed() const { return false; }
225 virtual bool isTyped() const { return false; }
226 virtual bool isFiled() const { return false; }
227 bool isLined() const { return LineNumber != 0; }
228
229 // DWARF tag, attribute or expression opcode.
230 dwarf::Tag getTag() const { return TagAttrOpcode.Tag; }
231 void setTag(dwarf::Tag Tag) { TagAttrOpcode.Tag = Tag; }
232 dwarf::Attribute getAttr() const { return TagAttrOpcode.Attr; }
233 void setAttr(dwarf::Attribute Attr) { TagAttrOpcode.Attr = Attr; }
234 LVSmall getOpcode() const { return TagAttrOpcode.Opcode; }
235 void setOpcode(LVSmall Opcode) { TagAttrOpcode.Opcode = Opcode; }
236
237 // DIE offset.
238 LVOffset getOffset() const { return Offset; }
239 void setOffset(LVOffset DieOffset) { Offset = DieOffset; }
240
241 // Level where this object is located.
242 LVLevel getLevel() const { return ScopeLevel; }
243 void setLevel(LVLevel Level) { ScopeLevel = Level; }
244
245 virtual StringRef getName() const { return StringRef(); }
246 virtual void setName(StringRef ObjectName) {}
247
248 LVElement *getParent() const {
249 assert((!Parent.Element ||
250 (Parent.Element && static_cast<LVElement *>(Parent.Element))) &&
251 "Invalid element");
252 return Parent.Element;
253 }
254 LVScope *getParentScope() const {
255 assert((!Parent.Scope ||
256 (Parent.Scope && static_cast<LVScope *>(Parent.Scope))) &&
257 "Invalid scope");
258 return Parent.Scope;
259 }
260 LVSymbol *getParentSymbol() const {
261 assert((!Parent.Symbol ||
262 (Parent.Symbol && static_cast<LVSymbol *>(Parent.Symbol))) &&
263 "Invalid symbol");
264 return Parent.Symbol;
265 }
266 void setParent(LVScope *Scope);
267 void setParent(LVSymbol *Symbol);
268 void resetParent() { Parent = {.Element: nullptr}; }
269
270 virtual LVAddress getLowerAddress() const { return 0; }
271 virtual void setLowerAddress(LVAddress Address) {}
272 virtual LVAddress getUpperAddress() const { return 0; }
273 virtual void setUpperAddress(LVAddress Address) {}
274
275 uint32_t getLineNumber() const { return LineNumber; }
276 void setLineNumber(uint32_t Number) { LineNumber = Number; }
277
278 virtual const char *kind() const { return nullptr; }
279
280 std::string indentAsString() const;
281 std::string indentAsString(LVLevel Level) const;
282
283 // String used as padding for printing objects with no line number.
284 virtual std::string noLineAsString(bool ShowZero) const;
285
286 // Line number for display; in the case of inlined functions, we use the
287 // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
288 virtual std::string lineNumberAsString(bool ShowZero = false) const {
289 return lineAsString(LineNumber: getLineNumber(), Discriminator: 0, ShowZero);
290 }
291 std::string lineNumberAsStringStripped(bool ShowZero = false) const;
292
293 // This function prints the logical view to an output stream.
294 // Split: Prints the compilation unit view to a file.
295 // Match: Prints the object only if it satisfies the patterns collected
296 // from the command line. See the '--select' option.
297 // Print: Print the object only if satisfies the conditions specified by
298 // the different '--print' options.
299 // Full: Prints full information for objects representing debug locations,
300 // aggregated scopes, compile unit, functions and namespaces.
301 virtual Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
302 bool Full = true) const;
303 void printAttributes(raw_ostream &OS, bool Full = true) const;
304 void printAttributes(raw_ostream &OS, bool Full, StringRef Name,
305 LVObject *Parent, StringRef Value,
306 bool UseQuotes = false, bool PrintRef = false) const;
307
308 // Mark branch as missing (current element and parents).
309 void markBranchAsMissing();
310
311 // Prints the common information for an object (name, type, etc).
312 virtual void print(raw_ostream &OS, bool Full = true) const;
313 // Prints additional information for an object, depending on its kind
314 // (class attributes, debug ranges, files, directories, etc).
315 virtual void printExtra(raw_ostream &OS, bool Full = true) const {}
316
317#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
318 virtual void dump() const { print(OS&: dbgs()); }
319#endif
320
321 uint64_t getID() const {
322 return
323#ifndef NDEBUG
324 ID;
325#else
326 0;
327#endif
328 }
329};
330
331} // end namespace logicalview
332} // end namespace llvm
333
334#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
335

source code of llvm/include/llvm/DebugInfo/LogicalView/Core/LVObject.h