LLDB mainline
Status.h
Go to the documentation of this file.
1//===-- Status.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_UTILITY_STATUS_H
10#define LLDB_UTILITY_STATUS_H
11
13#include "lldb/lldb-defines.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/Error.h"
17#include "llvm/Support/FormatVariadic.h"
18#include <cstdarg>
19#include <cstdint>
20#include <string>
21#include <system_error>
22#include <type_traits>
23
24namespace llvm {
25class raw_ostream;
26}
27
28namespace lldb_private {
29
30/// Going a bit against the spirit of llvm::Error,
31/// lldb_private::Status need to store errors long-term and sometimes
32/// copy them. This base class defines an interface for this
33/// operation.
35 : public llvm::ErrorInfo<CloneableError, llvm::ErrorInfoBase> {
36public:
37 using llvm::ErrorInfo<CloneableError, llvm::ErrorInfoBase>::ErrorInfo;
38 CloneableError() : ErrorInfo() {}
39 virtual std::unique_ptr<CloneableError> Clone() const = 0;
40 virtual lldb::ErrorType GetErrorType() const = 0;
41 static char ID;
42};
43
44/// Common base class for all error-code errors.
46 : public llvm::ErrorInfo<CloneableECError, CloneableError> {
47public:
48 using llvm::ErrorInfo<CloneableECError, CloneableError>::ErrorInfo;
49 std::error_code convertToErrorCode() const override { return EC; }
50 void log(llvm::raw_ostream &OS) const override { OS << EC.message(); }
51 lldb::ErrorType GetErrorType() const override;
52 static char ID;
53
54protected:
55 CloneableECError() = delete;
56 CloneableECError(std::error_code ec) : ErrorInfo(), EC(ec) {}
57 std::error_code EC;
58};
59/// FIXME: Move these declarations closer to where they're used.
61 : public llvm::ErrorInfo<MachKernelError, CloneableECError> {
62public:
63 using llvm::ErrorInfo<MachKernelError, CloneableECError>::ErrorInfo;
64 MachKernelError(std::error_code ec) : ErrorInfo(ec) {}
65 std::string message() const override;
66 std::unique_ptr<CloneableError> Clone() const override;
67 lldb::ErrorType GetErrorType() const override;
68 static char ID;
69};
70
71class Win32Error : public llvm::ErrorInfo<Win32Error, CloneableECError> {
72public:
73 using llvm::ErrorInfo<Win32Error, CloneableECError>::ErrorInfo;
74 Win32Error(std::error_code ec, const llvm::Twine &msg = {}) : ErrorInfo(ec) {}
75 std::string message() const override;
76 std::unique_ptr<CloneableError> Clone() const override;
77 lldb::ErrorType GetErrorType() const override;
78 static char ID;
79};
80
81/// \class Status Status.h "lldb/Utility/Status.h" An error handling class.
82///
83/// This class is designed to be able to hold any error code that can be
84/// encountered on a given platform. The errors are stored as a value of type
85/// Status::ValueType. This value should be large enough to hold any and all
86/// errors that the class supports. Each error has an associated type that is
87/// of type lldb::ErrorType. New types can be added to support new error
88/// types, and architecture specific types can be enabled. In the future we
89/// may wish to switch to a registration mechanism where new error types can
90/// be registered at runtime instead of a hard coded scheme.
91///
92/// All errors in this class also know how to generate a string representation
93/// of themselves for printing results and error codes. The string value will
94/// be fetched on demand and its string value will be cached until the error
95/// is cleared of the value of the error changes.
96///
97/// API design notes:
98///
99/// Most APIs that currently vend a Status would be better served by
100/// returning llvm::Expected<> instead. If possibles APIs should be
101/// refactored to avoid Status. The only legitimate long-term uses of
102/// Status are objects that need to store an error for a long time
103/// (which should be questioned as a design decision, too).
104///
105/// Implementation notes:
106///
107/// Internally, Status stores an llvm::Error.
108/// eErrorTypeInvalid
109/// eErrorTypeGeneric llvm::StringError
110/// eErrorTypePOSIX llvm::ECError
111/// eErrorTypeMachKernel MachKernelError
112/// eErrorTypeExpression llvm::ErrorList<ExpressionError>
113/// eErrorTypeWin32 Win32Error
114
115class Status {
116public:
117 /// into ValueType.
118 typedef uint32_t ValueType;
119
120 Status();
121 Status(Status &&other) = default;
122
123 /// Initialize the error object with a generic success value.
124 ///
125 /// \param[in] err
126 /// An error code.
127 ///
128 /// \param[in] type
129 /// The type for \a err.
131 std::string msg = {});
132
133 Status(std::error_code EC);
134
135 /// Create a generic error with the message \c err_str.
136 explicit Status(std::string err_str);
137
138 static Status FromErrorString(const char *str) {
139 if (str)
140 return Status(std::string(str));
141 return Status(std::string("null error"));
142 }
143
144 static Status FromErrorStringWithFormat(const char *format, ...)
145 __attribute__((format(printf, 1, 2)));
146
147 template <typename... Args>
148 static Status FromErrorStringWithFormatv(const char *format, Args &&...args) {
149 return Status(llvm::formatv(format, std::forward<Args>(args)...));
150 }
151
152 /// Set the current error to errno.
153 ///
154 /// Update the error value to be \c errno and update the type to be \c
155 /// Status::POSIX.
156 static Status FromErrno();
157
158 ~Status();
159
160 const Status &operator=(Status &&);
161 /// Avoid using this in new code. Migrate APIs to llvm::Expected instead.
162 static Status FromError(llvm::Error error);
163
164 /// FIXME: Replace all uses with takeError() instead.
165 llvm::Error ToError() const;
166
167 llvm::Error takeError() { return std::move(m_error); }
168
169 /// Don't call this function in new code. Instead, redesign the API
170 /// to use llvm::Expected instead of Status.
171 Status Clone() const { return Status(ToError()); }
172
173 /// Get the error string associated with the current error.
174 //
175 /// Gets the error value as a NULL terminated C string. The error string
176 /// will be fetched and cached on demand. The error string will be retrieved
177 /// from a callback that is appropriate for the type of the error and will
178 /// be cached until the error value is changed or cleared.
179 ///
180 /// \return
181 /// The error as a NULL terminated C string value if the error
182 /// is valid and is able to be converted to a string value,
183 /// NULL otherwise.
184 const char *AsCString(const char *default_error_str = "unknown error") const;
185
186 /// Clear the object state.
187 ///
188 /// Reverts the state of this object to contain a generic success value and
189 /// frees any cached error string value.
190 void Clear();
191
192 /// Test for error condition.
193 ///
194 /// \return
195 /// \b true if this object contains an error, \b false
196 /// otherwise.
197 bool Fail() const;
198
199 /// Access the error value.
200 ///
201 /// If the internally stored \ref llvm::Error is an \ref
202 /// llvm::ErrorList then this returns the error value of the first
203 /// error.
204 ///
205 /// \return
206 /// The error value.
207 ValueType GetError() const;
208
209 /// Access the error type.
210 ///
211 /// If the internally stored \ref llvm::Error is an \ref
212 /// llvm::ErrorList then this returns the error value of the first
213 /// error.
214 ///
215 /// \return
216 /// The error type enumeration value.
217 lldb::ErrorType GetType() const;
218
219 /// Test for success condition.
220 ///
221 /// Returns true if the error code in this object is considered a successful
222 /// return value.
223 ///
224 /// \return
225 /// \b true if this object contains an value that describes
226 /// success (non-erro), \b false otherwise.
227 bool Success() const;
228
229protected:
230 Status(llvm::Error error) : m_error(std::move(error)) {}
231 llvm::Error m_error;
232 /// TODO: Replace this with just calling toString(m_error).
233 mutable std::string m_string;
234};
235
236} // namespace lldb_private
237
238namespace llvm {
239template <> struct format_provider<lldb_private::Status> {
240 static void format(const lldb_private::Status &error, llvm::raw_ostream &OS,
241 llvm::StringRef Options);
242};
243} // namespace llvm
244
245#define LLDB_ERRORF(status, fmt, ...) \
246 do { \
247 if (status) { \
248 (status)->SetErrorStringWithFormat((fmt), __VA_ARGS__); \
249 } \
250 } while (0);
251
252#endif // LLDB_UTILITY_STATUS_H
static llvm::raw_ostream & error(Stream &strm)
A command line argument class.
Definition: Args.h:33
Common base class for all error-code errors.
Definition: Status.h:46
std::error_code EC
Definition: Status.h:57
void log(llvm::raw_ostream &OS) const override
Definition: Status.h:50
lldb::ErrorType GetErrorType() const override
Definition: Status.cpp:243
std::error_code convertToErrorCode() const override
Definition: Status.h:49
CloneableECError(std::error_code ec)
Definition: Status.h:56
Going a bit against the spirit of llvm::Error, lldb_private::Status need to store errors long-term an...
Definition: Status.h:35
virtual std::unique_ptr< CloneableError > Clone() const =0
virtual lldb::ErrorType GetErrorType() const =0
FIXME: Move these declarations closer to where they're used.
Definition: Status.h:61
std::string message() const override
Definition: Status.cpp:169
std::unique_ptr< CloneableError > Clone() const override
Definition: Status.cpp:184
MachKernelError(std::error_code ec)
Definition: Status.h:64
lldb::ErrorType GetErrorType() const override
Definition: Status.cpp:247
An error handling class.
Definition: Status.h:115
uint32_t ValueType
into ValueType.
Definition: Status.h:118
void Clear()
Clear the object state.
Definition: Status.cpp:215
static Status FromErrno()
Set the current error to errno.
Definition: Status.cpp:276
Status(Status &&other)=default
lldb::ErrorType GetType() const
Access the error type.
Definition: Status.cpp:255
llvm::Error takeError()
Definition: Status.h:167
Status Clone() const
Don't call this function in new code.
Definition: Status.h:171
ValueType GetError() const
Access the error value.
Definition: Status.cpp:222
Status(llvm::Error error)
Definition: Status.h:230
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
Definition: Status.cpp:139
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition: Status.cpp:106
static Status FromErrorString(const char *str)
Definition: Status.h:138
bool Fail() const
Test for error condition.
Definition: Status.cpp:270
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:195
const Status & operator=(Status &&)
Definition: Status.cpp:99
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition: Status.h:148
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition: Status.cpp:137
llvm::Error m_error
Definition: Status.h:231
bool Success() const
Test for success condition.
Definition: Status.cpp:280
std::string m_string
TODO: Replace this with just calling toString(m_error).
Definition: Status.h:233
Win32Error(std::error_code ec, const llvm::Twine &msg={})
Definition: Status.h:74
static char ID
Definition: Status.h:78
std::string message() const override
Definition: Status.cpp:177
lldb::ErrorType GetErrorType() const override
Definition: Status.cpp:251
std::unique_ptr< CloneableError > Clone() const override
Definition: Status.cpp:188
A class that represents a running process on the host machine.
@ eErrorTypeGeneric
Generic errors that can be any value.
Definition: Debugger.h:54