xref: /llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVLine.cpp (revision e98a4c5acb378bdaae5f7aeb747bd27146f45191)
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