1 //===-- LVLine.cpp --------------------------------------------------------===//
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 implements the LVLine class.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
14 #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
15 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
18 using namespace llvm::logicalview
;
20 #define DEBUG_TYPE "Line"
23 const char *const KindBasicBlock
= "BasicBlock";
24 const char *const KindDiscriminator
= "Discriminator";
25 const char *const KindEndSequence
= "EndSequence";
26 const char *const KindEpilogueBegin
= "EpilogueBegin";
27 const char *const KindLineDebug
= "Line";
28 const char *const KindLineSource
= "Code";
29 const char *const KindNewStatement
= "NewStatement";
30 const char *const KindPrologueEnd
= "PrologueEnd";
31 const char *const KindUndefined
= "Undefined";
32 const char *const KindAlwaysStepInto
= "AlwaysStepInto"; // CodeView
33 const char *const KindNeverStepInto
= "NeverStepInto"; // CodeView
34 } // end anonymous namespace
36 //===----------------------------------------------------------------------===//
38 //===----------------------------------------------------------------------===//
39 // Return a string representation for the line kind.
40 const char *LVLine::kind() const {
41 const char *Kind
= KindUndefined
;
44 else if (getIsLineAssembler())
45 Kind
= KindLineSource
;
49 LVLineDispatch
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
}};
61 // String used as padding for printing elements with no line number.
62 std::string
LVLine::noLineAsString(bool ShowZero
) const {
63 if (options().getInternalNone())
64 return LVObject::noLineAsString(ShowZero
);
65 return (ShowZero
|| options().getAttributeZero()) ? (" 0 ")
69 void LVLine::markMissingParents(const LVLines
*References
,
70 const LVLines
*Targets
) {
71 if (!(References
&& Targets
))
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";
86 for (LVLine
*Reference
: *References
) {
88 dbgs() << "Search Reference: Line = " << Reference
->getLineNumber()
91 if (!Reference
->findIn(Targets
))
92 Reference
->markBranchAsMissing();
96 LVLine
*LVLine::findIn(const LVLines
*Targets
) const {
101 dbgs() << "\n[LVLine::findIn]\n"
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";
113 for (LVLine
*Line
: *Targets
)
120 bool LVLine::equals(const LVLine
*Line
) const {
121 return LVElement::equals(Line
);
124 bool LVLine::equals(const LVLines
*References
, const LVLines
*Targets
) {
125 if (!References
&& !Targets
)
127 if (References
&& Targets
&& References
->size() == Targets
->size()) {
128 for (const LVLine
*Reference
: *References
)
129 if (!Reference
->findIn(Targets
))
136 void LVLine::report(LVComparePass Pass
) {
137 getComparator().printItem(this, Pass
);
140 void LVLine::print(raw_ostream
&OS
, bool Full
) const {
141 if (getReader().doPrintLine(this)) {
142 getReaderCompileUnit()->incrementPrintedLines();
143 LVElement::print(OS
, Full
);
144 printExtra(OS
, Full
);
148 //===----------------------------------------------------------------------===//
149 // DWARF line record.
150 //===----------------------------------------------------------------------===//
151 std::string
LVLineDebug::statesInfo(bool Formatted
) const {
152 // Returns the DWARF extra qualifiers.
154 raw_string_ostream
Stream(String
);
156 std::string Separator
= Formatted
? " " : "";
157 if (getIsNewStatement()) {
158 Stream
<< Separator
<< "{" << KindNewStatement
<< "}";
161 if (getIsDiscriminator()) {
162 Stream
<< Separator
<< "{" << KindDiscriminator
<< "}";
165 if (getIsBasicBlock()) {
166 Stream
<< Separator
<< "{" << KindBasicBlock
<< "}";
169 if (getIsEndSequence()) {
170 Stream
<< Separator
<< "{" << KindEndSequence
<< "}";
173 if (getIsEpilogueBegin()) {
174 Stream
<< Separator
<< "{" << KindEpilogueBegin
<< "}";
177 if (getIsPrologueEnd()) {
178 Stream
<< Separator
<< "{" << KindPrologueEnd
<< "}";
181 if (getIsAlwaysStepInto()) {
182 Stream
<< Separator
<< "{" << KindAlwaysStepInto
<< "}";
185 if (getIsNeverStepInto()) {
186 Stream
<< Separator
<< "{" << KindNeverStepInto
<< "}";
193 bool LVLineDebug::equals(const LVLine
*Line
) const {
194 if (!LVLine::equals(Line
))
196 return getFilenameIndex() == Line
->getFilenameIndex();
199 void LVLineDebug::printExtra(raw_ostream
&OS
, bool Full
) const {
200 OS
<< formattedKind(kind());
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());
211 //===----------------------------------------------------------------------===//
212 // Assembler line extracted from the ELF .text section.
213 //===----------------------------------------------------------------------===//
214 bool LVLineAssembler::equals(const LVLine
*Line
) const {
215 return LVLine::equals(Line
);
218 void LVLineAssembler::printExtra(raw_ostream
&OS
, bool Full
) const {
219 OS
<< formattedKind(kind());
220 OS
<< " " << formattedName(getName());