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