1 //===-- SBError.cpp -------------------------------------------------------===//
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 #include "lldb/API/SBError.h"
10 #include "Utils.h"
11 #include "lldb/API/SBStream.h"
12 #include "lldb/API/SBStructuredData.h"
13 #include "lldb/Core/StructuredDataImpl.h"
14 #include "lldb/Utility/Instrumentation.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/Utility/VASPrintf.h"
17
18 #include <cstdarg>
19
20 using namespace lldb;
21 using namespace lldb_private;
22
SBError()23 SBError::SBError() { LLDB_INSTRUMENT_VA(this); }
24
SBError(const SBError & rhs)25 SBError::SBError(const SBError &rhs) {
26 LLDB_INSTRUMENT_VA(this, rhs);
27
28 if (rhs.m_opaque_up)
29 m_opaque_up = std::make_unique<Status>(rhs.m_opaque_up->Clone());
30 }
31
SBError(const char * message)32 SBError::SBError(const char *message) {
33 LLDB_INSTRUMENT_VA(this, message);
34
35 SetErrorString(message);
36 }
37
SBError(lldb_private::Status && status)38 SBError::SBError(lldb_private::Status &&status)
39 : m_opaque_up(new Status(std::move(status))) {
40 LLDB_INSTRUMENT_VA(this, status);
41 }
42
43 SBError::~SBError() = default;
44
operator =(const SBError & rhs)45 const SBError &SBError::operator=(const SBError &rhs) {
46 LLDB_INSTRUMENT_VA(this, rhs);
47
48 if (this != &rhs)
49 if (rhs.m_opaque_up)
50 m_opaque_up = std::make_unique<Status>(rhs.m_opaque_up->Clone());
51
52 return *this;
53 }
54
GetCString() const55 const char *SBError::GetCString() const {
56 LLDB_INSTRUMENT_VA(this);
57
58 if (m_opaque_up)
59 return m_opaque_up->AsCString();
60 return nullptr;
61 }
62
Clear()63 void SBError::Clear() {
64 LLDB_INSTRUMENT_VA(this);
65
66 if (m_opaque_up)
67 m_opaque_up->Clear();
68 }
69
Fail() const70 bool SBError::Fail() const {
71 LLDB_INSTRUMENT_VA(this);
72
73 bool ret_value = false;
74 if (m_opaque_up)
75 ret_value = m_opaque_up->Fail();
76
77
78 return ret_value;
79 }
80
Success() const81 bool SBError::Success() const {
82 LLDB_INSTRUMENT_VA(this);
83
84 bool ret_value = true;
85 if (m_opaque_up)
86 ret_value = m_opaque_up->Success();
87
88 return ret_value;
89 }
90
GetError() const91 uint32_t SBError::GetError() const {
92 LLDB_INSTRUMENT_VA(this);
93
94 uint32_t err = 0;
95 if (m_opaque_up)
96 err = m_opaque_up->GetError();
97
98
99 return err;
100 }
101
GetErrorData() const102 SBStructuredData SBError::GetErrorData() const {
103 LLDB_INSTRUMENT_VA(this);
104
105 SBStructuredData sb_data;
106 if (!m_opaque_up)
107 return sb_data;
108
109 StructuredData::ObjectSP data(m_opaque_up->GetAsStructuredData());
110 sb_data.m_impl_up->SetObjectSP(data);
111 return sb_data;
112 }
113
GetType() const114 ErrorType SBError::GetType() const {
115 LLDB_INSTRUMENT_VA(this);
116
117 ErrorType err_type = eErrorTypeInvalid;
118 if (m_opaque_up)
119 err_type = m_opaque_up->GetType();
120
121 return err_type;
122 }
123
SetError(uint32_t err,ErrorType type)124 void SBError::SetError(uint32_t err, ErrorType type) {
125 LLDB_INSTRUMENT_VA(this, err, type);
126
127 CreateIfNeeded();
128 *m_opaque_up = Status(err, type);
129 }
130
SetError(Status && lldb_error)131 void SBError::SetError(Status &&lldb_error) {
132 CreateIfNeeded();
133 *m_opaque_up = std::move(lldb_error);
134 }
135
SetErrorToErrno()136 void SBError::SetErrorToErrno() {
137 LLDB_INSTRUMENT_VA(this);
138
139 CreateIfNeeded();
140 *m_opaque_up = Status::FromErrno();
141 }
142
SetErrorToGenericError()143 void SBError::SetErrorToGenericError() {
144 LLDB_INSTRUMENT_VA(this);
145
146 CreateIfNeeded();
147 *m_opaque_up = Status(std::string("generic error"));
148 }
149
SetErrorString(const char * err_str)150 void SBError::SetErrorString(const char *err_str) {
151 LLDB_INSTRUMENT_VA(this, err_str);
152
153 CreateIfNeeded();
154 *m_opaque_up = Status::FromErrorString(err_str);
155 }
156
SetErrorStringWithFormat(const char * format,...)157 int SBError::SetErrorStringWithFormat(const char *format, ...) {
158 CreateIfNeeded();
159 std::string string;
160 va_list args;
161 va_start(args, format);
162 if (format != nullptr && format[0]) {
163 llvm::SmallString<1024> buf;
164 VASprintf(buf, format, args);
165 string = std::string(buf.str());
166 *m_opaque_up = Status(std::move(string));
167 }
168 va_end(args);
169 return string.size();
170 }
171
IsValid() const172 bool SBError::IsValid() const {
173 LLDB_INSTRUMENT_VA(this);
174 return this->operator bool();
175 }
operator bool() const176 SBError::operator bool() const {
177 LLDB_INSTRUMENT_VA(this);
178
179 return m_opaque_up != nullptr;
180 }
181
CreateIfNeeded()182 void SBError::CreateIfNeeded() {
183 if (m_opaque_up == nullptr)
184 m_opaque_up = std::make_unique<Status>();
185 }
186
operator ->()187 lldb_private::Status *SBError::operator->() { return m_opaque_up.get(); }
188
get()189 lldb_private::Status *SBError::get() { return m_opaque_up.get(); }
190
ref()191 lldb_private::Status &SBError::ref() {
192 CreateIfNeeded();
193 return *m_opaque_up;
194 }
195
operator *() const196 const lldb_private::Status &SBError::operator*() const {
197 // Be sure to call "IsValid()" before calling this function or it will crash
198 return *m_opaque_up;
199 }
200
GetDescription(SBStream & description)201 bool SBError::GetDescription(SBStream &description) {
202 LLDB_INSTRUMENT_VA(this, description);
203
204 if (m_opaque_up) {
205 if (m_opaque_up->Success())
206 description.Printf("success");
207 else {
208 const char *err_string = GetCString();
209 description.Printf("error: %s",
210 (err_string != nullptr ? err_string : ""));
211 }
212 } else
213 description.Printf("error: <NULL>");
214
215 return true;
216 }
217