1 //===-- DiagnosticManager.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 #ifndef LLDB_EXPRESSION_DIAGNOSTICMANAGER_H 10 #define LLDB_EXPRESSION_DIAGNOSTICMANAGER_H 11 12 #include "lldb/lldb-defines.h" 13 #include "lldb/lldb-types.h" 14 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/StringRef.h" 17 18 #include <string> 19 #include <vector> 20 21 namespace lldb_private { 22 23 enum DiagnosticOrigin { 24 eDiagnosticOriginUnknown = 0, 25 eDiagnosticOriginLLDB, 26 eDiagnosticOriginClang, 27 eDiagnosticOriginSwift, 28 eDiagnosticOriginLLVM 29 }; 30 31 enum DiagnosticSeverity { 32 eDiagnosticSeverityError, 33 eDiagnosticSeverityWarning, 34 eDiagnosticSeverityRemark 35 }; 36 37 const uint32_t LLDB_INVALID_COMPILER_ID = UINT32_MAX; 38 39 class Diagnostic { 40 friend class DiagnosticManager; 41 42 public: getKind()43 DiagnosticOrigin getKind() const { return m_origin; } 44 classof(const Diagnostic * diag)45 static bool classof(const Diagnostic *diag) { 46 DiagnosticOrigin kind = diag->getKind(); 47 switch (kind) { 48 case eDiagnosticOriginUnknown: 49 case eDiagnosticOriginLLDB: 50 case eDiagnosticOriginLLVM: 51 return true; 52 case eDiagnosticOriginClang: 53 case eDiagnosticOriginSwift: 54 return false; 55 } 56 } 57 Diagnostic(llvm::StringRef message,DiagnosticSeverity severity,DiagnosticOrigin origin,uint32_t compiler_id)58 Diagnostic(llvm::StringRef message, DiagnosticSeverity severity, 59 DiagnosticOrigin origin, uint32_t compiler_id) 60 : m_message(message), m_severity(severity), m_origin(origin), 61 m_compiler_id(compiler_id) {} 62 Diagnostic(const Diagnostic & rhs)63 Diagnostic(const Diagnostic &rhs) 64 : m_message(rhs.m_message), m_severity(rhs.m_severity), 65 m_origin(rhs.m_origin), m_compiler_id(rhs.m_compiler_id) {} 66 67 virtual ~Diagnostic() = default; 68 HasFixIts()69 virtual bool HasFixIts() const { return false; } 70 GetSeverity()71 DiagnosticSeverity GetSeverity() const { return m_severity; } 72 GetCompilerID()73 uint32_t GetCompilerID() const { return m_compiler_id; } 74 GetMessage()75 llvm::StringRef GetMessage() const { return m_message; } 76 77 void AppendMessage(llvm::StringRef message, 78 bool precede_with_newline = true) { 79 if (precede_with_newline) 80 m_message.push_back('\n'); 81 m_message += message; 82 } 83 84 protected: 85 std::string m_message; 86 DiagnosticSeverity m_severity; 87 DiagnosticOrigin m_origin; 88 uint32_t m_compiler_id; // Compiler-specific diagnostic ID 89 }; 90 91 typedef std::vector<std::unique_ptr<Diagnostic>> DiagnosticList; 92 93 class DiagnosticManager { 94 public: Clear()95 void Clear() { 96 m_diagnostics.clear(); 97 m_fixed_expression.clear(); 98 } 99 Diagnostics()100 const DiagnosticList &Diagnostics() { return m_diagnostics; } 101 HasFixIts()102 bool HasFixIts() const { 103 return llvm::any_of(m_diagnostics, 104 [](const std::unique_ptr<Diagnostic> &diag) { 105 return diag->HasFixIts(); 106 }); 107 } 108 109 void AddDiagnostic(llvm::StringRef message, DiagnosticSeverity severity, 110 DiagnosticOrigin origin, 111 uint32_t compiler_id = LLDB_INVALID_COMPILER_ID) { 112 m_diagnostics.emplace_back( 113 std::make_unique<Diagnostic>(message, severity, origin, compiler_id)); 114 } 115 AddDiagnostic(std::unique_ptr<Diagnostic> diagnostic)116 void AddDiagnostic(std::unique_ptr<Diagnostic> diagnostic) { 117 m_diagnostics.push_back(std::move(diagnostic)); 118 } 119 120 size_t Printf(DiagnosticSeverity severity, const char *format, ...) 121 __attribute__((format(printf, 3, 4))); 122 void PutString(DiagnosticSeverity severity, llvm::StringRef str); 123 AppendMessageToDiagnostic(llvm::StringRef str)124 void AppendMessageToDiagnostic(llvm::StringRef str) { 125 if (!m_diagnostics.empty()) 126 m_diagnostics.back()->AppendMessage(str); 127 } 128 129 // Returns a string containing errors in this format: 130 // 131 // "error: error text\n 132 // warning: warning text\n 133 // remark text\n" 134 std::string GetString(char separator = '\n'); 135 136 void Dump(Log *log); 137 GetFixedExpression()138 const std::string &GetFixedExpression() { return m_fixed_expression; } 139 140 // Moves fixed_expression to the internal storage. SetFixedExpression(std::string fixed_expression)141 void SetFixedExpression(std::string fixed_expression) { 142 m_fixed_expression = std::move(fixed_expression); 143 } 144 145 protected: 146 DiagnosticList m_diagnostics; 147 std::string m_fixed_expression; 148 }; 149 } 150 151 #endif // LLDB_EXPRESSION_DIAGNOSTICMANAGER_H 152