xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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/Compiler.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   std::optional<uint64_t> Address;
38   StringRef Symbol;
39 };
40 
41 class DIPrinter {
42 public:
43   DIPrinter() = default;
44   virtual ~DIPrinter() = default;
45 
46   virtual void print(const Request &Request, const DILineInfo &Info) = 0;
47   virtual void print(const Request &Request, const DIInliningInfo &Info) = 0;
48   virtual void print(const Request &Request, const DIGlobal &Global) = 0;
49   virtual void print(const Request &Request,
50                      const std::vector<DILocal> &Locals) = 0;
51   virtual void print(const Request &Request,
52                      const std::vector<DILineInfo> &Locations) = 0;
53 
54   virtual bool printError(const Request &Request,
55                           const ErrorInfoBase &ErrorInfo) = 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 using ErrorHandler = std::function<void(const ErrorInfoBase &, StringRef)>;
70 
71 class LLVM_ABI PlainPrinterBase : public DIPrinter {
72 protected:
73   raw_ostream &OS;
74   ErrorHandler ErrHandler;
75   PrinterConfig Config;
76 
77   void print(const DILineInfo &Info, bool Inlined);
78   void printFunctionName(StringRef FunctionName, bool Inlined);
79   virtual void printSimpleLocation(StringRef Filename,
80                                    const DILineInfo &Info) = 0;
81   void printContext(SourceCode SourceCode);
82   void printVerbose(StringRef Filename, const DILineInfo &Info);
printStartAddress(const DILineInfo & Info)83   virtual void printStartAddress(const DILineInfo &Info) {}
printFooter()84   virtual void printFooter() {}
85 
86 private:
87   void printHeader(std::optional<uint64_t> Address);
88 
89 public:
PlainPrinterBase(raw_ostream & OS,ErrorHandler EH,PrinterConfig & Config)90   PlainPrinterBase(raw_ostream &OS, ErrorHandler EH, PrinterConfig &Config)
91       : OS(OS), ErrHandler(EH), Config(Config) {}
92 
93   void print(const Request &Request, const DILineInfo &Info) override;
94   void print(const Request &Request, const DIInliningInfo &Info) override;
95   void print(const Request &Request, const DIGlobal &Global) override;
96   void print(const Request &Request,
97              const std::vector<DILocal> &Locals) override;
98   void print(const Request &Request,
99              const std::vector<DILineInfo> &Locations) override;
100 
101   bool printError(const Request &Request,
102                   const ErrorInfoBase &ErrorInfo) override;
103 
listBegin()104   void listBegin() override {}
listEnd()105   void listEnd() override {}
106 };
107 
108 class LLVM_ABI LLVMPrinter : public PlainPrinterBase {
109 private:
110   void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
111   void printStartAddress(const DILineInfo &Info) override;
112   void printFooter() override;
113 
114 public:
LLVMPrinter(raw_ostream & OS,ErrorHandler EH,PrinterConfig & Config)115   LLVMPrinter(raw_ostream &OS, ErrorHandler EH, PrinterConfig &Config)
116       : PlainPrinterBase(OS, EH, Config) {}
117 };
118 
119 class LLVM_ABI GNUPrinter : public PlainPrinterBase {
120 private:
121   void printSimpleLocation(StringRef Filename, const DILineInfo &Info) override;
122 
123 public:
GNUPrinter(raw_ostream & OS,ErrorHandler EH,PrinterConfig & Config)124   GNUPrinter(raw_ostream &OS, ErrorHandler EH, PrinterConfig &Config)
125       : PlainPrinterBase(OS, EH, Config) {}
126 };
127 
128 class LLVM_ABI JSONPrinter : public DIPrinter {
129 private:
130   raw_ostream &OS;
131   PrinterConfig Config;
132   std::unique_ptr<json::Array> ObjectList;
133 
printJSON(const json::Value & V)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:
JSONPrinter(raw_ostream & OS,PrinterConfig & Config)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   void print(const Request &Request,
150              const std::vector<DILineInfo> &Locations) 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