blob: 01f933141f0459e9c821b9f37f01962d1369ab9c [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Error.cpp -----------------------------------------------*- 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// C Includes
Charles Davis322fc842013-08-27 06:13:56 +000011#ifdef __APPLE__
Charles Davis510938e2013-08-27 05:04:57 +000012#include <mach/mach.h>
Charles Davis322fc842013-08-27 06:13:56 +000013#endif
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014
15// C++ Includes
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000016#include <cerrno>
17#include <cstdarg>
Zachary Turner7d86ee52017-03-08 17:56:08 +000018#include <system_error>
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000019
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020// Other libraries and framework includes
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000021#include "llvm/ADT/SmallVector.h"
22
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023// Project includes
Zachary Turnerbf9a7732017-02-02 21:39:50 +000024#include "lldb/Utility/Error.h"
Zachary Turner24ae6292017-02-16 19:38:21 +000025#include "lldb/Utility/VASPrintf.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027using namespace lldb;
28using namespace lldb_private;
29
Kate Stoneb9c1b512016-09-06 20:57:50 +000030Error::Error() : m_code(0), m_type(eErrorTypeInvalid), m_string() {}
Greg Claytonca512b32011-01-14 04:54:56 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032Error::Error(ValueType err, ErrorType type)
33 : m_code(err), m_type(type), m_string() {}
Greg Claytonca512b32011-01-14 04:54:56 +000034
Zachary Turner7d86ee52017-03-08 17:56:08 +000035Error::Error(std::error_code EC)
36 : m_code(EC.value()), m_type(ErrorType::eErrorTypeGeneric),
37 m_string(EC.message()) {}
38
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000039Error::Error(const Error &rhs) = default;
Greg Claytonca512b32011-01-14 04:54:56 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041Error::Error(const char *format, ...)
42 : m_code(0), m_type(eErrorTypeInvalid), m_string() {
43 va_list args;
44 va_start(args, format);
45 SetErrorToGenericError();
46 SetErrorStringWithVarArg(format, args);
47 va_end(args);
Enrico Granataf2bbf712011-07-15 02:26:42 +000048}
49
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050//----------------------------------------------------------------------
51// Assignment operator
52//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000053const Error &Error::operator=(const Error &rhs) {
54 if (this != &rhs) {
55 m_code = rhs.m_code;
56 m_type = rhs.m_type;
57 m_string = rhs.m_string;
58 }
59 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060}
61
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062//----------------------------------------------------------------------
63// Assignment operator
64//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000065const Error &Error::operator=(uint32_t err) {
66 m_code = err;
67 m_type = eErrorTypeMachKernel;
68 m_string.clear();
69 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070}
71
Eugene Zelenkoa74f37a2016-03-10 23:57:12 +000072Error::~Error() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
74//----------------------------------------------------------------------
75// Get the error value as a NULL C string. The error string will be
76// fetched and cached on demand. The cached error string value will
77// remain until the error value is changed or cleared.
78//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000079const char *Error::AsCString(const char *default_error_str) const {
80 if (Success())
81 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 if (m_string.empty()) {
84 const char *s = nullptr;
85 switch (m_type) {
86 case eErrorTypeMachKernel:
87#if defined(__APPLE__)
88 s = ::mach_error_string(m_code);
Eli Friedman6eb685c2010-06-10 23:45:58 +000089#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 case eErrorTypePOSIX:
93 s = ::strerror(m_code);
94 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 default:
97 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000098 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 if (s != nullptr)
100 m_string.assign(s);
101 }
102 if (m_string.empty()) {
103 if (default_error_str)
104 m_string.assign(default_error_str);
105 else
106 return nullptr; // User wanted a nullptr string back...
107 }
108 return m_string.c_str();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109}
110
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111//----------------------------------------------------------------------
112// Clear the error and any cached error string that it might contain.
113//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114void Error::Clear() {
115 m_code = 0;
116 m_type = eErrorTypeInvalid;
117 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118}
119
120//----------------------------------------------------------------------
121// Access the error value.
122//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123Error::ValueType Error::GetError() const { return m_code; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124
125//----------------------------------------------------------------------
126// Access the error type.
127//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128ErrorType Error::GetType() const { return m_type; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129
130//----------------------------------------------------------------------
Ed Maste75500e72016-07-19 15:28:02 +0000131// Returns true if this object contains a value that describes an
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132// error or otherwise non-success result.
133//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134bool Error::Fail() const { return m_code != 0; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135
136//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137// Set accesssor for the error value to "err" and the type to
138// "eErrorTypeMachKernel"
139//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140void Error::SetMachError(uint32_t err) {
141 m_code = err;
142 m_type = eErrorTypeMachKernel;
143 m_string.clear();
144}
145
146void Error::SetExpressionError(lldb::ExpressionResults result,
147 const char *mssg) {
148 m_code = result;
149 m_type = eErrorTypeExpression;
150 m_string = mssg;
151}
152
153int Error::SetExpressionErrorWithFormat(lldb::ExpressionResults result,
154 const char *format, ...) {
155 int length = 0;
156
157 if (format != nullptr && format[0]) {
158 va_list args;
159 va_start(args, format);
160 length = SetErrorStringWithVarArg(format, args);
161 va_end(args);
162 } else {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163 m_string.clear();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 }
165 m_code = result;
166 m_type = eErrorTypeExpression;
167 return length;
Jim Ingham1624a2d2014-05-05 02:26:40 +0000168}
169
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170//----------------------------------------------------------------------
171// Set accesssor for the error value and type.
172//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173void Error::SetError(ValueType err, ErrorType type) {
174 m_code = err;
175 m_type = type;
176 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177}
178
179//----------------------------------------------------------------------
180// Update the error value to be "errno" and update the type to
181// be "POSIX".
182//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183void Error::SetErrorToErrno() {
184 m_code = errno;
185 m_type = eErrorTypePOSIX;
186 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187}
188
189//----------------------------------------------------------------------
190// Update the error value to be LLDB_GENERIC_ERROR and update the type
191// to be "Generic".
192//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193void Error::SetErrorToGenericError() {
194 m_code = LLDB_GENERIC_ERROR;
195 m_type = eErrorTypeGeneric;
196 m_string.clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197}
198
199//----------------------------------------------------------------------
200// Set accessor for the error string value for a specific error.
201// This allows any string to be supplied as an error explanation.
202// The error string value will remain until the error value is
203// cleared or a new error value/type is assigned.
204//----------------------------------------------------------------------
Zachary Turnerc1564272016-11-16 21:15:24 +0000205void Error::SetErrorString(llvm::StringRef err_str) {
206 if (!err_str.empty()) {
207 // If we have an error string, we should always at least have an error
208 // set to a generic value.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 if (Success())
210 SetErrorToGenericError();
Zachary Turnerc1564272016-11-16 21:15:24 +0000211 }
212 m_string = err_str;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213}
214
215//------------------------------------------------------------------
216/// Set the current error string to a formatted error string.
217///
218/// @param format
219/// A printf style format string
220//------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000221int Error::SetErrorStringWithFormat(const char *format, ...) {
222 if (format != nullptr && format[0]) {
223 va_list args;
224 va_start(args, format);
225 int length = SetErrorStringWithVarArg(format, args);
226 va_end(args);
227 return length;
228 } else {
229 m_string.clear();
230 }
231 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232}
233
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234int Error::SetErrorStringWithVarArg(const char *format, va_list args) {
235 if (format != nullptr && format[0]) {
236 // If we have an error string, we should always at least have
237 // an error set to a generic value.
238 if (Success())
239 SetErrorToGenericError();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240
Zachary Turner24ae6292017-02-16 19:38:21 +0000241 llvm::SmallString<1024> buf;
242 VASprintf(buf, format, args);
Pavel Labatha272fa82017-02-17 10:19:46 +0000243 m_string = buf.str();
Zachary Turner24ae6292017-02-16 19:38:21 +0000244 return buf.size();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245 } else {
246 m_string.clear();
247 }
248 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249}
250
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251//----------------------------------------------------------------------
252// Returns true if the error code in this object is considered a
253// successful return value.
254//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000255bool Error::Success() const { return m_code == 0; }
Jim Ingham4e5c8212013-06-07 22:09:53 +0000256
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257bool Error::WasInterrupted() const {
258 return (m_type == eErrorTypePOSIX && m_code == EINTR);
Jim Ingham4e5c8212013-06-07 22:09:53 +0000259}
Zachary Turner33aba3c2017-02-06 18:31:44 +0000260
261void llvm::format_provider<lldb_private::Error>::format(
262 const lldb_private::Error &error, llvm::raw_ostream &OS,
263 llvm::StringRef Options) {
264 llvm::format_provider<llvm::StringRef>::format(error.AsCString(), OS,
265 Options);
266}