xref: /aosp_15_r20/external/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- lib/DebugInfo/Symbolize/DIPrinter.cpp ------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines the DIPrinter class, which is responsible for printing
11*9880d681SAndroid Build Coastguard Worker // structures defined in DebugInfo/DIContext.h
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/Symbolize/DIPrinter.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringRef.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DIContext.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorOr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/LineIterator.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
23*9880d681SAndroid Build Coastguard Worker #include <algorithm>
24*9880d681SAndroid Build Coastguard Worker #include <cmath>
25*9880d681SAndroid Build Coastguard Worker #include <cstddef>
26*9880d681SAndroid Build Coastguard Worker #include <cstdint>
27*9880d681SAndroid Build Coastguard Worker #include <memory>
28*9880d681SAndroid Build Coastguard Worker #include <string>
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker namespace llvm {
31*9880d681SAndroid Build Coastguard Worker namespace symbolize {
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker // By default, DILineInfo contains "<invalid>" for function/filename it
34*9880d681SAndroid Build Coastguard Worker // cannot fetch. We replace it to "??" to make our output closer to addr2line.
35*9880d681SAndroid Build Coastguard Worker static const char kDILineInfoBadString[] = "<invalid>";
36*9880d681SAndroid Build Coastguard Worker static const char kBadString[] = "??";
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker // Prints source code around in the FileName the Line.
printContext(const std::string & FileName,int64_t Line)39*9880d681SAndroid Build Coastguard Worker void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
40*9880d681SAndroid Build Coastguard Worker   if (PrintSourceContext <= 0)
41*9880d681SAndroid Build Coastguard Worker     return;
42*9880d681SAndroid Build Coastguard Worker 
43*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
44*9880d681SAndroid Build Coastguard Worker       MemoryBuffer::getFile(FileName);
45*9880d681SAndroid Build Coastguard Worker   if (!BufOrErr)
46*9880d681SAndroid Build Coastguard Worker     return;
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
49*9880d681SAndroid Build Coastguard Worker   int64_t FirstLine =
50*9880d681SAndroid Build Coastguard Worker       std::max(static_cast<int64_t>(1), Line - PrintSourceContext / 2);
51*9880d681SAndroid Build Coastguard Worker   int64_t LastLine = FirstLine + PrintSourceContext;
52*9880d681SAndroid Build Coastguard Worker   size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker   for (line_iterator I = line_iterator(*Buf, false);
55*9880d681SAndroid Build Coastguard Worker        !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
56*9880d681SAndroid Build Coastguard Worker     int64_t L = I.line_number();
57*9880d681SAndroid Build Coastguard Worker     if (L >= FirstLine && L <= LastLine) {
58*9880d681SAndroid Build Coastguard Worker       OS << format_decimal(L, MaxLineNumberWidth);
59*9880d681SAndroid Build Coastguard Worker       if (L == Line)
60*9880d681SAndroid Build Coastguard Worker         OS << " >: ";
61*9880d681SAndroid Build Coastguard Worker       else
62*9880d681SAndroid Build Coastguard Worker         OS << "  : ";
63*9880d681SAndroid Build Coastguard Worker       OS << *I << "\n";
64*9880d681SAndroid Build Coastguard Worker     }
65*9880d681SAndroid Build Coastguard Worker   }
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker 
print(const DILineInfo & Info,bool Inlined)68*9880d681SAndroid Build Coastguard Worker void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
69*9880d681SAndroid Build Coastguard Worker   if (PrintFunctionNames) {
70*9880d681SAndroid Build Coastguard Worker     std::string FunctionName = Info.FunctionName;
71*9880d681SAndroid Build Coastguard Worker     if (FunctionName == kDILineInfoBadString)
72*9880d681SAndroid Build Coastguard Worker       FunctionName = kBadString;
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker     StringRef Delimiter = PrintPretty ? " at " : "\n";
75*9880d681SAndroid Build Coastguard Worker     StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
76*9880d681SAndroid Build Coastguard Worker     OS << Prefix << FunctionName << Delimiter;
77*9880d681SAndroid Build Coastguard Worker   }
78*9880d681SAndroid Build Coastguard Worker   std::string Filename = Info.FileName;
79*9880d681SAndroid Build Coastguard Worker   if (Filename == kDILineInfoBadString)
80*9880d681SAndroid Build Coastguard Worker     Filename = kBadString;
81*9880d681SAndroid Build Coastguard Worker   OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n";
82*9880d681SAndroid Build Coastguard Worker   printContext(Filename, Info.Line);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker 
operator <<(const DILineInfo & Info)85*9880d681SAndroid Build Coastguard Worker DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
86*9880d681SAndroid Build Coastguard Worker   print(Info, false);
87*9880d681SAndroid Build Coastguard Worker   return *this;
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker 
operator <<(const DIInliningInfo & Info)90*9880d681SAndroid Build Coastguard Worker DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
91*9880d681SAndroid Build Coastguard Worker   uint32_t FramesNum = Info.getNumberOfFrames();
92*9880d681SAndroid Build Coastguard Worker   if (FramesNum == 0) {
93*9880d681SAndroid Build Coastguard Worker     print(DILineInfo(), false);
94*9880d681SAndroid Build Coastguard Worker     return *this;
95*9880d681SAndroid Build Coastguard Worker   }
96*9880d681SAndroid Build Coastguard Worker   for (uint32_t i = 0; i < FramesNum; i++)
97*9880d681SAndroid Build Coastguard Worker     print(Info.getFrame(i), i > 0);
98*9880d681SAndroid Build Coastguard Worker   return *this;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker 
operator <<(const DIGlobal & Global)101*9880d681SAndroid Build Coastguard Worker DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
102*9880d681SAndroid Build Coastguard Worker   std::string Name = Global.Name;
103*9880d681SAndroid Build Coastguard Worker   if (Name == kDILineInfoBadString)
104*9880d681SAndroid Build Coastguard Worker     Name = kBadString;
105*9880d681SAndroid Build Coastguard Worker   OS << Name << "\n";
106*9880d681SAndroid Build Coastguard Worker   OS << Global.Start << " " << Global.Size << "\n";
107*9880d681SAndroid Build Coastguard Worker   return *this;
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker } // end namespace symbolize
111*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
112