File indexing completed on 2026-05-10 08:42:47
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_EXPRESSION_DIAGNOSTICMANAGER_H
0010 #define LLDB_EXPRESSION_DIAGNOSTICMANAGER_H
0011
0012 #include "lldb/lldb-defines.h"
0013 #include "lldb/lldb-types.h"
0014
0015 #include "lldb/Utility/DiagnosticsRendering.h"
0016 #include "lldb/Utility/FileSpec.h"
0017 #include "lldb/Utility/Status.h"
0018
0019 #include "llvm/ADT/STLExtras.h"
0020 #include "llvm/ADT/StringRef.h"
0021
0022 #include <string>
0023 #include <vector>
0024
0025 namespace lldb_private {
0026
0027
0028
0029 class ExpressionError
0030 : public llvm::ErrorInfo<ExpressionError, DiagnosticError> {
0031 std::string m_message;
0032 std::vector<DiagnosticDetail> m_details;
0033
0034 public:
0035 static char ID;
0036 using llvm::ErrorInfo<ExpressionError, DiagnosticError>::ErrorInfo;
0037 ExpressionError(lldb::ExpressionResults result, std::string msg,
0038 std::vector<DiagnosticDetail> details = {});
0039 std::string message() const override;
0040 llvm::ArrayRef<DiagnosticDetail> GetDetails() const override {
0041 return m_details;
0042 }
0043 std::error_code convertToErrorCode() const override;
0044 void log(llvm::raw_ostream &OS) const override;
0045 std::unique_ptr<CloneableError> Clone() const override;
0046 };
0047
0048 enum DiagnosticOrigin {
0049 eDiagnosticOriginUnknown = 0,
0050 eDiagnosticOriginLLDB,
0051 eDiagnosticOriginClang,
0052 eDiagnosticOriginSwift,
0053 eDiagnosticOriginLLVM
0054 };
0055
0056 const uint32_t LLDB_INVALID_COMPILER_ID = UINT32_MAX;
0057
0058 class Diagnostic {
0059 friend class DiagnosticManager;
0060
0061 public:
0062 DiagnosticOrigin getKind() const { return m_origin; }
0063
0064 static bool classof(const Diagnostic *diag) {
0065 DiagnosticOrigin kind = diag->getKind();
0066 switch (kind) {
0067 case eDiagnosticOriginUnknown:
0068 case eDiagnosticOriginLLDB:
0069 case eDiagnosticOriginLLVM:
0070 return true;
0071 case eDiagnosticOriginClang:
0072 case eDiagnosticOriginSwift:
0073 return false;
0074 }
0075 }
0076
0077 Diagnostic(DiagnosticOrigin origin, uint32_t compiler_id,
0078 DiagnosticDetail detail)
0079 : m_origin(origin), m_compiler_id(compiler_id), m_detail(detail) {}
0080
0081 virtual ~Diagnostic() = default;
0082
0083 virtual bool HasFixIts() const { return false; }
0084
0085 lldb::Severity GetSeverity() const { return m_detail.severity; }
0086
0087 uint32_t GetCompilerID() const { return m_compiler_id; }
0088
0089 llvm::StringRef GetMessage() const { return m_detail.message; }
0090 const DiagnosticDetail &GetDetail() const { return m_detail; }
0091
0092 void AppendMessage(llvm::StringRef message, bool precede_with_newline = true);
0093
0094 protected:
0095 DiagnosticOrigin m_origin;
0096
0097 uint32_t m_compiler_id;
0098 DiagnosticDetail m_detail;
0099 };
0100
0101 typedef std::vector<std::unique_ptr<Diagnostic>> DiagnosticList;
0102
0103 class DiagnosticManager {
0104 public:
0105 void Clear() {
0106 m_diagnostics.clear();
0107 m_fixed_expression.clear();
0108 }
0109
0110 const DiagnosticList &Diagnostics() { return m_diagnostics; }
0111
0112 bool HasFixIts() const {
0113 return llvm::any_of(m_diagnostics,
0114 [](const std::unique_ptr<Diagnostic> &diag) {
0115 return diag->HasFixIts();
0116 });
0117 }
0118
0119 void AddDiagnostic(llvm::StringRef message, lldb::Severity severity,
0120 DiagnosticOrigin origin,
0121 uint32_t compiler_id = LLDB_INVALID_COMPILER_ID);
0122
0123 void AddDiagnostic(std::unique_ptr<Diagnostic> diagnostic) {
0124 if (diagnostic)
0125 m_diagnostics.push_back(std::move(diagnostic));
0126 }
0127
0128
0129
0130 void Consume(DiagnosticManager &&other) {
0131 std::move(other.m_diagnostics.begin(), other.m_diagnostics.end(),
0132 std::back_inserter(m_diagnostics));
0133 m_fixed_expression = std::move(other.m_fixed_expression);
0134 other.Clear();
0135 }
0136
0137 size_t Printf(lldb::Severity severity, const char *format, ...)
0138 __attribute__((format(printf, 3, 4)));
0139 void PutString(lldb::Severity severity, llvm::StringRef str);
0140
0141 void AppendMessageToDiagnostic(llvm::StringRef str) {
0142 if (!m_diagnostics.empty())
0143 m_diagnostics.back()->AppendMessage(str);
0144 }
0145
0146
0147 llvm::Error GetAsError(lldb::ExpressionResults result,
0148 llvm::Twine message = {}) const;
0149
0150
0151
0152
0153
0154
0155 std::string GetString(char separator = '\n');
0156
0157 void Dump(Log *log);
0158
0159 const std::string &GetFixedExpression() { return m_fixed_expression; }
0160
0161
0162 void SetFixedExpression(std::string fixed_expression) {
0163 m_fixed_expression = std::move(fixed_expression);
0164 }
0165
0166 protected:
0167 DiagnosticList m_diagnostics;
0168 std::string m_fixed_expression;
0169 };
0170 }
0171
0172 #endif