1 | //===-- LVLine.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 LVLine class, which is used to describe a debug |
10 | // information line. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLINE_H |
15 | #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLINE_H |
16 | |
17 | #include "llvm/DebugInfo/LogicalView/Core/LVElement.h" |
18 | |
19 | namespace llvm { |
20 | namespace logicalview { |
21 | |
22 | enum class LVLineKind { |
23 | IsBasicBlock, |
24 | IsDiscriminator, |
25 | IsEndSequence, |
26 | IsEpilogueBegin, |
27 | IsLineDebug, |
28 | IsLineAssembler, |
29 | IsNewStatement, // Shared with CodeView 'IsStatement' flag. |
30 | IsPrologueEnd, |
31 | IsAlwaysStepInto, // CodeView |
32 | IsNeverStepInto, // CodeView |
33 | LastEntry |
34 | }; |
35 | using LVLineKindSet = std::set<LVLineKind>; |
36 | using LVLineDispatch = std::map<LVLineKind, LVLineGetFunction>; |
37 | using LVLineRequest = std::vector<LVLineGetFunction>; |
38 | |
39 | // Class to represent a logical line. |
40 | class LVLine : public LVElement { |
41 | // Typed bitvector with kinds for this line. |
42 | LVProperties<LVLineKind> Kinds; |
43 | static LVLineDispatch Dispatch; |
44 | |
45 | // Find the current line in the given 'Targets'. |
46 | LVLine *findIn(const LVLines *Targets) const; |
47 | |
48 | public: |
49 | LVLine() : LVElement(LVSubclassID::LV_LINE) { |
50 | setIsLine(); |
51 | setIncludeInPrint(); |
52 | } |
53 | LVLine(const LVLine &) = delete; |
54 | LVLine &operator=(const LVLine &) = delete; |
55 | virtual ~LVLine() = default; |
56 | |
57 | static bool classof(const LVElement *Element) { |
58 | return Element->getSubclassID() == LVSubclassID::LV_LINE; |
59 | } |
60 | |
61 | KIND(LVLineKind, IsBasicBlock); |
62 | KIND(LVLineKind, IsDiscriminator); |
63 | KIND(LVLineKind, IsEndSequence); |
64 | KIND(LVLineKind, IsEpilogueBegin); |
65 | KIND(LVLineKind, IsLineDebug); |
66 | KIND(LVLineKind, IsLineAssembler); |
67 | KIND(LVLineKind, IsNewStatement); |
68 | KIND(LVLineKind, IsPrologueEnd); |
69 | KIND(LVLineKind, IsAlwaysStepInto); |
70 | KIND(LVLineKind, IsNeverStepInto); |
71 | |
72 | const char *kind() const override; |
73 | |
74 | // Use the offset to store the line address. |
75 | uint64_t getAddress() const { return getOffset(); } |
76 | void setAddress(uint64_t address) { setOffset(address); } |
77 | |
78 | // String used for printing objects with no line number. |
79 | std::string noLineAsString(bool ShowZero = false) const override; |
80 | |
81 | // Line number for display; in the case of Inlined Functions, we use the |
82 | // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute. |
83 | std::string lineNumberAsString(bool ShowZero = false) const override { |
84 | return lineAsString(LineNumber: getLineNumber(), Discriminator: getDiscriminator(), ShowZero); |
85 | } |
86 | |
87 | static LVLineDispatch &getDispatch() { return Dispatch; } |
88 | |
89 | // Iterate through the 'References' set and check that all its elements |
90 | // are present in the 'Targets' set. For a missing element, mark its |
91 | // parents as missing. |
92 | static void markMissingParents(const LVLines *References, |
93 | const LVLines *Targets); |
94 | |
95 | // Returns true if current line is logically equal to the given 'Line'. |
96 | virtual bool equals(const LVLine *Line) const; |
97 | |
98 | // Returns true if the given 'References' are logically equal to the |
99 | // given 'Targets'. |
100 | static bool equals(const LVLines *References, const LVLines *Targets); |
101 | |
102 | // Report the current line as missing or added during comparison. |
103 | void report(LVComparePass Pass) override; |
104 | |
105 | void print(raw_ostream &OS, bool Full = true) const override; |
106 | void (raw_ostream &OS, bool Full = true) const override {} |
107 | |
108 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
109 | void dump() const override { print(OS&: dbgs()); } |
110 | #endif |
111 | }; |
112 | |
113 | // Class to represent a DWARF line record object. |
114 | class LVLineDebug final : public LVLine { |
115 | // Discriminator value (DW_LNE_set_discriminator). The DWARF standard |
116 | // defines the discriminator as an unsigned LEB128 integer. |
117 | uint32_t Discriminator = 0; |
118 | |
119 | public: |
120 | LVLineDebug() : LVLine() { setIsLineDebug(); } |
121 | LVLineDebug(const LVLineDebug &) = delete; |
122 | LVLineDebug &operator=(const LVLineDebug &) = delete; |
123 | ~LVLineDebug() = default; |
124 | |
125 | // Additional line information. It includes attributes that describes |
126 | // states in the machine instructions (basic block, end prologue, etc). |
127 | std::string statesInfo(bool Formatted) const; |
128 | |
129 | // Access DW_LNE_set_discriminator attribute. |
130 | uint32_t getDiscriminator() const override { return Discriminator; } |
131 | void setDiscriminator(uint32_t Value) override { |
132 | Discriminator = Value; |
133 | setIsDiscriminator(); |
134 | } |
135 | |
136 | // Returns true if current line is logically equal to the given 'Line'. |
137 | bool equals(const LVLine *Line) const override; |
138 | |
139 | void (raw_ostream &OS, bool Full = true) const override; |
140 | }; |
141 | |
142 | // Class to represent an assembler line extracted from the text section. |
143 | class LVLineAssembler final : public LVLine { |
144 | public: |
145 | LVLineAssembler() : LVLine() { setIsLineAssembler(); } |
146 | LVLineAssembler(const LVLineAssembler &) = delete; |
147 | LVLineAssembler &operator=(const LVLineAssembler &) = delete; |
148 | ~LVLineAssembler() = default; |
149 | |
150 | // Print blanks as the line number. |
151 | std::string noLineAsString(bool ShowZero) const override { |
152 | return std::string(8, ' '); |
153 | }; |
154 | |
155 | // Returns true if current line is logically equal to the given 'Line'. |
156 | bool equals(const LVLine *Line) const override; |
157 | |
158 | void (raw_ostream &OS, bool Full = true) const override; |
159 | }; |
160 | |
161 | } // end namespace logicalview |
162 | } // end namespace llvm |
163 | |
164 | #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLINE_H |
165 | |