• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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