Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===-- Status.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_UTILITY_STATUS_H
0010 #define LLDB_UTILITY_STATUS_H
0011 
0012 #include "lldb/Utility/FileSpec.h"
0013 #include "lldb/Utility/StructuredData.h"
0014 #include "lldb/lldb-defines.h"
0015 #include "lldb/lldb-enumerations.h"
0016 #include "llvm/ADT/StringRef.h"
0017 #include "llvm/Support/Error.h"
0018 #include "llvm/Support/FormatVariadic.h"
0019 #include <cstdarg>
0020 #include <cstdint>
0021 #include <string>
0022 #include <system_error>
0023 #include <type_traits>
0024 
0025 namespace llvm {
0026 class raw_ostream;
0027 }
0028 
0029 namespace lldb_private {
0030 
0031 /// Going a bit against the spirit of llvm::Error,
0032 /// lldb_private::Status need to store errors long-term and sometimes
0033 /// copy them. This base class defines an interface for this
0034 /// operation.
0035 class CloneableError
0036     : public llvm::ErrorInfo<CloneableError, llvm::ErrorInfoBase> {
0037 public:
0038   using llvm::ErrorInfo<CloneableError, llvm::ErrorInfoBase>::ErrorInfo;
0039   CloneableError() : ErrorInfo() {}
0040   virtual std::unique_ptr<CloneableError> Clone() const = 0;
0041   virtual lldb::ErrorType GetErrorType() const = 0;
0042   virtual StructuredData::ObjectSP GetAsStructuredData() const = 0;
0043   static char ID;
0044 };
0045 
0046 /// Common base class for all error-code errors.
0047 class CloneableECError
0048     : public llvm::ErrorInfo<CloneableECError, CloneableError> {
0049 public:
0050   using llvm::ErrorInfo<CloneableECError, CloneableError>::ErrorInfo;
0051   std::error_code convertToErrorCode() const override { return EC; }
0052   void log(llvm::raw_ostream &OS) const override { OS << EC.message(); }
0053   lldb::ErrorType GetErrorType() const override;
0054   virtual StructuredData::ObjectSP GetAsStructuredData() const override;
0055   static char ID;
0056 
0057 protected:
0058   CloneableECError() = delete;
0059   CloneableECError(std::error_code ec) : ErrorInfo(), EC(ec) {}
0060   std::error_code EC;
0061 };
0062 /// FIXME: Move these declarations closer to where they're used.
0063 class MachKernelError
0064     : public llvm::ErrorInfo<MachKernelError, CloneableECError> {
0065 public:
0066   using llvm::ErrorInfo<MachKernelError, CloneableECError>::ErrorInfo;
0067   MachKernelError(std::error_code ec) : ErrorInfo(ec) {}
0068   std::string message() const override;
0069   std::unique_ptr<CloneableError> Clone() const override;
0070   lldb::ErrorType GetErrorType() const override;
0071   static char ID;
0072 };
0073 
0074 class Win32Error : public llvm::ErrorInfo<Win32Error, CloneableECError> {
0075 public:
0076   using llvm::ErrorInfo<Win32Error, CloneableECError>::ErrorInfo;
0077   Win32Error(std::error_code ec, const llvm::Twine &msg = {}) : ErrorInfo(ec) {}
0078   std::string message() const override;
0079   std::unique_ptr<CloneableError> Clone() const override;
0080   lldb::ErrorType GetErrorType() const override;
0081   static char ID;
0082 };
0083 
0084 /// \class Status Status.h "lldb/Utility/Status.h" An error handling class.
0085 ///
0086 /// This class is designed to be able to hold any error code that can be
0087 /// encountered on a given platform. The errors are stored as a value of type
0088 /// Status::ValueType. This value should be large enough to hold any and all
0089 /// errors that the class supports. Each error has an associated type that is
0090 /// of type lldb::ErrorType. New types can be added to support new error
0091 /// types, and architecture specific types can be enabled. In the future we
0092 /// may wish to switch to a registration mechanism where new error types can
0093 /// be registered at runtime instead of a hard coded scheme.
0094 ///
0095 /// All errors in this class also know how to generate a string representation
0096 /// of themselves for printing results and error codes. The string value will
0097 /// be fetched on demand and its string value will be cached until the error
0098 /// is cleared of the value of the error changes.
0099 ///
0100 /// API design notes:
0101 ///
0102 /// Most APIs that currently vend a Status would be better served by
0103 /// returning llvm::Expected<> instead. If possibles APIs should be
0104 /// refactored to avoid Status. The only legitimate long-term uses of
0105 /// Status are objects that need to store an error for a long time
0106 /// (which should be questioned as a design decision, too).
0107 ///
0108 /// Implementation notes:
0109 ///
0110 /// Internally, Status stores an llvm::Error.
0111 ///   eErrorTypeInvalid
0112 ///   eErrorTypeGeneric      llvm::StringError
0113 ///   eErrorTypePOSIX        llvm::ECError
0114 ///   eErrorTypeMachKernel   MachKernelError
0115 ///   eErrorTypeExpression   llvm::ErrorList<ExpressionError>
0116 ///   eErrorTypeWin32        Win32Error
0117 
0118 class Status {
0119 public:
0120   /// into ValueType.
0121   typedef uint32_t ValueType;
0122 
0123   Status();
0124   Status(Status &&other) = default;
0125 
0126   /// Initialize the error object with a generic success value.
0127   ///
0128   /// \param[in] err
0129   ///     An error code.
0130   ///
0131   /// \param[in] type
0132   ///     The type for \a err.
0133   explicit Status(ValueType err, lldb::ErrorType type = lldb::eErrorTypeGeneric,
0134                   std::string msg = {});
0135 
0136   Status(std::error_code EC);
0137 
0138   /// Create a generic error with the message \c err_str.
0139   explicit Status(std::string err_str);
0140 
0141   static Status FromErrorString(const char *str) {
0142     if (str)
0143       return Status(std::string(str));
0144     return Status(std::string("null error"));
0145   }
0146 
0147   static Status FromErrorStringWithFormat(const char *format, ...)
0148       __attribute__((format(printf, 1, 2)));
0149 
0150   template <typename... Args>
0151   static Status FromErrorStringWithFormatv(const char *format, Args &&...args) {
0152     return Status(llvm::formatv(format, std::forward<Args>(args)...));
0153   }
0154 
0155   /// Set the current error to errno.
0156   ///
0157   /// Update the error value to be \c errno and update the type to be \c
0158   /// Status::POSIX.
0159   static Status FromErrno();
0160 
0161   ~Status();
0162 
0163   const Status &operator=(Status &&);
0164   /// Avoid using this in new code. Migrate APIs to llvm::Expected instead.
0165   static Status FromError(llvm::Error error);
0166 
0167   /// FIXME: Replace all uses with takeError() instead.
0168   llvm::Error ToError() const;
0169 
0170   llvm::Error takeError() { return std::move(m_error); }
0171 
0172   /// Don't call this function in new code. Instead, redesign the API
0173   /// to use llvm::Expected instead of Status.
0174   Status Clone() const { return Status(ToError()); }
0175 
0176   /// Get the error string associated with the current error.
0177   //
0178   /// Gets the error value as a NULL terminated C string. The error string
0179   /// will be fetched and cached on demand. The error string will be retrieved
0180   /// from a callback that is appropriate for the type of the error and will
0181   /// be cached until the error value is changed or cleared.
0182   ///
0183   /// \return
0184   ///     The error as a NULL terminated C string value if the error
0185   ///     is valid and is able to be converted to a string value,
0186   ///     NULL otherwise.
0187   const char *AsCString(const char *default_error_str = "unknown error") const;
0188 
0189   /// Get the error in machine-readable form.
0190   StructuredData::ObjectSP GetAsStructuredData() const;
0191 
0192   /// Clear the object state.
0193   ///
0194   /// Reverts the state of this object to contain a generic success value and
0195   /// frees any cached error string value.
0196   void Clear();
0197 
0198   /// Test for error condition.
0199   ///
0200   /// \return
0201   ///     \b true if this object contains an error, \b false
0202   ///     otherwise.
0203   bool Fail() const;
0204 
0205   /// Access the error value.
0206   ///
0207   /// If the internally stored \ref llvm::Error is an \ref
0208   /// llvm::ErrorList then this returns the error value of the first
0209   /// error.
0210   ///
0211   /// \return
0212   ///     The error value.
0213   ValueType GetError() const;
0214 
0215   /// Access the error type.
0216   ///
0217   /// If the internally stored \ref llvm::Error is an \ref
0218   /// llvm::ErrorList then this returns the error value of the first
0219   /// error.
0220   ///
0221   /// \return
0222   ///     The error type enumeration value.
0223   lldb::ErrorType GetType() const;
0224 
0225   /// Test for success condition.
0226   ///
0227   /// Returns true if the error code in this object is considered a successful
0228   /// return value.
0229   ///
0230   /// \return
0231   ///     \b true if this object contains an value that describes
0232   ///     success (non-erro), \b false otherwise.
0233   bool Success() const;
0234 
0235 protected:
0236   Status(llvm::Error error) : m_error(std::move(error)) {}
0237   llvm::Error m_error;
0238   /// TODO: Replace this with just calling toString(m_error).
0239   mutable std::string m_string;
0240 };
0241 
0242 } // namespace lldb_private
0243 
0244 namespace llvm {
0245 template <> struct format_provider<lldb_private::Status> {
0246   static void format(const lldb_private::Status &error, llvm::raw_ostream &OS,
0247                      llvm::StringRef Options);
0248 };
0249 } // namespace llvm
0250 
0251 #define LLDB_ERRORF(status, fmt, ...)                                          \
0252   do {                                                                         \
0253     if (status) {                                                              \
0254       (status)->SetErrorStringWithFormat((fmt), __VA_ARGS__);                  \
0255     }                                                                          \
0256   } while (0);
0257 
0258 #endif // LLDB_UTILITY_STATUS_H