LLVM 20.0.0git
LVLine.cpp
Go to the documentation of this file.
1//===-- LVLine.cpp --------------------------------------------------------===//
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 implements the LVLine class.
10//
11//===----------------------------------------------------------------------===//
12
16
17using namespace llvm;
18using namespace llvm::logicalview;
19
20#define DEBUG_TYPE "Line"
21
22namespace {
23const char *const KindBasicBlock = "BasicBlock";
24const char *const KindDiscriminator = "Discriminator";
25const char *const KindEndSequence = "EndSequence";
26const char *const KindEpilogueBegin = "EpilogueBegin";
27const char *const KindLineDebug = "Line";
28const char *const KindLineSource = "Code";
29const char *const KindNewStatement = "NewStatement";
30const char *const KindPrologueEnd = "PrologueEnd";
31const char *const KindUndefined = "Undefined";
32const char *const KindAlwaysStepInto = "AlwaysStepInto"; // CodeView
33const char *const KindNeverStepInto = "NeverStepInto"; // CodeView
34} // end anonymous namespace
35
36//===----------------------------------------------------------------------===//
37// Logical line.
38//===----------------------------------------------------------------------===//
39// Return a string representation for the line kind.
40const char *LVLine::kind() const {
41 const char *Kind = KindUndefined;
42 if (getIsLineDebug())
43 Kind = KindLineDebug;
44 else if (getIsLineAssembler())
45 Kind = KindLineSource;
46 return Kind;
47}
48
49LVLineDispatch LVLine::Dispatch = {
50 {LVLineKind::IsBasicBlock, &LVLine::getIsBasicBlock},
51 {LVLineKind::IsDiscriminator, &LVLine::getIsDiscriminator},
52 {LVLineKind::IsEndSequence, &LVLine::getIsEndSequence},
53 {LVLineKind::IsLineDebug, &LVLine::getIsLineDebug},
54 {LVLineKind::IsLineAssembler, &LVLine::getIsLineAssembler},
55 {LVLineKind::IsNewStatement, &LVLine::getIsNewStatement},
56 {LVLineKind::IsEpilogueBegin, &LVLine::getIsEpilogueBegin},
57 {LVLineKind::IsPrologueEnd, &LVLine::getIsPrologueEnd},
58 {LVLineKind::IsAlwaysStepInto, &LVLine::getIsAlwaysStepInto},
59 {LVLineKind::IsNeverStepInto, &LVLine::getIsNeverStepInto}};
60
61// String used as padding for printing elements with no line number.
62std::string LVLine::noLineAsString(bool ShowZero) const {
63 if (options().getInternalNone())
64 return LVObject::noLineAsString(ShowZero);
65 return (ShowZero || options().getAttributeZero()) ? (" 0 ")
66 : (" - ");
67}
68
69void LVLine::markMissingParents(const LVLines *References,
70 const LVLines *Targets) {
71 if (!(References && Targets))
72 return;
73
75 dbgs() << "\n[LVLine::markMissingParents]\n";
76 for (const LVLine *Reference : *References)
77 dbgs() << "References: "
78 << "Kind = " << formattedKind(Reference->kind()) << ", "
79 << "Line = " << Reference->getLineNumber() << "\n";
80 for (const LVLine *Target : *Targets)
81 dbgs() << "Targets : "
82 << "Kind = " << formattedKind(Target->kind()) << ", "
83 << "Line = " << Target->getLineNumber() << "\n";
84 });
85
86 for (LVLine *Reference : *References) {
88 dbgs() << "Search Reference: Line = " << Reference->getLineNumber()
89 << "\n";
90 });
91 if (!Reference->findIn(Targets))
92 Reference->markBranchAsMissing();
93 }
94}
95
96LVLine *LVLine::findIn(const LVLines *Targets) const {
97 if (!Targets)
98 return nullptr;
99
100 LLVM_DEBUG({
101 dbgs() << "\n[LVLine::findIn]\n"
102 << "Reference: "
103 << "Level = " << getLevel() << ", "
104 << "Kind = " << formattedKind(kind()) << ", "
105 << "Line = " << getLineNumber() << "\n";
106 for (const LVLine *Target : *Targets)
107 dbgs() << "Target : "
108 << "Level = " << Target->getLevel() << ", "
109 << "Kind = " << formattedKind(Target->kind()) << ", "
110 << "Line = " << Target->getLineNumber() << "\n";
111 });
112
113 for (LVLine *Line : *Targets)
114 if (equals(Line))
115 return Line;
116
117 return nullptr;
118}
119
120bool LVLine::equals(const LVLine *Line) const {
121 return LVElement::equals(Line);
122}
123
124bool LVLine::equals(const LVLines *References, const LVLines *Targets) {
125 if (!References && !Targets)
126 return true;
127 if (References && Targets && References->size() == Targets->size()) {
128 for (const LVLine *Reference : *References)
129 if (!Reference->findIn(Targets))
130 return false;
131 return true;
132 }
133 return false;
134}
135
138}
139
140void LVLine::print(raw_ostream &OS, bool Full) const {
141 if (getReader().doPrintLine(this)) {
145 }
146}
147
148//===----------------------------------------------------------------------===//
149// DWARF line record.
150//===----------------------------------------------------------------------===//
151std::string LVLineDebug::statesInfo(bool Formatted) const {
152 // Returns the DWARF extra qualifiers.
153 std::string String;
155
156 std::string Separator = Formatted ? " " : "";
157 if (getIsNewStatement()) {
158 Stream << Separator << "{" << KindNewStatement << "}";
159 Separator = " ";
160 }
161 if (getIsDiscriminator()) {
162 Stream << Separator << "{" << KindDiscriminator << "}";
163 Separator = " ";
164 }
165 if (getIsBasicBlock()) {
166 Stream << Separator << "{" << KindBasicBlock << "}";
167 Separator = " ";
168 }
169 if (getIsEndSequence()) {
170 Stream << Separator << "{" << KindEndSequence << "}";
171 Separator = " ";
172 }
173 if (getIsEpilogueBegin()) {
174 Stream << Separator << "{" << KindEpilogueBegin << "}";
175 Separator = " ";
176 }
177 if (getIsPrologueEnd()) {
178 Stream << Separator << "{" << KindPrologueEnd << "}";
179 Separator = " ";
180 }
181 if (getIsAlwaysStepInto()) {
182 Stream << Separator << "{" << KindAlwaysStepInto << "}";
183 Separator = " ";
184 }
185 if (getIsNeverStepInto()) {
186 Stream << Separator << "{" << KindNeverStepInto << "}";
187 Separator = " ";
188 }
189
190 return String;
191}
192
193bool LVLineDebug::equals(const LVLine *Line) const {
194 if (!LVLine::equals(Line))
195 return false;
196 return getFilenameIndex() == Line->getFilenameIndex();
197}
198
200 OS << formattedKind(kind());
201
202 if (options().getAttributeQualifier()) {
203 // The qualifier includes the states information and the source filename
204 // that contains the line element.
205 OS << statesInfo(/*Formatted=*/true);
206 OS << " " << formattedName(getPathname());
207 }
208 OS << "\n";
209}
210
211//===----------------------------------------------------------------------===//
212// Assembler line extracted from the ELF .text section.
213//===----------------------------------------------------------------------===//
215 return LVLine::equals(Line);
216}
217
219 OS << formattedKind(kind());
220 OS << " " << formattedName(getName());
221 OS << "\n";
222}
#define LLVM_DEBUG(X)
Definition: Debug.h:101
raw_pwrite_stream & OS
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:94
size_t size() const
Definition: SmallVector.h:92
Target - Wrapper for Target specific information.
void printItem(LVElement *Element, LVComparePass Pass)
Definition: LVCompare.cpp:361
StringRef getName() const override
Definition: LVElement.h:184
bool equals(const LVElement *Element) const
Definition: LVElement.cpp:475
size_t getFilenameIndex() const
Definition: LVElement.h:233
StringRef getPathname() const
Definition: LVElement.h:190
void printExtra(raw_ostream &OS, bool Full=true) const override
Definition: LVLine.cpp:218
bool equals(const LVLine *Line) const override
Definition: LVLine.cpp:214
bool equals(const LVLine *Line) const override
Definition: LVLine.cpp:193
std::string statesInfo(bool Formatted) const
Definition: LVLine.cpp:151
void printExtra(raw_ostream &OS, bool Full=true) const override
Definition: LVLine.cpp:199
std::string noLineAsString(bool ShowZero=false) const override
Definition: LVLine.cpp:62
static void markMissingParents(const LVLines *References, const LVLines *Targets)
Definition: LVLine.cpp:69
void printExtra(raw_ostream &OS, bool Full=true) const override
Definition: LVLine.h:106
void report(LVComparePass Pass) override
Definition: LVLine.cpp:136
const char * kind() const override
Definition: LVLine.cpp:40
void print(raw_ostream &OS, bool Full=true) const override
Definition: LVLine.cpp:140
virtual bool equals(const LVLine *Line) const
Definition: LVLine.cpp:120
virtual void print(raw_ostream &OS, bool Full=true) const
Definition: LVObject.cpp:160
LVLevel getLevel() const
Definition: LVObject.h:242
uint32_t getLineNumber() const
Definition: LVObject.h:272
virtual std::string noLineAsString(bool ShowZero) const
Definition: LVObject.cpp:47
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:661
LVReader & getReader()
Definition: LVReader.h:333
std::string formattedKind(StringRef Kind)
Definition: LVSupport.h:216
LVScopeCompileUnit * getReaderCompileUnit()
Definition: LVReader.h:337
std::string formattedName(StringRef Name)
Definition: LVSupport.h:220
std::map< LVLineKind, LVLineGetFunction > LVLineDispatch
Definition: LVLine.h:36
LVOptions & options()
Definition: LVOptions.h:445
LVCompare & getComparator()
Definition: LVCompare.h:84
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163