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