1e28b9357SCarlos Alberto Enciso //===-- LVLine.cpp --------------------------------------------------------===//
2e28b9357SCarlos Alberto Enciso //
3e28b9357SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e28b9357SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
5e28b9357SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e28b9357SCarlos Alberto Enciso //
7e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
8e28b9357SCarlos Alberto Enciso //
9e28b9357SCarlos Alberto Enciso // This implements the LVLine class.
10e28b9357SCarlos Alberto Enciso //
11e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
12e28b9357SCarlos Alberto Enciso
13e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
14*e98a4c5aSCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
15e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
16e28b9357SCarlos Alberto Enciso
17e28b9357SCarlos Alberto Enciso using namespace llvm;
18e28b9357SCarlos Alberto Enciso using namespace llvm::logicalview;
19e28b9357SCarlos Alberto Enciso
20e28b9357SCarlos Alberto Enciso #define DEBUG_TYPE "Line"
21e28b9357SCarlos Alberto Enciso
22e28b9357SCarlos Alberto Enciso namespace {
23e28b9357SCarlos Alberto Enciso const char *const KindBasicBlock = "BasicBlock";
24e28b9357SCarlos Alberto Enciso const char *const KindDiscriminator = "Discriminator";
25e28b9357SCarlos Alberto Enciso const char *const KindEndSequence = "EndSequence";
26e28b9357SCarlos Alberto Enciso const char *const KindEpilogueBegin = "EpilogueBegin";
27e28b9357SCarlos Alberto Enciso const char *const KindLineDebug = "Line";
28e28b9357SCarlos Alberto Enciso const char *const KindLineSource = "Code";
29e28b9357SCarlos Alberto Enciso const char *const KindNewStatement = "NewStatement";
30e28b9357SCarlos Alberto Enciso const char *const KindPrologueEnd = "PrologueEnd";
31e28b9357SCarlos Alberto Enciso const char *const KindUndefined = "Undefined";
32e28b9357SCarlos Alberto Enciso const char *const KindAlwaysStepInto = "AlwaysStepInto"; // CodeView
33e28b9357SCarlos Alberto Enciso const char *const KindNeverStepInto = "NeverStepInto"; // CodeView
34e28b9357SCarlos Alberto Enciso } // end anonymous namespace
35e28b9357SCarlos Alberto Enciso
36e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
37e28b9357SCarlos Alberto Enciso // Logical line.
38e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
39e28b9357SCarlos Alberto Enciso // Return a string representation for the line kind.
kind() const40e28b9357SCarlos Alberto Enciso const char *LVLine::kind() const {
41e28b9357SCarlos Alberto Enciso const char *Kind = KindUndefined;
42e28b9357SCarlos Alberto Enciso if (getIsLineDebug())
43e28b9357SCarlos Alberto Enciso Kind = KindLineDebug;
44e28b9357SCarlos Alberto Enciso else if (getIsLineAssembler())
45e28b9357SCarlos Alberto Enciso Kind = KindLineSource;
46e28b9357SCarlos Alberto Enciso return Kind;
47e28b9357SCarlos Alberto Enciso }
48e28b9357SCarlos Alberto Enciso
490332a8e7SCarlos Alberto Enciso LVLineDispatch LVLine::Dispatch = {
500332a8e7SCarlos Alberto Enciso {LVLineKind::IsBasicBlock, &LVLine::getIsBasicBlock},
510332a8e7SCarlos Alberto Enciso {LVLineKind::IsDiscriminator, &LVLine::getIsDiscriminator},
520332a8e7SCarlos Alberto Enciso {LVLineKind::IsEndSequence, &LVLine::getIsEndSequence},
530332a8e7SCarlos Alberto Enciso {LVLineKind::IsLineDebug, &LVLine::getIsLineDebug},
540332a8e7SCarlos Alberto Enciso {LVLineKind::IsLineAssembler, &LVLine::getIsLineAssembler},
550332a8e7SCarlos Alberto Enciso {LVLineKind::IsNewStatement, &LVLine::getIsNewStatement},
560332a8e7SCarlos Alberto Enciso {LVLineKind::IsEpilogueBegin, &LVLine::getIsEpilogueBegin},
570332a8e7SCarlos Alberto Enciso {LVLineKind::IsPrologueEnd, &LVLine::getIsPrologueEnd},
580332a8e7SCarlos Alberto Enciso {LVLineKind::IsAlwaysStepInto, &LVLine::getIsAlwaysStepInto},
590332a8e7SCarlos Alberto Enciso {LVLineKind::IsNeverStepInto, &LVLine::getIsNeverStepInto}};
600332a8e7SCarlos Alberto Enciso
61e28b9357SCarlos Alberto Enciso // String used as padding for printing elements with no line number.
noLineAsString(bool ShowZero) const62e28b9357SCarlos Alberto Enciso std::string LVLine::noLineAsString(bool ShowZero) const {
632c155d37SCarlos Alberto Enciso if (options().getInternalNone())
642c155d37SCarlos Alberto Enciso return LVObject::noLineAsString(ShowZero);
65e28b9357SCarlos Alberto Enciso return (ShowZero || options().getAttributeZero()) ? (" 0 ")
66e28b9357SCarlos Alberto Enciso : (" - ");
67e28b9357SCarlos Alberto Enciso }
68e28b9357SCarlos Alberto Enciso
markMissingParents(const LVLines * References,const LVLines * Targets)69*e98a4c5aSCarlos Alberto Enciso void LVLine::markMissingParents(const LVLines *References,
70*e98a4c5aSCarlos Alberto Enciso const LVLines *Targets) {
71*e98a4c5aSCarlos Alberto Enciso if (!(References && Targets))
72*e98a4c5aSCarlos Alberto Enciso return;
73*e98a4c5aSCarlos Alberto Enciso
74*e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
75*e98a4c5aSCarlos Alberto Enciso dbgs() << "\n[LVLine::markMissingParents]\n";
76*e98a4c5aSCarlos Alberto Enciso for (const LVLine *Reference : *References)
77*e98a4c5aSCarlos Alberto Enciso dbgs() << "References: "
78*e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Reference->kind()) << ", "
79*e98a4c5aSCarlos Alberto Enciso << "Line = " << Reference->getLineNumber() << "\n";
80*e98a4c5aSCarlos Alberto Enciso for (const LVLine *Target : *Targets)
81*e98a4c5aSCarlos Alberto Enciso dbgs() << "Targets : "
82*e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Target->kind()) << ", "
83*e98a4c5aSCarlos Alberto Enciso << "Line = " << Target->getLineNumber() << "\n";
84*e98a4c5aSCarlos Alberto Enciso });
85*e98a4c5aSCarlos Alberto Enciso
86*e98a4c5aSCarlos Alberto Enciso for (LVLine *Reference : *References) {
87*e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
88*e98a4c5aSCarlos Alberto Enciso dbgs() << "Search Reference: Line = " << Reference->getLineNumber()
89*e98a4c5aSCarlos Alberto Enciso << "\n";
90*e98a4c5aSCarlos Alberto Enciso });
91*e98a4c5aSCarlos Alberto Enciso if (!Reference->findIn(Targets))
92*e98a4c5aSCarlos Alberto Enciso Reference->markBranchAsMissing();
93*e98a4c5aSCarlos Alberto Enciso }
94*e98a4c5aSCarlos Alberto Enciso }
95*e98a4c5aSCarlos Alberto Enciso
findIn(const LVLines * Targets) const96*e98a4c5aSCarlos Alberto Enciso LVLine *LVLine::findIn(const LVLines *Targets) const {
97*e98a4c5aSCarlos Alberto Enciso if (!Targets)
98*e98a4c5aSCarlos Alberto Enciso return nullptr;
99*e98a4c5aSCarlos Alberto Enciso
100*e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
101*e98a4c5aSCarlos Alberto Enciso dbgs() << "\n[LVLine::findIn]\n"
102*e98a4c5aSCarlos Alberto Enciso << "Reference: "
103*e98a4c5aSCarlos Alberto Enciso << "Level = " << getLevel() << ", "
104*e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(kind()) << ", "
105*e98a4c5aSCarlos Alberto Enciso << "Line = " << getLineNumber() << "\n";
106*e98a4c5aSCarlos Alberto Enciso for (const LVLine *Target : *Targets)
107*e98a4c5aSCarlos Alberto Enciso dbgs() << "Target : "
108*e98a4c5aSCarlos Alberto Enciso << "Level = " << Target->getLevel() << ", "
109*e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Target->kind()) << ", "
110*e98a4c5aSCarlos Alberto Enciso << "Line = " << Target->getLineNumber() << "\n";
111*e98a4c5aSCarlos Alberto Enciso });
112*e98a4c5aSCarlos Alberto Enciso
113*e98a4c5aSCarlos Alberto Enciso for (LVLine *Line : *Targets)
114*e98a4c5aSCarlos Alberto Enciso if (equals(Line))
115*e98a4c5aSCarlos Alberto Enciso return Line;
116*e98a4c5aSCarlos Alberto Enciso
117*e98a4c5aSCarlos Alberto Enciso return nullptr;
118*e98a4c5aSCarlos Alberto Enciso }
119*e98a4c5aSCarlos Alberto Enciso
equals(const LVLine * Line) const120*e98a4c5aSCarlos Alberto Enciso bool LVLine::equals(const LVLine *Line) const {
121*e98a4c5aSCarlos Alberto Enciso return LVElement::equals(Line);
122*e98a4c5aSCarlos Alberto Enciso }
123*e98a4c5aSCarlos Alberto Enciso
equals(const LVLines * References,const LVLines * Targets)124*e98a4c5aSCarlos Alberto Enciso bool LVLine::equals(const LVLines *References, const LVLines *Targets) {
125*e98a4c5aSCarlos Alberto Enciso if (!References && !Targets)
126*e98a4c5aSCarlos Alberto Enciso return true;
127*e98a4c5aSCarlos Alberto Enciso if (References && Targets && References->size() == Targets->size()) {
128*e98a4c5aSCarlos Alberto Enciso for (const LVLine *Reference : *References)
129*e98a4c5aSCarlos Alberto Enciso if (!Reference->findIn(Targets))
130*e98a4c5aSCarlos Alberto Enciso return false;
131*e98a4c5aSCarlos Alberto Enciso return true;
132*e98a4c5aSCarlos Alberto Enciso }
133*e98a4c5aSCarlos Alberto Enciso return false;
134*e98a4c5aSCarlos Alberto Enciso }
135*e98a4c5aSCarlos Alberto Enciso
report(LVComparePass Pass)136*e98a4c5aSCarlos Alberto Enciso void LVLine::report(LVComparePass Pass) {
137*e98a4c5aSCarlos Alberto Enciso getComparator().printItem(this, Pass);
138*e98a4c5aSCarlos Alberto Enciso }
139*e98a4c5aSCarlos Alberto Enciso
print(raw_ostream & OS,bool Full) const140e28b9357SCarlos Alberto Enciso void LVLine::print(raw_ostream &OS, bool Full) const {
141e28b9357SCarlos Alberto Enciso if (getReader().doPrintLine(this)) {
142e28b9357SCarlos Alberto Enciso getReaderCompileUnit()->incrementPrintedLines();
143e28b9357SCarlos Alberto Enciso LVElement::print(OS, Full);
144e28b9357SCarlos Alberto Enciso printExtra(OS, Full);
145e28b9357SCarlos Alberto Enciso }
146e28b9357SCarlos Alberto Enciso }
147e28b9357SCarlos Alberto Enciso
148e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
149e28b9357SCarlos Alberto Enciso // DWARF line record.
150e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
statesInfo(bool Formatted) const151e28b9357SCarlos Alberto Enciso std::string LVLineDebug::statesInfo(bool Formatted) const {
152e28b9357SCarlos Alberto Enciso // Returns the DWARF extra qualifiers.
153e28b9357SCarlos Alberto Enciso std::string String;
154e28b9357SCarlos Alberto Enciso raw_string_ostream Stream(String);
155e28b9357SCarlos Alberto Enciso
156e28b9357SCarlos Alberto Enciso std::string Separator = Formatted ? " " : "";
157e28b9357SCarlos Alberto Enciso if (getIsNewStatement()) {
158e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindNewStatement << "}";
159e28b9357SCarlos Alberto Enciso Separator = " ";
160e28b9357SCarlos Alberto Enciso }
161e28b9357SCarlos Alberto Enciso if (getIsDiscriminator()) {
162e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindDiscriminator << "}";
163e28b9357SCarlos Alberto Enciso Separator = " ";
164e28b9357SCarlos Alberto Enciso }
165e28b9357SCarlos Alberto Enciso if (getIsBasicBlock()) {
166e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindBasicBlock << "}";
167e28b9357SCarlos Alberto Enciso Separator = " ";
168e28b9357SCarlos Alberto Enciso }
169e28b9357SCarlos Alberto Enciso if (getIsEndSequence()) {
170e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindEndSequence << "}";
171e28b9357SCarlos Alberto Enciso Separator = " ";
172e28b9357SCarlos Alberto Enciso }
173e28b9357SCarlos Alberto Enciso if (getIsEpilogueBegin()) {
174e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindEpilogueBegin << "}";
175e28b9357SCarlos Alberto Enciso Separator = " ";
176e28b9357SCarlos Alberto Enciso }
177e28b9357SCarlos Alberto Enciso if (getIsPrologueEnd()) {
178e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindPrologueEnd << "}";
179e28b9357SCarlos Alberto Enciso Separator = " ";
180e28b9357SCarlos Alberto Enciso }
181e28b9357SCarlos Alberto Enciso if (getIsAlwaysStepInto()) {
182e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindAlwaysStepInto << "}";
183e28b9357SCarlos Alberto Enciso Separator = " ";
184e28b9357SCarlos Alberto Enciso }
185e28b9357SCarlos Alberto Enciso if (getIsNeverStepInto()) {
186e28b9357SCarlos Alberto Enciso Stream << Separator << "{" << KindNeverStepInto << "}";
187e28b9357SCarlos Alberto Enciso Separator = " ";
188e28b9357SCarlos Alberto Enciso }
189e28b9357SCarlos Alberto Enciso
190e28b9357SCarlos Alberto Enciso return String;
191e28b9357SCarlos Alberto Enciso }
192e28b9357SCarlos Alberto Enciso
equals(const LVLine * Line) const193*e98a4c5aSCarlos Alberto Enciso bool LVLineDebug::equals(const LVLine *Line) const {
194*e98a4c5aSCarlos Alberto Enciso if (!LVLine::equals(Line))
195*e98a4c5aSCarlos Alberto Enciso return false;
196*e98a4c5aSCarlos Alberto Enciso return getFilenameIndex() == Line->getFilenameIndex();
197*e98a4c5aSCarlos Alberto Enciso }
198*e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const199e28b9357SCarlos Alberto Enciso void LVLineDebug::printExtra(raw_ostream &OS, bool Full) const {
200e28b9357SCarlos Alberto Enciso OS << formattedKind(kind());
201e28b9357SCarlos Alberto Enciso
202e28b9357SCarlos Alberto Enciso if (options().getAttributeQualifier()) {
203e28b9357SCarlos Alberto Enciso // The qualifier includes the states information and the source filename
204e28b9357SCarlos Alberto Enciso // that contains the line element.
205e28b9357SCarlos Alberto Enciso OS << statesInfo(/*Formatted=*/true);
206e28b9357SCarlos Alberto Enciso OS << " " << formattedName(getPathname());
207e28b9357SCarlos Alberto Enciso }
208e28b9357SCarlos Alberto Enciso OS << "\n";
209e28b9357SCarlos Alberto Enciso }
210e28b9357SCarlos Alberto Enciso
211e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
212e28b9357SCarlos Alberto Enciso // Assembler line extracted from the ELF .text section.
213e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
equals(const LVLine * Line) const214*e98a4c5aSCarlos Alberto Enciso bool LVLineAssembler::equals(const LVLine *Line) const {
215*e98a4c5aSCarlos Alberto Enciso return LVLine::equals(Line);
216*e98a4c5aSCarlos Alberto Enciso }
217*e98a4c5aSCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const218e28b9357SCarlos Alberto Enciso void LVLineAssembler::printExtra(raw_ostream &OS, bool Full) const {
219e28b9357SCarlos Alberto Enciso OS << formattedKind(kind());
220e28b9357SCarlos Alberto Enciso OS << " " << formattedName(getName());
221e28b9357SCarlos Alberto Enciso OS << "\n";
222e28b9357SCarlos Alberto Enciso }
223