1303241Sdim//===-- DiagnosticManager.h -------------------------------------*- C++ -*-===// 2303241Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6303241Sdim// 7303241Sdim//===----------------------------------------------------------------------===// 8303241Sdim 9303241Sdim#ifndef lldb_DiagnosticManager_h 10303241Sdim#define lldb_DiagnosticManager_h 11303241Sdim 12303241Sdim#include "lldb/lldb-defines.h" 13303241Sdim#include "lldb/lldb-types.h" 14303241Sdim 15360784Sdim#include "llvm/ADT/STLExtras.h" 16314564Sdim#include "llvm/ADT/StringRef.h" 17314564Sdim 18303241Sdim#include <string> 19303241Sdim#include <vector> 20303241Sdim 21314564Sdimnamespace lldb_private { 22303241Sdim 23314564Sdimenum DiagnosticOrigin { 24314564Sdim eDiagnosticOriginUnknown = 0, 25314564Sdim eDiagnosticOriginLLDB, 26314564Sdim eDiagnosticOriginClang, 27314564Sdim eDiagnosticOriginSwift, 28314564Sdim eDiagnosticOriginLLVM 29303241Sdim}; 30303241Sdim 31314564Sdimenum DiagnosticSeverity { 32314564Sdim eDiagnosticSeverityError, 33314564Sdim eDiagnosticSeverityWarning, 34314564Sdim eDiagnosticSeverityRemark 35303241Sdim}; 36303241Sdim 37303241Sdimconst uint32_t LLDB_INVALID_COMPILER_ID = UINT32_MAX; 38303241Sdim 39314564Sdimclass Diagnostic { 40314564Sdim friend class DiagnosticManager; 41303241Sdim 42303241Sdimpublic: 43314564Sdim DiagnosticOrigin getKind() const { return m_origin; } 44314564Sdim 45314564Sdim static bool classof(const Diagnostic *diag) { 46314564Sdim DiagnosticOrigin kind = diag->getKind(); 47314564Sdim switch (kind) { 48314564Sdim case eDiagnosticOriginUnknown: 49314564Sdim case eDiagnosticOriginLLDB: 50314564Sdim case eDiagnosticOriginLLVM: 51314564Sdim return true; 52314564Sdim case eDiagnosticOriginClang: 53314564Sdim case eDiagnosticOriginSwift: 54314564Sdim return false; 55303241Sdim } 56314564Sdim } 57303241Sdim 58314564Sdim Diagnostic(llvm::StringRef message, DiagnosticSeverity severity, 59314564Sdim DiagnosticOrigin origin, uint32_t compiler_id) 60314564Sdim : m_message(message), m_severity(severity), m_origin(origin), 61314564Sdim m_compiler_id(compiler_id) {} 62314564Sdim 63314564Sdim Diagnostic(const Diagnostic &rhs) 64314564Sdim : m_message(rhs.m_message), m_severity(rhs.m_severity), 65314564Sdim m_origin(rhs.m_origin), m_compiler_id(rhs.m_compiler_id) {} 66314564Sdim 67314564Sdim virtual ~Diagnostic() = default; 68314564Sdim 69314564Sdim virtual bool HasFixIts() const { return false; } 70314564Sdim 71314564Sdim DiagnosticSeverity GetSeverity() const { return m_severity; } 72314564Sdim 73314564Sdim uint32_t GetCompilerID() const { return m_compiler_id; } 74314564Sdim 75314564Sdim llvm::StringRef GetMessage() const { return m_message; } 76314564Sdim 77314564Sdim void AppendMessage(llvm::StringRef message, 78314564Sdim bool precede_with_newline = true) { 79314564Sdim if (precede_with_newline) 80314564Sdim m_message.push_back('\n'); 81314564Sdim m_message.append(message); 82314564Sdim } 83314564Sdim 84303241Sdimprotected: 85314564Sdim std::string m_message; 86314564Sdim DiagnosticSeverity m_severity; 87314564Sdim DiagnosticOrigin m_origin; 88314564Sdim uint32_t m_compiler_id; // Compiler-specific diagnostic ID 89303241Sdim}; 90303241Sdim 91360784Sdimtypedef std::vector<std::unique_ptr<Diagnostic>> DiagnosticList; 92303241Sdim 93314564Sdimclass DiagnosticManager { 94303241Sdimpublic: 95314564Sdim void Clear() { 96314564Sdim m_diagnostics.clear(); 97314564Sdim m_fixed_expression.clear(); 98314564Sdim } 99314564Sdim 100314564Sdim const DiagnosticList &Diagnostics() { return m_diagnostics; } 101314564Sdim 102360784Sdim bool HasFixIts() const { 103360784Sdim return llvm::any_of(m_diagnostics, 104360784Sdim [](const std::unique_ptr<Diagnostic> &diag) { 105360784Sdim return diag->HasFixIts(); 106360784Sdim }); 107314564Sdim } 108303241Sdim 109314564Sdim void AddDiagnostic(llvm::StringRef message, DiagnosticSeverity severity, 110314564Sdim DiagnosticOrigin origin, 111314564Sdim uint32_t compiler_id = LLDB_INVALID_COMPILER_ID) { 112360784Sdim m_diagnostics.emplace_back( 113360784Sdim std::make_unique<Diagnostic>(message, severity, origin, compiler_id)); 114314564Sdim } 115303241Sdim 116360784Sdim void AddDiagnostic(std::unique_ptr<Diagnostic> diagnostic) { 117360784Sdim m_diagnostics.push_back(std::move(diagnostic)); 118314564Sdim } 119314564Sdim 120314564Sdim size_t Printf(DiagnosticSeverity severity, const char *format, ...) 121314564Sdim __attribute__((format(printf, 3, 4))); 122360784Sdim void PutString(DiagnosticSeverity severity, llvm::StringRef str); 123314564Sdim 124314564Sdim void AppendMessageToDiagnostic(llvm::StringRef str) { 125360784Sdim if (!m_diagnostics.empty()) 126314564Sdim m_diagnostics.back()->AppendMessage(str); 127314564Sdim } 128303241Sdim 129314564Sdim // Returns a string containing errors in this format: 130314564Sdim // 131314564Sdim // "error: error text\n 132314564Sdim // warning: warning text\n 133314564Sdim // remark text\n" 134314564Sdim std::string GetString(char separator = '\n'); 135314564Sdim 136314564Sdim void Dump(Log *log); 137314564Sdim 138314564Sdim const std::string &GetFixedExpression() { return m_fixed_expression; } 139314564Sdim 140314564Sdim // Moves fixed_expression to the internal storage. 141314564Sdim void SetFixedExpression(std::string fixed_expression) { 142314564Sdim m_fixed_expression = std::move(fixed_expression); 143314564Sdim } 144314564Sdim 145303241Sdimprotected: 146314564Sdim DiagnosticList m_diagnostics; 147314564Sdim std::string m_fixed_expression; 148303241Sdim}; 149303241Sdim} 150303241Sdim 151303241Sdim#endif /* lldb_DiagnosticManager_h */ 152