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) = 0;
55 
56   virtual void listBegin() = 0;
57   virtual void listEnd() = 0;
58 };
59 
60 struct PrinterConfig {
61   bool PrintAddress;
62   bool PrintFunctions;
63   bool Pretty;
64   bool Verbose;
65   int SourceContextLines;
66 };
67 
68 using ErrorHandler = function_ref<void(const ErrorInfoBase &, StringRef)>;
69 
70 class PlainPrinterBase : public DIPrinter {
71 protected:
72   raw_ostream &OS;
73   ErrorHandler ErrHandler;
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, ErrorHandler EH, PrinterConfig &Config)
90       : OS(OS), ErrHandler(EH), 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,
101                   const ErrorInfoBase &ErrorInfo) 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, ErrorHandler EH, PrinterConfig &Config)
115       : PlainPrinterBase(OS, EH, 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, ErrorHandler EH, PrinterConfig &Config)
124       : PlainPrinterBase(OS, EH, Config) {}
125 
126 };
127 
128 class JSONPrinter : public DIPrinter {
129 private:
130   raw_ostream &OS;
131   PrinterConfig Config;
132   std::unique_ptr<json::Array> ObjectList;
133 
134   void printJSON(const json::Value &V) {
135     json::OStream JOS(OS, Config.Pretty ? 2 : 0);
136     JOS.value(V);
137     OS << '\n';
138   }
139 
140 public:
141   JSONPrinter(raw_ostream &OS, PrinterConfig &Config)
142       : OS(OS), Config(Config) {}
143 
144   void print(const Request &Request, const DILineInfo &Info) override;
145   void print(const Request &Request, const DIInliningInfo &Info) override;
146   void print(const Request &Request, const DIGlobal &Global) override;
147   void print(const Request &Request,
148              const std::vector<DILocal> &Locals) override;
149 
150   void printInvalidCommand(const Request &Request, StringRef Command) override;
151 
152   bool printError(const Request &Request,
153                   const ErrorInfoBase &ErrorInfo) override;
154 
155   void listBegin() override;
156   void listEnd() override;
157 };
158 } // namespace symbolize
159 } // namespace llvm
160 
161 #endif
162