aboutsummaryrefslogtreecommitdiff
path: root/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
blob: 4bb11bf62593a078a92a06a3e38eddfbbd812794 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//===- llvm/DebugInfo/Symbolize/DIPrinter.h ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the DIPrinter class, which is responsible for printing
// structures defined in DebugInfo/DIContext.h
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H
#define LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H

#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/JSON.h"
#include <memory>
#include <vector>

namespace llvm {
struct DILineInfo;
class DIInliningInfo;
struct DIGlobal;
struct DILocal;
class ErrorInfoBase;
class raw_ostream;

namespace symbolize {

class SourceCode;

struct Request {
  StringRef ModuleName;
  Optional<uint64_t> Address;
};

class DIPrinter {
public:
  DIPrinter() {}
  virtual ~DIPrinter() {}

  virtual void print(const Request &Request, const DILineInfo &Info) = 0;
  virtual void print(const Request &Request, const DIInliningInfo &Info) = 0;
  virtual void print(const Request &Request, const DIGlobal &Global) = 0;
  virtual void print(const Request &Request,
                     const std::vector<DILocal> &Locals) = 0;

  virtual void printInvalidCommand(const Request &Request,
                                   StringRef Command) = 0;

  virtual bool printError(const Request &Request,
                          const ErrorInfoBase &ErrorInfo,
                          StringRef ErrorBanner) = 0;

  virtual void listBegin() = 0;
  virtual void listEnd() = 0;
};

struct PrinterConfig {
  bool PrintAddress;
  bool PrintFunctions;
  bool Pretty;
  bool Verbose;
  int SourceContextLines;
};

class PlainPrinterBase : public DIPrinter {
protected:
  raw_ostream &OS;
  raw_ostream &ES;
  PrinterConfig Config;

  void print(const DILineInfo &Info, bool Inlined);
  void printFunctionName(StringRef FunctionName, bool Inlined);
  virtual void printSimpleLocation(StringRef Filename,
                                   const DILineInfo &Info) = 0;
  void printContext(SourceCode SourceCode);
  void printVerbose(StringRef Filename, const DILineInfo &Info);
  virtual void printStartAddress(const DILineInfo &Info) {}
  virtual void printFooter() {}

private:
  void printHeader(uint64_t Address);

public:
  PlainPrinterBase(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
      : DIPrinter(), OS(OS), ES(ES), Config(Config) {}

  void print(const Request &Request, const DILineInfo &Info) override;
  void print(const Request &Request, const DIInliningInfo &Info) override;
  void print(const Request &Request, const DIGlobal &Global) override;
  void print(const Request &Request,
             const std::vector<DILocal> &Locals) override;

  void printInvalidCommand(const Request &Request, StringRef Command) override;

  bool printError(const Request &Request, const ErrorInfoBase &ErrorInfo,
                  StringRef ErrorBanner) override;

  void listBegin() override {}
  void listEnd() override {}
};

class LLVMPrinter : public PlainPrinterBase {
private:
  void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
  void printStartAddress(const DILineInfo &Info) override;
  void printFooter() override;

public:
  LLVMPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
      : PlainPrinterBase(OS, ES, Config) {}
};

class GNUPrinter : public PlainPrinterBase {
private:
  void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;

public:
  GNUPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
      : PlainPrinterBase(OS, ES, Config) {}
};

class JSONPrinter : public DIPrinter {
private:
  raw_ostream &OS;
  PrinterConfig Config;
  std::unique_ptr<json::Array> ObjectList;

  void printJSON(const json::Value &V) {
    json::OStream JOS(OS, Config.Pretty ? 2 : 0);
    JOS.value(V);
    OS << '\n';
  }

public:
  JSONPrinter(raw_ostream &OS, PrinterConfig &Config)
      : DIPrinter(), OS(OS), Config(Config) {}

  void print(const Request &Request, const DILineInfo &Info) override;
  void print(const Request &Request, const DIInliningInfo &Info) override;
  void print(const Request &Request, const DIGlobal &Global) override;
  void print(const Request &Request,
             const std::vector<DILocal> &Locals) override;

  void printInvalidCommand(const Request &Request, StringRef Command) override;

  bool printError(const Request &Request, const ErrorInfoBase &ErrorInfo,
                  StringRef ErrorBanner) override;

  void listBegin() override;
  void listEnd() override;
};
} // namespace symbolize
} // namespace llvm

#endif