1 //===- llvm/DebugInfo/Symbolize/DIPrinter.h ---------------------*- C++ -*-===//
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 declares the DIPrinter class, which is responsible for printing
10 // structures defined in DebugInfo/DIContext.h
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H
15 #define LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H
16 
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/JSON.h"
20 #include <memory>
21 #include <vector>
22 
23 namespace llvm {
24 struct DILineInfo;
25 class DIInliningInfo;
26 struct DIGlobal;
27 struct DILocal;
28 class ErrorInfoBase;
29 class raw_ostream;
30 
31 namespace symbolize {
32 
33 class SourceCode;
34 
35 struct Request {
36   StringRef ModuleName;
37   Optional<uint64_t> Address;
38 };
39 
40 class DIPrinter {
41 public:
42   DIPrinter() = default;
43   virtual ~DIPrinter() = default;
44 
45   virtual void print(const Request &Request, const DILineInfo &Info) = 0;
46   virtual void print(const Request &Request, const DIInliningInfo &Info) = 0;
47   virtual void print(const Request &Request, const DIGlobal &Global) = 0;
48   virtual void print(const Request &Request,
49                      const std::vector<DILocal> &Locals) = 0;
50 
51   virtual void printInvalidCommand(const Request &Request,
52                                    StringRef Command) = 0;
53 
54   virtual bool printError(const Request &Request,
55                           const ErrorInfoBase &ErrorInfo,
56                           StringRef ErrorBanner) = 0;
57 
58   virtual void listBegin() = 0;
59   virtual void listEnd() = 0;
60 };
61 
62 struct PrinterConfig {
63   bool PrintAddress;
64   bool PrintFunctions;
65   bool Pretty;
66   bool Verbose;
67   int SourceContextLines;
68 };
69 
70 class PlainPrinterBase : public DIPrinter {
71 protected:
72   raw_ostream &OS;
73   raw_ostream &ES;
74   PrinterConfig Config;
75 
76   void print(const DILineInfo &Info, bool Inlined);
77   void printFunctionName(StringRef FunctionName, bool Inlined);
78   virtual void printSimpleLocation(StringRef Filename,
79                                    const DILineInfo &Info) = 0;
80   void printContext(SourceCode SourceCode);
81   void printVerbose(StringRef Filename, const DILineInfo &Info);
82   virtual void printStartAddress(const DILineInfo &Info) {}
83   virtual void printFooter() {}
84 
85 private:
86   void printHeader(uint64_t Address);
87 
88 public:
89   PlainPrinterBase(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
90       : OS(OS), ES(ES), Config(Config) {}
91 
92   void print(const Request &Request, const DILineInfo &Info) override;
93   void print(const Request &Request, const DIInliningInfo &Info) override;
94   void print(const Request &Request, const DIGlobal &Global) override;
95   void print(const Request &Request,
96              const std::vector<DILocal> &Locals) override;
97 
98   void printInvalidCommand(const Request &Request, StringRef Command) override;
99 
100   bool printError(const Request &Request, const ErrorInfoBase &ErrorInfo,
101                   StringRef ErrorBanner) override;
102 
103   void listBegin() override {}
104   void listEnd() override {}
105 };
106 
107 class LLVMPrinter : public PlainPrinterBase {
108 private:
109   void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
110   void printStartAddress(const DILineInfo &Info) override;
111   void printFooter() override;
112 
113 public:
114   LLVMPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
115       : PlainPrinterBase(OS, ES, Config) {}
116 };
117 
118 class GNUPrinter : public PlainPrinterBase {
119 private:
120   void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
121 
122 public:
123   GNUPrinter(raw_ostream &OS, raw_ostream &ES, PrinterConfig &Config)
124       : PlainPrinterBase(OS, ES, Config) {}
125 };
126 
127 class JSONPrinter : public DIPrinter {
128 private:
129   raw_ostream &OS;
130   PrinterConfig Config;
131   std::unique_ptr<json::Array> ObjectList;
132 
133   void printJSON(const json::Value &V) {
134     json::OStream JOS(OS, Config.Pretty ? 2 : 0);
135     JOS.value(V);
136     OS << '\n';
137   }
138 
139 public:
140   JSONPrinter(raw_ostream &OS, PrinterConfig &Config)
141       : OS(OS), Config(Config) {}
142 
143   void print(const Request &Request, const DILineInfo &Info) override;
144   void print(const Request &Request, const DIInliningInfo &Info) override;
145   void print(const Request &Request, const DIGlobal &Global) override;
146   void print(const Request &Request,
147              const std::vector<DILocal> &Locals) override;
148 
149   void printInvalidCommand(const Request &Request, StringRef Command) override;
150 
151   bool printError(const Request &Request, const ErrorInfoBase &ErrorInfo,
152                   StringRef ErrorBanner) override;
153 
154   void listBegin() override;
155   void listEnd() override;
156 };
157 } // namespace symbolize
158 } // namespace llvm
159 
160 #endif
161