Skip to content

Commit 88a8965

Browse files
committed
NFC. Refactored DIPrinter for support embedded source.
This patch introduces source loading and pruning functions. It will allow to use the DWARF embedded source and use the same code for JSON printout. No functional changes. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D102539
1 parent b7f60d8 commit 88a8965

File tree

2 files changed

+77
-26
lines changed

2 files changed

+77
-26
lines changed

llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class raw_ostream;
2929

3030
namespace symbolize {
3131

32+
class SourceCode;
33+
3234
struct Request {
3335
StringRef ModuleName;
3436
Optional<uint64_t> Address;
@@ -74,7 +76,7 @@ class PlainPrinterBase : public DIPrinter {
7476
void printFunctionName(StringRef FunctionName, bool Inlined);
7577
virtual void printSimpleLocation(StringRef Filename,
7678
const DILineInfo &Info) = 0;
77-
void printContext(StringRef FileName, int64_t Line);
79+
void printContext(SourceCode SourceCode);
7880
void printVerbose(StringRef Filename, const DILineInfo &Info);
7981
virtual void printFooter() {}
8082

llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,60 @@
3030
namespace llvm {
3131
namespace symbolize {
3232

33+
class SourceCode {
34+
std::unique_ptr<MemoryBuffer> MemBuf;
35+
36+
const Optional<StringRef> load(StringRef FileName,
37+
const Optional<StringRef> &EmbeddedSource) {
38+
if (Lines <= 0)
39+
return None;
40+
41+
if (EmbeddedSource)
42+
return EmbeddedSource;
43+
else {
44+
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
45+
MemoryBuffer::getFile(FileName);
46+
if (!BufOrErr)
47+
return None;
48+
MemBuf = std::move(*BufOrErr);
49+
return MemBuf->getBuffer();
50+
}
51+
}
52+
53+
const Optional<StringRef> pruneSource(const Optional<StringRef> &Source) {
54+
if (!Source)
55+
return None;
56+
size_t FirstLinePos = StringRef::npos, Pos = 0;
57+
for (int64_t L = 1; L <= LastLine; ++L, ++Pos) {
58+
if (L == FirstLine)
59+
FirstLinePos = Pos;
60+
Pos = Source->find('\n', Pos);
61+
if (Pos == StringRef::npos)
62+
break;
63+
}
64+
if (FirstLinePos == StringRef::npos)
65+
return None;
66+
return Source->substr(FirstLinePos, (Pos == StringRef::npos)
67+
? StringRef::npos
68+
: Pos - FirstLinePos);
69+
}
70+
71+
public:
72+
const int64_t Line;
73+
const int Lines;
74+
const int64_t FirstLine;
75+
const int64_t LastLine;
76+
const Optional<StringRef> PrunedSource;
77+
78+
SourceCode(
79+
StringRef FileName, int64_t Line, int Lines,
80+
const Optional<StringRef> &EmbeddedSource = Optional<StringRef>(None))
81+
: Line(Line), Lines(Lines),
82+
FirstLine(std::max(static_cast<int64_t>(1), Line - Lines / 2)),
83+
LastLine(FirstLine + Lines - 1),
84+
PrunedSource(pruneSource(load(FileName, EmbeddedSource))) {}
85+
};
86+
3387
void PlainPrinterBase::printHeader(uint64_t Address) {
3488
if (Config.PrintAddress) {
3589
OS << "0x";
@@ -40,32 +94,27 @@ void PlainPrinterBase::printHeader(uint64_t Address) {
4094
}
4195

4296
// Prints source code around in the FileName the Line.
43-
void PlainPrinterBase::printContext(StringRef FileName, int64_t Line) {
44-
if (Config.SourceContextLines <= 0)
97+
void PlainPrinterBase::printContext(SourceCode SourceCode) {
98+
if (!SourceCode.PrunedSource)
4599
return;
46100

47-
ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
48-
MemoryBuffer::getFile(FileName);
49-
if (!BufOrErr)
50-
return;
101+
StringRef Source = *SourceCode.PrunedSource;
102+
std::string SourceCopy;
103+
if (*Source.end() != '\0') {
104+
SourceCopy = Source.str();
105+
Source = SourceCopy;
106+
}
51107

52-
std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
53-
int64_t FirstLine =
54-
std::max(static_cast<int64_t>(1), Line - Config.SourceContextLines / 2);
55-
int64_t LastLine = FirstLine + Config.SourceContextLines;
56-
size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
57-
58-
for (line_iterator I = line_iterator(*Buf, false);
59-
!I.is_at_eof() && I.line_number() <= LastLine; ++I) {
60-
int64_t L = I.line_number();
61-
if (L >= FirstLine && L <= LastLine) {
62-
OS << format_decimal(L, MaxLineNumberWidth);
63-
if (L == Line)
64-
OS << " >: ";
65-
else
66-
OS << " : ";
67-
OS << *I << "\n";
68-
}
108+
size_t MaxLineNumberWidth = std::ceil(std::log10(SourceCode.LastLine));
109+
for (line_iterator I = line_iterator(MemoryBufferRef(Source, ""), false);
110+
!I.is_at_eof(); ++I) {
111+
int64_t L = SourceCode.FirstLine + I.line_number() - 1;
112+
OS << format_decimal(L, MaxLineNumberWidth);
113+
if (L == SourceCode.Line)
114+
OS << " >: ";
115+
else
116+
OS << " : ";
117+
OS << *I << '\n';
69118
}
70119
}
71120

@@ -82,7 +131,7 @@ void PlainPrinterBase::printFunctionName(StringRef FunctionName, bool Inlined) {
82131
void LLVMPrinter::printSimpleLocation(StringRef Filename,
83132
const DILineInfo &Info) {
84133
OS << Filename << ':' << Info.Line << ':' << Info.Column << '\n';
85-
printContext(Filename, Info.Line);
134+
printContext(SourceCode(Filename, Info.Line, Config.SourceContextLines));
86135
}
87136

88137
void GNUPrinter::printSimpleLocation(StringRef Filename,
@@ -91,7 +140,7 @@ void GNUPrinter::printSimpleLocation(StringRef Filename,
91140
if (Info.Discriminator)
92141
OS << " (discriminator " << Info.Discriminator << ')';
93142
OS << '\n';
94-
printContext(Filename, Info.Line);
143+
printContext(SourceCode(Filename, Info.Line, Config.SourceContextLines));
95144
}
96145

97146
void PlainPrinterBase::printVerbose(StringRef Filename,

0 commit comments

Comments
 (0)