1 //===-- LVObject.h ----------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the LVObject class, which is used to describe a debug
10 // information object.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
15 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H
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"
28 // Support for CodeView ModifierOptions::Unaligned.
29 constexpr Tag DW_TAG_unaligned = Tag(dwarf::DW_TAG_hi_user + 1);
34 namespace logicalview {
36 using LVSectionIndex = uint64_t;
37 using LVAddress = uint64_t;
38 using LVHalf = uint16_t;
39 using LVLevel = uint32_t;
40 using LVOffset = uint64_t;
41 using LVSigned = int64_t;
42 using LVUnsigned = uint64_t;
43 using LVSmall = uint8_t;
48 class LVLocationSymbol;
61 StringRef typeUnknown();
62 StringRef emptyString();
64 using LVElementSetFunction = void (LVElement::*)();
65 using LVElementGetFunction = bool (LVElement::*)() const;
66 using LVLineSetFunction = void (LVLine::*)();
67 using LVLineGetFunction = bool (LVLine::*)() const;
68 using LVObjectSetFunction = void (LVObject::*)();
69 using LVObjectGetFunction = bool (LVObject::*)() const;
70 using LVScopeSetFunction = void (LVScope::*)();
71 using LVScopeGetFunction = bool (LVScope::*)() const;
72 using LVSymbolSetFunction = void (LVSymbol::*)();
73 using LVSymbolGetFunction = bool (LVSymbol::*)() const;
74 using LVTypeSetFunction = void (LVType::*)();
75 using LVTypeGetFunction = bool (LVType::*)() const;
77 using LVElements = SmallVector<LVElement *, 8>;
78 using LVLines = SmallVector<LVLine *, 8>;
79 using LVLocations = SmallVector<LVLocation *, 8>;
80 using LVOperations = SmallVector<LVOperation *, 8>;
81 using LVScopes = SmallVector<LVScope *, 8>;
82 using LVSymbols = SmallVector<LVSymbol *, 8>;
83 using LVTypes = SmallVector<LVType *, 8>;
85 using LVOffsets = SmallVector<LVOffset, 8>;
87 const LVAddress MaxAddress = std::numeric_limits<uint64_t>::max();
89 enum class LVBinaryType { NONE, ELF, COFF };
90 enum class LVComparePass { Missing, Added };
92 // Validate functions.
93 using LVValidLocation = bool (LVLocation::*)();
95 // Keep counters of objects.
110 enum class Property {
111 IsLocation, // Location.
112 IsGlobalReference, // This object is being referenced from another CU.
113 IsGeneratedName, // The Object name was generated.
114 IsResolved, // Object has been resolved.
115 IsResolvedName, // Object name has been resolved.
116 IsDiscarded, // Object has been stripped by the linker.
117 IsOptimized, // Object has been optimized by the compiler.
118 IsAdded, // Object has been 'added'.
119 IsMatched, // Object has been matched to a given pattern.
120 IsMissing, // Object is 'missing'.
121 IsMissingLink, // Object is indirectly 'missing'.
122 IsInCompare, // In 'compare' mode.
123 IsFileFromReference, // File ID from specification.
124 IsLineFromReference, // Line No from specification.
125 HasMoved, // The object was moved from 'target' to 'reference'.
126 HasPattern, // The object has a pattern.
127 IsFinalized, // CodeView object is finalized.
128 IsReferenced, // CodeView object being referenced.
129 HasCodeViewLocation, // CodeView object with debug location.
132 // Typed bitvector with properties for this object.
133 LVProperties<Property> Properties;
136 uint32_t LineNumber = 0;
137 LVLevel ScopeLevel = 0;
140 dwarf::Attribute Attr;
142 } TagAttrOpcode = {dwarf::DW_TAG_null};
144 // The parent of this object (nullptr if the root scope). For locations,
145 // the parent is a symbol object; otherwise it is a scope object.
150 } Parent = {nullptr};
152 // We do not support any object duplication, as they are created by parsing
153 // the debug information. There is only the case where we need a very basic
154 // object, to manipulate its offset, line number and scope level. Allow the
155 // copy constructor to create that object; it is used to print a reference
156 // to another object and in the case of templates, to print its encoded args.
157 LVObject(const LVObject &Object) {
161 Properties = Object.Properties;
162 Offset = Object.Offset;
163 LineNumber = Object.LineNumber;
164 ScopeLevel = Object.ScopeLevel;
165 TagAttrOpcode = Object.TagAttrOpcode;
166 Parent = Object.Parent;
170 // This is an internal ID used for debugging logical elements. It is used
171 // for cases where an unique offset within the binary input file is not
183 // Get a string representation for the given number and discriminator.
184 std::string lineAsString(uint32_t LineNumber, LVHalf Discriminator,
185 bool ShowZero) const;
187 // Get a string representation for the given number.
188 std::string referenceAsString(uint32_t LineNumber, bool Spaces) const;
190 // Print the Filename or Pathname.
191 // Empty implementation for those objects that do not have any user
192 // source file references, such as debug locations.
193 virtual void printFileIndex(raw_ostream &OS, bool Full = true) const {}
201 LVObject &operator=(const LVObject &) = delete;
202 virtual ~LVObject() = default;
204 PROPERTY(Property, IsLocation);
205 PROPERTY(Property, IsGlobalReference);
206 PROPERTY(Property, IsGeneratedName);
207 PROPERTY(Property, IsResolved);
208 PROPERTY(Property, IsResolvedName);
209 PROPERTY(Property, IsDiscarded);
210 PROPERTY(Property, IsOptimized);
211 PROPERTY(Property, IsAdded);
212 PROPERTY(Property, IsMatched);
213 PROPERTY(Property, IsMissing);
214 PROPERTY(Property, IsMissingLink);
215 PROPERTY(Property, IsInCompare);
216 PROPERTY(Property, IsFileFromReference);
217 PROPERTY(Property, IsLineFromReference);
218 PROPERTY(Property, HasMoved);
219 PROPERTY(Property, HasPattern);
220 PROPERTY(Property, IsFinalized);
221 PROPERTY(Property, IsReferenced);
222 PROPERTY(Property, HasCodeViewLocation);
224 // True if the scope has been named or typed or with line number.
225 virtual bool isNamed() const { return false; }
226 virtual bool isTyped() const { return false; }
227 virtual bool isFiled() const { return false; }
228 bool isLined() const { return LineNumber != 0; }
230 // DWARF tag, attribute or expression opcode.
231 dwarf::Tag getTag() const { return TagAttrOpcode.Tag; }
232 void setTag(dwarf::Tag Tag) { TagAttrOpcode.Tag = Tag; }
233 dwarf::Attribute getAttr() const { return TagAttrOpcode.Attr; }
234 void setAttr(dwarf::Attribute Attr) { TagAttrOpcode.Attr = Attr; }
235 LVSmall getOpcode() const { return TagAttrOpcode.Opcode; }
236 void setOpcode(LVSmall Opcode) { TagAttrOpcode.Opcode = Opcode; }
239 LVOffset getOffset() const { return Offset; }
240 void setOffset(LVOffset DieOffset) { Offset = DieOffset; }
242 // Level where this object is located.
243 LVLevel getLevel() const { return ScopeLevel; }
244 void setLevel(LVLevel Level) { ScopeLevel = Level; }
246 virtual StringRef getName() const { return StringRef(); }
247 virtual void setName(StringRef ObjectName) {}
249 LVElement *getParent() const {
250 assert((!Parent.Element ||
251 (Parent.Element && static_cast<LVElement *>(Parent.Element))) &&
253 return Parent.Element;
255 LVScope *getParentScope() const {
256 assert((!Parent.Scope ||
257 (Parent.Scope && static_cast<LVScope *>(Parent.Scope))) &&
261 LVSymbol *getParentSymbol() const {
262 assert((!Parent.Symbol ||
263 (Parent.Symbol && static_cast<LVSymbol *>(Parent.Symbol))) &&
265 return Parent.Symbol;
267 void setParent(LVScope *Scope);
268 void setParent(LVSymbol *Symbol);
269 void resetParent() { Parent = {nullptr}; }
271 virtual LVAddress getLowerAddress() const { return 0; }
272 virtual void setLowerAddress(LVAddress Address) {}
273 virtual LVAddress getUpperAddress() const { return 0; }
274 virtual void setUpperAddress(LVAddress Address) {}
276 uint32_t getLineNumber() const { return LineNumber; }
277 void setLineNumber(uint32_t Number) { LineNumber = Number; }
279 virtual const char *kind() const { return nullptr; }
281 std::string indentAsString() const;
282 std::string indentAsString(LVLevel Level) const;
284 // String used as padding for printing objects with no line number.
285 virtual std::string noLineAsString(bool ShowZero) const;
287 // Line number for display; in the case of inlined functions, we use the
288 // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute.
289 virtual std::string lineNumberAsString(bool ShowZero = false) const {
290 return lineAsString(getLineNumber(), 0, ShowZero);
292 std::string lineNumberAsStringStripped(bool ShowZero = false) const;
294 // This function prints the logical view to an output stream.
295 // Split: Prints the compilation unit view to a file.
296 // Match: Prints the object only if it satisfies the patterns collected
297 // from the command line. See the '--select' option.
298 // Print: Print the object only if satisfies the conditions specified by
299 // the different '--print' options.
300 // Full: Prints full information for objects representing debug locations,
301 // aggregated scopes, compile unit, functions and namespaces.
302 virtual Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
303 bool Full = true) const;
304 void printAttributes(raw_ostream &OS, bool Full = true) const;
305 void printAttributes(raw_ostream &OS, bool Full, StringRef Name,
306 LVObject *Parent, StringRef Value,
307 bool UseQuotes = false, bool PrintRef = false) const;
309 // Mark branch as missing (current element and parents).
310 void markBranchAsMissing();
312 // Prints the common information for an object (name, type, etc).
313 virtual void print(raw_ostream &OS, bool Full = true) const;
314 // Prints additional information for an object, depending on its kind
315 // (class attributes, debug ranges, files, directories, etc).
316 virtual void printExtra(raw_ostream &OS, bool Full = true) const {}
318 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
319 virtual void dump() const { print(dbgs()); }
322 uint64_t getID() const {
332 } // end namespace logicalview
333 } // end namespace llvm
335 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOBJECT_H