Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:47

0001 //===-- DiagnosticManager.h -------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 /// An llvm::Error used to communicate diagnostics in Status. Multiple
0028 /// diagnostics may be chained in an llvm::ErrorList.
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   /// Compiler-specific diagnostic ID.
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   /// Moves over the contents of a second diagnostic manager over. Leaves other
0129   /// diagnostic manager in an empty state.
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   /// Returns an \ref ExpressionError with \c arg as error code.
0147   llvm::Error GetAsError(lldb::ExpressionResults result,
0148                          llvm::Twine message = {}) const;
0149 
0150   // Returns a string containing errors in this format:
0151   //
0152   // "error: error text\n
0153   // warning: warning text\n
0154   // remark text\n"
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   // Moves fixed_expression to the internal storage.
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 // LLDB_EXPRESSION_DIAGNOSTICMANAGER_H