1 //===-- Status.h ------------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLDB_UTILITY_STATUS_H 11 #define LLDB_UTILITY_STATUS_H 12 13 #include "lldb/lldb-defines.h" 14 #include "lldb/lldb-enumerations.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/Support/Error.h" 17 #include "llvm/Support/FormatVariadic.h" 18 #include <cstdarg> 19 #include <stdint.h> 20 #include <string> 21 #include <system_error> 22 #include <type_traits> 23 24 namespace llvm { 25 class raw_ostream; 26 } 27 28 namespace lldb_private { 29 30 //---------------------------------------------------------------------- 31 /// @class Status Status.h "lldb/Utility/Status.h" An error handling class. 32 /// 33 /// This class is designed to be able to hold any error code that can be 34 /// encountered on a given platform. The errors are stored as a value of type 35 /// Status::ValueType. This value should be large enough to hold any and all 36 /// errors that the class supports. Each error has an associated type that is 37 /// of type lldb::ErrorType. New types can be added to support new error 38 /// types, and architecture specific types can be enabled. In the future we 39 /// may wish to switch to a registration mechanism where new error types can 40 /// be registered at runtime instead of a hard coded scheme. 41 /// 42 /// All errors in this class also know how to generate a string representation 43 /// of themselves for printing results and error codes. The string value will 44 /// be fetched on demand and its string value will be cached until the error 45 /// is cleared of the value of the error changes. 46 //---------------------------------------------------------------------- 47 class Status { 48 public: 49 //------------------------------------------------------------------ 50 /// Every error value that this object can contain needs to be able to fit 51 /// into ValueType. 52 //------------------------------------------------------------------ 53 typedef uint32_t ValueType; 54 55 //------------------------------------------------------------------ 56 /// Default constructor. 57 /// 58 /// Initialize the error object with a generic success value. 59 /// 60 /// @param[in] err 61 /// An error code. 62 /// 63 /// @param[in] type 64 /// The type for \a err. 65 //------------------------------------------------------------------ 66 Status(); 67 68 explicit Status(ValueType err, 69 lldb::ErrorType type = lldb::eErrorTypeGeneric); 70 71 /* implicit */ Status(std::error_code EC); 72 73 explicit Status(const char *format, ...) 74 __attribute__((format(printf, 2, 3))); 75 76 Status(const Status &rhs); 77 //------------------------------------------------------------------ 78 /// Assignment operator. 79 /// 80 /// @param[in] err 81 /// An error code. 82 /// 83 /// @return 84 /// A const reference to this object. 85 //------------------------------------------------------------------ 86 const Status &operator=(const Status &rhs); 87 88 ~Status(); 89 90 // llvm::Error support Status(llvm::Error error)91 explicit Status(llvm::Error error) { *this = std::move(error); } 92 const Status &operator=(llvm::Error error); 93 llvm::Error ToError() const; 94 95 //------------------------------------------------------------------ 96 /// Get the error string associated with the current error. 97 // 98 /// Gets the error value as a NULL terminated C string. The error string 99 /// will be fetched and cached on demand. The error string will be retrieved 100 /// from a callback that is appropriate for the type of the error and will 101 /// be cached until the error value is changed or cleared. 102 /// 103 /// @return 104 /// The error as a NULL terminated C string value if the error 105 /// is valid and is able to be converted to a string value, 106 /// NULL otherwise. 107 //------------------------------------------------------------------ 108 const char *AsCString(const char *default_error_str = "unknown error") const; 109 110 //------------------------------------------------------------------ 111 /// Clear the object state. 112 /// 113 /// Reverts the state of this object to contain a generic success value and 114 /// frees any cached error string value. 115 //------------------------------------------------------------------ 116 void Clear(); 117 118 //------------------------------------------------------------------ 119 /// Test for error condition. 120 /// 121 /// @return 122 /// \b true if this object contains an error, \b false 123 /// otherwise. 124 //------------------------------------------------------------------ 125 bool Fail() const; 126 127 //------------------------------------------------------------------ 128 /// Access the error value. 129 /// 130 /// @return 131 /// The error value. 132 //------------------------------------------------------------------ 133 ValueType GetError() const; 134 135 //------------------------------------------------------------------ 136 /// Access the error type. 137 /// 138 /// @return 139 /// The error type enumeration value. 140 //------------------------------------------------------------------ 141 lldb::ErrorType GetType() const; 142 143 //------------------------------------------------------------------ 144 /// Set accessor from a kern_return_t. 145 /// 146 /// Set accesssor for the error value to \a err and the error type to \c 147 /// MachKernel. 148 /// 149 /// @param[in] err 150 /// A mach error code. 151 //------------------------------------------------------------------ 152 void SetMachError(uint32_t err); 153 154 void SetExpressionError(lldb::ExpressionResults, const char *mssg); 155 156 int SetExpressionErrorWithFormat(lldb::ExpressionResults, const char *format, 157 ...) __attribute__((format(printf, 3, 4))); 158 159 //------------------------------------------------------------------ 160 /// Set accesssor with an error value and type. 161 /// 162 /// Set accesssor for the error value to \a err and the error type to \a 163 /// type. 164 /// 165 /// @param[in] err 166 /// A mach error code. 167 /// 168 /// @param[in] type 169 /// The type for \a err. 170 //------------------------------------------------------------------ 171 void SetError(ValueType err, lldb::ErrorType type); 172 173 //------------------------------------------------------------------ 174 /// Set the current error to errno. 175 /// 176 /// Update the error value to be \c errno and update the type to be \c 177 /// Status::POSIX. 178 //------------------------------------------------------------------ 179 void SetErrorToErrno(); 180 181 //------------------------------------------------------------------ 182 /// Set the current error to a generic error. 183 /// 184 /// Update the error value to be \c LLDB_GENERIC_ERROR and update the type 185 /// to be \c Status::Generic. 186 //------------------------------------------------------------------ 187 void SetErrorToGenericError(); 188 189 //------------------------------------------------------------------ 190 /// Set the current error string to \a err_str. 191 /// 192 /// Set accessor for the error string value for a generic errors, or to 193 /// supply additional details above and beyond the standard error strings 194 /// that the standard type callbacks typically provide. This allows custom 195 /// strings to be supplied as an error explanation. The error string value 196 /// will remain until the error value is cleared or a new error value/type 197 /// is assigned. 198 /// 199 /// @param err_str 200 /// The new custom error string to copy and cache. 201 //------------------------------------------------------------------ 202 void SetErrorString(llvm::StringRef err_str); 203 204 //------------------------------------------------------------------ 205 /// Set the current error string to a formatted error string. 206 /// 207 /// @param format 208 /// A printf style format string 209 //------------------------------------------------------------------ 210 int SetErrorStringWithFormat(const char *format, ...) 211 __attribute__((format(printf, 2, 3))); 212 213 int SetErrorStringWithVarArg(const char *format, va_list args); 214 215 template <typename... Args> SetErrorStringWithFormatv(const char * format,Args &&...args)216 void SetErrorStringWithFormatv(const char *format, Args &&... args) { 217 SetErrorString(llvm::formatv(format, std::forward<Args>(args)...).str()); 218 } 219 220 //------------------------------------------------------------------ 221 /// Test for success condition. 222 /// 223 /// Returns true if the error code in this object is considered a successful 224 /// return value. 225 /// 226 /// @return 227 /// \b true if this object contains an value that describes 228 /// success (non-erro), \b false otherwise. 229 //------------------------------------------------------------------ 230 bool Success() const; 231 232 //------------------------------------------------------------------ 233 /// Test for a failure due to a generic interrupt. 234 /// 235 /// Returns true if the error code in this object was caused by an 236 /// interrupt. At present only supports Posix EINTR. 237 /// 238 /// @return 239 /// \b true if this object contains an value that describes 240 /// failure due to interrupt, \b false otherwise. 241 //------------------------------------------------------------------ 242 bool WasInterrupted() const; 243 244 protected: 245 //------------------------------------------------------------------ 246 /// Member variables 247 //------------------------------------------------------------------ 248 ValueType m_code; ///< Status code as an integer value. 249 lldb::ErrorType m_type; ///< The type of the above error code. 250 mutable std::string m_string; ///< A string representation of the error code. 251 }; 252 253 } // namespace lldb_private 254 255 namespace llvm { 256 template <> struct format_provider<lldb_private::Status> { 257 static void format(const lldb_private::Status &error, llvm::raw_ostream &OS, 258 llvm::StringRef Options); 259 }; 260 } 261 262 #endif // #ifndef LLDB_UTILITY_STATUS_H 263