blob: 3eb9ffc17f161bebf285e1bd1233c4cb177053b1 [file] [log] [blame]
Alexey Samsonovd6aa8202015-11-03 22:20:52 +00001//===- lib/DebugInfo/Symbolize/DIPrinter.cpp ------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the DIPrinter class, which is responsible for printing
11// structures defined in DebugInfo/DIContext.h
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/DebugInfo/Symbolize/DIPrinter.h"
Eugene Zelenko417d4c52016-05-09 23:11:38 +000016#include "llvm/ADT/StringRef.h"
Alexey Samsonovd6aa8202015-11-03 22:20:52 +000017#include "llvm/DebugInfo/DIContext.h"
Eugene Zelenko417d4c52016-05-09 23:11:38 +000018#include "llvm/Support/ErrorOr.h"
19#include "llvm/Support/Format.h"
Mike Aizatsky17dbc282016-01-09 00:14:35 +000020#include "llvm/Support/LineIterator.h"
Eugene Zelenko417d4c52016-05-09 23:11:38 +000021#include "llvm/Support/MemoryBuffer.h"
22#include "llvm/Support/raw_ostream.h"
23#include <algorithm>
24#include <cmath>
25#include <cstddef>
26#include <cstdint>
27#include <memory>
28#include <string>
Alexey Samsonovd6aa8202015-11-03 22:20:52 +000029
30namespace llvm {
31namespace symbolize {
32
33// By default, DILineInfo contains "<invalid>" for function/filename it
34// cannot fetch. We replace it to "??" to make our output closer to addr2line.
35static const char kDILineInfoBadString[] = "<invalid>";
36static const char kBadString[] = "??";
37
Mike Aizatsky17dbc282016-01-09 00:14:35 +000038// Prints source code around in the FileName the Line.
39void DIPrinter::printContext(std::string FileName, int64_t Line) {
40 if (PrintSourceContext <= 0)
41 return;
42
43 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
44 MemoryBuffer::getFile(FileName);
45 if (!BufOrErr)
46 return;
47
48 std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
Mike Aizatsky6129dac2016-01-09 00:31:56 +000049 int64_t FirstLine =
50 std::max(static_cast<int64_t>(1), Line - PrintSourceContext / 2);
Mike Aizatsky17dbc282016-01-09 00:14:35 +000051 int64_t LastLine = FirstLine + PrintSourceContext;
52 size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
53
54 for (line_iterator I = line_iterator(*Buf, false);
55 !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
56 int64_t L = I.line_number();
57 if (L >= FirstLine && L <= LastLine) {
58 OS << format_decimal(L, MaxLineNumberWidth);
59 if (L == Line)
60 OS << " >: ";
61 else
62 OS << " : ";
63 OS << *I << "\n";
64 }
65 }
66}
67
68void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
Alexey Samsonovd6aa8202015-11-03 22:20:52 +000069 if (PrintFunctionNames) {
70 std::string FunctionName = Info.FunctionName;
71 if (FunctionName == kDILineInfoBadString)
72 FunctionName = kBadString;
Hemant Kulkarnibdce12a2015-11-11 20:41:43 +000073
Eugene Zelenko417d4c52016-05-09 23:11:38 +000074 StringRef Delimiter = PrintPretty ? " at " : "\n";
Hemant Kulkarnibdce12a2015-11-11 20:41:43 +000075 StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
76 OS << Prefix << FunctionName << Delimiter;
Alexey Samsonovd6aa8202015-11-03 22:20:52 +000077 }
78 std::string Filename = Info.FileName;
79 if (Filename == kDILineInfoBadString)
80 Filename = kBadString;
81 OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n";
Mike Aizatsky17dbc282016-01-09 00:14:35 +000082 printContext(Filename, Info.Line);
Hemant Kulkarnibdce12a2015-11-11 20:41:43 +000083}
84
85DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
Mike Aizatsky17dbc282016-01-09 00:14:35 +000086 print(Info, false);
Alexey Samsonovd6aa8202015-11-03 22:20:52 +000087 return *this;
88}
89
90DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
91 uint32_t FramesNum = Info.getNumberOfFrames();
Hemant Kulkarnibdce12a2015-11-11 20:41:43 +000092 if (FramesNum == 0) {
Mike Aizatsky17dbc282016-01-09 00:14:35 +000093 print(DILineInfo(), false);
Hemant Kulkarnibdce12a2015-11-11 20:41:43 +000094 return *this;
Alexey Samsonovd6aa8202015-11-03 22:20:52 +000095 }
Hemant Kulkarnibdce12a2015-11-11 20:41:43 +000096 for (uint32_t i = 0; i < FramesNum; i++)
Mike Aizatsky17dbc282016-01-09 00:14:35 +000097 print(Info.getFrame(i), i > 0);
Alexey Samsonovd6aa8202015-11-03 22:20:52 +000098 return *this;
99}
100
101DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
102 std::string Name = Global.Name;
103 if (Name == kDILineInfoBadString)
104 Name = kBadString;
105 OS << Name << "\n";
106 OS << Global.Start << " " << Global.Size << "\n";
107 return *this;
108}
109
Eugene Zelenko417d4c52016-05-09 23:11:38 +0000110} // end namespace symbolize
111} // end namespace llvm