LLVM  10.0.0svn
DIPrinter.cpp
Go to the documentation of this file.
1 //===- lib/DebugInfo/Symbolize/DIPrinter.cpp ------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the DIPrinter class, which is responsible for printing
10 // structures defined in DebugInfo/DIContext.h
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/StringRef.h"
17 #include "llvm/Support/ErrorOr.h"
18 #include "llvm/Support/Format.h"
21 #include "llvm/Support/Path.h"
23 #include <algorithm>
24 #include <cmath>
25 #include <cstddef>
26 #include <cstdint>
27 #include <memory>
28 #include <string>
29 
30 namespace llvm {
31 namespace symbolize {
32 
33 // Prints source code around in the FileName the Line.
34 void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
35  if (PrintSourceContext <= 0)
36  return;
37 
38  ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
39  MemoryBuffer::getFile(FileName);
40  if (!BufOrErr)
41  return;
42 
43  std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
44  int64_t FirstLine =
45  std::max(static_cast<int64_t>(1), Line - PrintSourceContext / 2);
46  int64_t LastLine = FirstLine + PrintSourceContext;
47  size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
48 
49  for (line_iterator I = line_iterator(*Buf, false);
50  !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
51  int64_t L = I.line_number();
52  if (L >= FirstLine && L <= LastLine) {
53  OS << format_decimal(L, MaxLineNumberWidth);
54  if (L == Line)
55  OS << " >: ";
56  else
57  OS << " : ";
58  OS << *I << "\n";
59  }
60  }
61 }
62 
63 void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
64  if (PrintFunctionNames) {
65  std::string FunctionName = Info.FunctionName;
66  if (FunctionName == DILineInfo::BadString)
67  FunctionName = DILineInfo::Addr2LineBadString;
68 
69  StringRef Delimiter = PrintPretty ? " at " : "\n";
70  StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
71  OS << Prefix << FunctionName << Delimiter;
72  }
73  std::string Filename = Info.FileName;
74  if (Filename == DILineInfo::BadString)
76  else if (Basenames)
77  Filename = llvm::sys::path::filename(Filename);
78  if (!Verbose) {
79  OS << Filename << ":" << Info.Line;
80  if (Style == OutputStyle::LLVM)
81  OS << ":" << Info.Column;
82  OS << "\n";
83  printContext(Filename, Info.Line);
84  return;
85  }
86  OS << " Filename: " << Filename << "\n";
87  if (Info.StartLine)
88  OS << "Function start line: " << Info.StartLine << "\n";
89  OS << " Line: " << Info.Line << "\n";
90  OS << " Column: " << Info.Column << "\n";
91  if (Info.Discriminator)
92  OS << " Discriminator: " << Info.Discriminator << "\n";
93 }
94 
96  print(Info, false);
97  return *this;
98 }
99 
101  uint32_t FramesNum = Info.getNumberOfFrames();
102  if (FramesNum == 0) {
103  print(DILineInfo(), false);
104  return *this;
105  }
106  for (uint32_t i = 0; i < FramesNum; i++)
107  print(Info.getFrame(i), i > 0);
108  return *this;
109 }
110 
112  std::string Name = Global.Name;
113  if (Name == DILineInfo::BadString)
115  OS << Name << "\n";
116  OS << Global.Start << " " << Global.Size << "\n";
117  return *this;
118 }
119 
121  OS << Local.FunctionName << '\n';
122  OS << Local.Name << '\n';
123  if (Local.DeclFile.empty())
124  OS << "??";
125  else
126  OS << Local.DeclFile;
127  OS << ':' << Local.DeclLine << '\n';
128  if (Local.FrameOffset)
129  OS << *Local.FrameOffset << ' ';
130  else
131  OS << "?? ";
132  if (Local.Size)
133  OS << *Local.Size << ' ';
134  else
135  OS << "?? ";
136  if (Local.TagOffset)
137  OS << *Local.TagOffset << '\n';
138  else
139  OS << "??\n";
140  return *this;
141 }
142 
143 } // end namespace symbolize
144 } // end namespace llvm
std::string DeclFile
Definition: DIContext.h:122
Optional< int64_t > FrameOffset
Definition: DIContext.h:124
This class represents lattice values for constants.
Definition: AllocatorList.h:23
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
Optional< uint64_t > TagOffset
Definition: DIContext.h:126
DIPrinter & operator<<(const DILineInfo &Info)
Definition: DIPrinter.cpp:95
A format-neutral container for source line information.
Definition: DIContext.h:30
static constexpr const char *const Addr2LineBadString
Definition: DIContext.h:34
uint64_t Start
Definition: DIContext.h:113
uint32_t getNumberOfFrames() const
Definition: DIContext.h:97
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
uint64_t DeclLine
Definition: DIContext.h:123
A format-neutral container for inlined code description.
Definition: DIContext.h:81
static constexpr const char *const BadString
Definition: DIContext.h:32
std::string Name
Definition: DIContext.h:121
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:379
std::string Name
Definition: DIContext.h:112
uint64_t Size
Definition: DIContext.h:114
FormattedNumber format_decimal(int64_t N, unsigned Width)
format_decimal - Output N as a right justified, fixed-width decimal.
Definition: Format.h:211
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:565
Optional< uint64_t > Size
Definition: DIContext.h:125
#define I(x, y, z)
Definition: MD5.cpp:58
Provides ErrorOr<T> smart pointer.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
std::string FunctionName
Definition: DIContext.h:120
const DILineInfo & getFrame(unsigned Index) const
Definition: DIContext.h:87
Container for description of a global variable.
Definition: DIContext.h:111