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