Bug Summary

File:tools/lldb/include/lldb/Utility/StructuredData.h
Warning:line 469, column 42
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name BreakpointResolverScripted.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Breakpoint -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Breakpoint -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lldb/source/Breakpoint -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Breakpoint/BreakpointResolverScripted.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Breakpoint/BreakpointResolverScripted.cpp

1//===-- BreakpointResolverScripted.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#include "lldb/Breakpoint/BreakpointResolverScripted.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16
17#include "lldb/Breakpoint/BreakpointLocation.h"
18#include "lldb/Core/Debugger.h"
19#include "lldb/Core/Module.h"
20#include "lldb/Core/Section.h"
21#include "lldb/Core/StructuredDataImpl.h"
22#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/ScriptInterpreter.h"
24#include "lldb/Target/Process.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Utility/Log.h"
27#include "lldb/Utility/StreamString.h"
28
29using namespace lldb;
30using namespace lldb_private;
31
32//----------------------------------------------------------------------
33// BreakpointResolverScripted:
34//----------------------------------------------------------------------
35BreakpointResolverScripted::BreakpointResolverScripted(
36 Breakpoint *bkpt,
37 const llvm::StringRef class_name,
38 lldb::SearchDepth depth,
39 StructuredDataImpl *args_data,
40 ScriptInterpreter &script_interp)
41 : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver),
42 m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) {
43 CreateImplementationIfNeeded();
44}
45
46void BreakpointResolverScripted::CreateImplementationIfNeeded() {
47 if (m_implementation_sp)
48 return;
49
50 if (m_class_name.empty())
51 return;
52
53 if (m_breakpoint) {
54 TargetSP target_sp = m_breakpoint->GetTargetSP();
55 ScriptInterpreter *script_interp = target_sp->GetDebugger()
56 .GetCommandInterpreter()
57 .GetScriptInterpreter();
58 if (!script_interp)
59 return;
60 lldb::BreakpointSP bkpt_sp(m_breakpoint->shared_from_this());
61 m_implementation_sp = script_interp->CreateScriptedBreakpointResolver(
62 m_class_name.c_str(), m_args_ptr, bkpt_sp);
63 }
64}
65
66void BreakpointResolverScripted::NotifyBreakpointSet() {
67 CreateImplementationIfNeeded();
68}
69
70BreakpointResolverScripted::~BreakpointResolverScripted() {}
71
72BreakpointResolver *
73BreakpointResolverScripted::CreateFromStructuredData(
74 Breakpoint *bkpt, const StructuredData::Dictionary &options_dict,
75 Status &error) {
76 llvm::StringRef class_name;
77 bool success;
78
79 if (!bkpt)
1
Assuming 'bkpt' is non-null
2
Taking false branch
80 return nullptr;
81
82 success = options_dict.GetValueForKeyAsString(
83 GetKey(OptionNames::PythonClassName), class_name);
84 if (!success) {
3
Taking false branch
85 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
86 return nullptr;
87 }
88 lldb::SearchDepth depth;
89 int depth_as_int;
90 success = options_dict.GetValueForKeyAsInteger(
91 GetKey(OptionNames::SearchDepth), depth_as_int);
92 if (!success) {
4
Taking false branch
93 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
94 return nullptr;
95 }
96 if (depth_as_int >= (int) OptionNames::LastOptionName) {
5
Assuming 'depth_as_int' is < LastOptionName
6
Taking false branch
97 error.SetErrorString("BRFL::CFSD: Invalid value for search depth.");
98 return nullptr;
99 }
100 depth = (lldb::SearchDepth) depth_as_int;
101
102 StructuredDataImpl *args_data_impl = new StructuredDataImpl();
103 StructuredData::Dictionary *args_dict = new StructuredData::Dictionary();
7
Memory is allocated
104 success = options_dict.GetValueForKeyAsDictionary(
8
Calling 'Dictionary::GetValueForKeyAsDictionary'
105 GetKey(OptionNames::ScriptArgs), args_dict);
106 if (success) {
107 // FIXME: The resolver needs a copy of the ARGS dict that it can own,
108 // so I need to make a copy constructor for the Dictionary so I can pass
109 // that to it here. For now the args are empty.
110 //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict);
111
112 }
113 ScriptInterpreter *script_interp = bkpt->GetTarget()
114 .GetDebugger()
115 .GetCommandInterpreter()
116 .GetScriptInterpreter();
117 return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl,
118 *script_interp);
119}
120
121StructuredData::ObjectSP
122BreakpointResolverScripted::SerializeToStructuredData() {
123 StructuredData::DictionarySP options_dict_sp(
124 new StructuredData::Dictionary());
125
126 options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName),
127 m_class_name);
128 return WrapOptionsDict(options_dict_sp);
129}
130
131ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
132 return m_breakpoint->GetTarget().GetDebugger().GetCommandInterpreter()
133 .GetScriptInterpreter();
134}
135
136Searcher::CallbackReturn
137BreakpointResolverScripted::SearchCallback(SearchFilter &filter,
138 SymbolContext &context, Address *addr,
139 bool containing) {
140 assert(m_breakpoint != NULL)((m_breakpoint != __null) ? static_cast<void> (0) : __assert_fail
("m_breakpoint != NULL", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Breakpoint/BreakpointResolverScripted.cpp"
, 140, __PRETTY_FUNCTION__))
;
141 bool should_continue = true;
142 if (!m_implementation_sp)
143 return Searcher::eCallbackReturnStop;
144
145 ScriptInterpreter *interp = GetScriptInterpreter();
146 should_continue = interp->ScriptedBreakpointResolverSearchCallback(
147 m_implementation_sp,
148 &context);
149 if (should_continue)
150 return Searcher::eCallbackReturnContinue;
151 else
152 return Searcher::eCallbackReturnStop;
153}
154
155lldb::SearchDepth
156BreakpointResolverScripted::GetDepth() {
157 assert(m_breakpoint != NULL)((m_breakpoint != __null) ? static_cast<void> (0) : __assert_fail
("m_breakpoint != NULL", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/source/Breakpoint/BreakpointResolverScripted.cpp"
, 157, __PRETTY_FUNCTION__))
;
158 lldb::SearchDepth depth = lldb::eSearchDepthModule;
159 if (m_implementation_sp) {
160 ScriptInterpreter *interp = GetScriptInterpreter();
161 depth = interp->ScriptedBreakpointResolverSearchDepth(
162 m_implementation_sp);
163 }
164 return depth;
165}
166
167void BreakpointResolverScripted::GetDescription(Stream *s) {
168 StructuredData::GenericSP generic_sp;
169 std::string short_help;
170
171 if (m_implementation_sp) {
172 ScriptInterpreter *interp = GetScriptInterpreter();
173 interp->GetShortHelpForCommandObject(m_implementation_sp,
174 short_help);
175 }
176 if (!short_help.empty())
177 s->PutCString(short_help.c_str());
178 else
179 s->Printf("python class = %s", m_class_name.c_str());
180}
181
182void BreakpointResolverScripted::Dump(Stream *s) const {}
183
184lldb::BreakpointResolverSP
185BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) {
186 ScriptInterpreter *script_interp = GetScriptInterpreter();
187 // FIXME: Have to make a copy of the arguments from the m_args_ptr and then
188 // pass that to the new resolver.
189 lldb::BreakpointResolverSP ret_sp(
190 new BreakpointResolverScripted(&breakpoint, m_class_name,
191 m_depth, nullptr, *script_interp));
192 return ret_sp;
193}

/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include/lldb/Utility/StructuredData.h

1//===-- StructuredData.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 liblldb_StructuredData_h_
11#define liblldb_StructuredData_h_
12
13#include "llvm/ADT/StringRef.h"
14
15#include "lldb/Utility/ConstString.h"
16#include "lldb/Utility/FileSpec.h" // for FileSpec
17#include "lldb/lldb-enumerations.h" // for StructuredDataType
18
19#include <cassert> // for assert
20#include <cstddef> // for size_t
21#include <cstdint> // for uint64_t
22#include <functional>
23#include <map>
24#include <memory>
25#include <string>
26#include <type_traits> // for move
27#include <utility>
28#include <vector>
29
30namespace lldb_private {
31class Status;
32}
33namespace lldb_private {
34class Stream;
35}
36
37namespace lldb_private {
38
39//----------------------------------------------------------------------
40/// @class StructuredData StructuredData.h "lldb/Utility/StructuredData.h"
41/// A class which can hold structured data
42///
43/// The StructuredData class is designed to hold the data from a JSON or plist
44/// style file -- a serialized data structure with dictionaries (maps,
45/// hashes), arrays, and concrete values like integers, floating point
46/// numbers, strings, booleans.
47///
48/// StructuredData does not presuppose any knowledge of the schema for the
49/// data it is holding; it can parse JSON data, for instance, and other parts
50/// of lldb can iterate through the parsed data set to find keys and values
51/// that may be present.
52//----------------------------------------------------------------------
53
54class StructuredData {
55public:
56 class Object;
57 class Array;
58 class Integer;
59 class Float;
60 class Boolean;
61 class String;
62 class Dictionary;
63 class Generic;
64
65 typedef std::shared_ptr<Object> ObjectSP;
66 typedef std::shared_ptr<Array> ArraySP;
67 typedef std::shared_ptr<Integer> IntegerSP;
68 typedef std::shared_ptr<Float> FloatSP;
69 typedef std::shared_ptr<Boolean> BooleanSP;
70 typedef std::shared_ptr<String> StringSP;
71 typedef std::shared_ptr<Dictionary> DictionarySP;
72 typedef std::shared_ptr<Generic> GenericSP;
73
74 class Object : public std::enable_shared_from_this<Object> {
75 public:
76 Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
77 : m_type(t) {}
78
79 virtual ~Object() = default;
80
81 virtual bool IsValid() const { return true; }
82
83 virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; }
84
85 lldb::StructuredDataType GetType() const { return m_type; }
86
87 void SetType(lldb::StructuredDataType t) { m_type = t; }
88
89 Array *GetAsArray() {
90 return ((m_type == lldb::eStructuredDataTypeArray)
91 ? static_cast<Array *>(this)
92 : nullptr);
93 }
94
95 Dictionary *GetAsDictionary() {
96 return ((m_type == lldb::eStructuredDataTypeDictionary)
97 ? static_cast<Dictionary *>(this)
98 : nullptr);
99 }
100
101 Integer *GetAsInteger() {
102 return ((m_type == lldb::eStructuredDataTypeInteger)
103 ? static_cast<Integer *>(this)
104 : nullptr);
105 }
106
107 uint64_t GetIntegerValue(uint64_t fail_value = 0) {
108 Integer *integer = GetAsInteger();
109 return ((integer != nullptr) ? integer->GetValue() : fail_value);
110 }
111
112 Float *GetAsFloat() {
113 return ((m_type == lldb::eStructuredDataTypeFloat)
114 ? static_cast<Float *>(this)
115 : nullptr);
116 }
117
118 double GetFloatValue(double fail_value = 0.0) {
119 Float *f = GetAsFloat();
120 return ((f != nullptr) ? f->GetValue() : fail_value);
121 }
122
123 Boolean *GetAsBoolean() {
124 return ((m_type == lldb::eStructuredDataTypeBoolean)
125 ? static_cast<Boolean *>(this)
126 : nullptr);
127 }
128
129 bool GetBooleanValue(bool fail_value = false) {
130 Boolean *b = GetAsBoolean();
131 return ((b != nullptr) ? b->GetValue() : fail_value);
132 }
133
134 String *GetAsString() {
135 return ((m_type == lldb::eStructuredDataTypeString)
136 ? static_cast<String *>(this)
137 : nullptr);
138 }
139
140 llvm::StringRef GetStringValue(const char *fail_value = nullptr) {
141 String *s = GetAsString();
142 if (s)
143 return s->GetValue();
144
145 return fail_value;
146 }
147
148 Generic *GetAsGeneric() {
149 return ((m_type == lldb::eStructuredDataTypeGeneric)
150 ? static_cast<Generic *>(this)
151 : nullptr);
152 }
153
154 ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path);
155
156 void DumpToStdout(bool pretty_print = true) const;
157
158 virtual void Dump(Stream &s, bool pretty_print = true) const = 0;
159
160 private:
161 lldb::StructuredDataType m_type;
162 };
163
164 class Array : public Object {
165 public:
166 Array() : Object(lldb::eStructuredDataTypeArray) {}
167
168 ~Array() override = default;
169
170 bool
171 ForEach(std::function<bool(Object *object)> const &foreach_callback) const {
172 for (const auto &object_sp : m_items) {
173 if (foreach_callback(object_sp.get()) == false)
174 return false;
175 }
176 return true;
177 }
178
179 size_t GetSize() const { return m_items.size(); }
180
181 ObjectSP operator[](size_t idx) {
182 if (idx < m_items.size())
183 return m_items[idx];
184 return ObjectSP();
185 }
186
187 ObjectSP GetItemAtIndex(size_t idx) const {
188 assert(idx < GetSize())((idx < GetSize()) ? static_cast<void> (0) : __assert_fail
("idx < GetSize()", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lldb/include/lldb/Utility/StructuredData.h"
, 188, __PRETTY_FUNCTION__))
;
189 if (idx < m_items.size())
190 return m_items[idx];
191 return ObjectSP();
192 }
193
194 template <class IntType>
195 bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
196 ObjectSP value_sp = GetItemAtIndex(idx);
197 if (value_sp.get()) {
198 if (auto int_value = value_sp->GetAsInteger()) {
199 result = static_cast<IntType>(int_value->GetValue());
200 return true;
201 }
202 }
203 return false;
204 }
205
206 template <class IntType>
207 bool GetItemAtIndexAsInteger(size_t idx, IntType &result,
208 IntType default_val) const {
209 bool success = GetItemAtIndexAsInteger(idx, result);
210 if (!success)
211 result = default_val;
212 return success;
213 }
214
215 bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const {
216 ObjectSP value_sp = GetItemAtIndex(idx);
217 if (value_sp.get()) {
218 if (auto string_value = value_sp->GetAsString()) {
219 result = string_value->GetValue();
220 return true;
221 }
222 }
223 return false;
224 }
225
226 bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result,
227 llvm::StringRef default_val) const {
228 bool success = GetItemAtIndexAsString(idx, result);
229 if (!success)
230 result = default_val;
231 return success;
232 }
233
234 bool GetItemAtIndexAsString(size_t idx, ConstString &result) const {
235 ObjectSP value_sp = GetItemAtIndex(idx);
236 if (value_sp.get()) {
237 if (auto string_value = value_sp->GetAsString()) {
238 result = ConstString(string_value->GetValue());
239 return true;
240 }
241 }
242 return false;
243 }
244
245 bool GetItemAtIndexAsString(size_t idx, ConstString &result,
246 const char *default_val) const {
247 bool success = GetItemAtIndexAsString(idx, result);
248 if (!success)
249 result.SetCString(default_val);
250 return success;
251 }
252
253 bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const {
254 result = nullptr;
255 ObjectSP value_sp = GetItemAtIndex(idx);
256 if (value_sp.get()) {
257 result = value_sp->GetAsDictionary();
258 return (result != nullptr);
259 }
260 return false;
261 }
262
263 bool GetItemAtIndexAsArray(size_t idx, Array *&result) const {
264 result = nullptr;
265 ObjectSP value_sp = GetItemAtIndex(idx);
266 if (value_sp.get()) {
267 result = value_sp->GetAsArray();
268 return (result != nullptr);
269 }
270 return false;
271 }
272
273 void Push(ObjectSP item) { m_items.push_back(item); }
274
275 void AddItem(ObjectSP item) { m_items.push_back(item); }
276
277 void Dump(Stream &s, bool pretty_print = true) const override;
278
279 protected:
280 typedef std::vector<ObjectSP> collection;
281 collection m_items;
282 };
283
284 class Integer : public Object {
285 public:
286 Integer(uint64_t i = 0)
287 : Object(lldb::eStructuredDataTypeInteger), m_value(i) {}
288
289 ~Integer() override = default;
290
291 void SetValue(uint64_t value) { m_value = value; }
292
293 uint64_t GetValue() { return m_value; }
294
295 void Dump(Stream &s, bool pretty_print = true) const override;
296
297 protected:
298 uint64_t m_value;
299 };
300
301 class Float : public Object {
302 public:
303 Float(double d = 0.0)
304 : Object(lldb::eStructuredDataTypeFloat), m_value(d) {}
305
306 ~Float() override = default;
307
308 void SetValue(double value) { m_value = value; }
309
310 double GetValue() { return m_value; }
311
312 void Dump(Stream &s, bool pretty_print = true) const override;
313
314 protected:
315 double m_value;
316 };
317
318 class Boolean : public Object {
319 public:
320 Boolean(bool b = false)
321 : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {}
322
323 ~Boolean() override = default;
324
325 void SetValue(bool value) { m_value = value; }
326
327 bool GetValue() { return m_value; }
328
329 void Dump(Stream &s, bool pretty_print = true) const override;
330
331 protected:
332 bool m_value;
333 };
334
335 class String : public Object {
336 public:
337 String() : Object(lldb::eStructuredDataTypeString) {}
338 explicit String(llvm::StringRef S)
339 : Object(lldb::eStructuredDataTypeString), m_value(S) {}
340
341 void SetValue(llvm::StringRef S) { m_value = S; }
342
343 llvm::StringRef GetValue() { return m_value; }
344
345 void Dump(Stream &s, bool pretty_print = true) const override;
346
347 protected:
348 std::string m_value;
349 };
350
351 class Dictionary : public Object {
352 public:
353 Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {}
354
355 ~Dictionary() override = default;
356
357 size_t GetSize() const { return m_dict.size(); }
358
359 void ForEach(std::function<bool(ConstString key, Object *object)> const
360 &callback) const {
361 for (const auto &pair : m_dict) {
362 if (callback(pair.first, pair.second.get()) == false)
363 break;
364 }
365 }
366
367 ObjectSP GetKeys() const {
368 auto object_sp = std::make_shared<Array>();
369 collection::const_iterator iter;
370 for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) {
371 auto key_object_sp = std::make_shared<String>();
372 key_object_sp->SetValue(iter->first.AsCString());
373 object_sp->Push(key_object_sp);
374 }
375 return object_sp;
376 }
377
378 ObjectSP GetValueForKey(llvm::StringRef key) const {
379 ObjectSP value_sp;
380 if (!key.empty()) {
381 ConstString key_cs(key);
382 collection::const_iterator iter = m_dict.find(key_cs);
383 if (iter != m_dict.end())
384 value_sp = iter->second;
385 }
386 return value_sp;
387 }
388
389 bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {
390 bool success = false;
391 ObjectSP value_sp = GetValueForKey(key);
392 if (value_sp.get()) {
393 Boolean *result_ptr = value_sp->GetAsBoolean();
394 if (result_ptr) {
395 result = result_ptr->GetValue();
396 success = true;
397 }
398 }
399 return success;
400 }
401 template <class IntType>
402 bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
403 ObjectSP value_sp = GetValueForKey(key);
404 if (value_sp) {
405 if (auto int_value = value_sp->GetAsInteger()) {
406 result = static_cast<IntType>(int_value->GetValue());
407 return true;
408 }
409 }
410 return false;
411 }
412
413 template <class IntType>
414 bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result,
415 IntType default_val) const {
416 bool success = GetValueForKeyAsInteger<IntType>(key, result);
417 if (!success)
418 result = default_val;
419 return success;
420 }
421
422 bool GetValueForKeyAsString(llvm::StringRef key,
423 llvm::StringRef &result) const {
424 ObjectSP value_sp = GetValueForKey(key);
425 if (value_sp.get()) {
426 if (auto string_value = value_sp->GetAsString()) {
427 result = string_value->GetValue();
428 return true;
429 }
430 }
431 return false;
432 }
433
434 bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result,
435 const char *default_val) const {
436 bool success = GetValueForKeyAsString(key, result);
437 if (!success) {
438 if (default_val)
439 result = default_val;
440 else
441 result = llvm::StringRef();
442 }
443 return success;
444 }
445
446 bool GetValueForKeyAsString(llvm::StringRef key,
447 ConstString &result) const {
448 ObjectSP value_sp = GetValueForKey(key);
449 if (value_sp.get()) {
450 if (auto string_value = value_sp->GetAsString()) {
451 result = ConstString(string_value->GetValue());
452 return true;
453 }
454 }
455 return false;
456 }
457
458 bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result,
459 const char *default_val) const {
460 bool success = GetValueForKeyAsString(key, result);
461 if (!success)
462 result.SetCString(default_val);
463 return success;
464 }
465
466 bool GetValueForKeyAsDictionary(llvm::StringRef key,
467 Dictionary *&result) const {
468 result = nullptr;
469 ObjectSP value_sp = GetValueForKey(key);
9
Potential memory leak
470 if (value_sp.get()) {
471 result = value_sp->GetAsDictionary();
472 return (result != nullptr);
473 }
474 return false;
475 }
476
477 bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const {
478 result = nullptr;
479 ObjectSP value_sp = GetValueForKey(key);
480 if (value_sp.get()) {
481 result = value_sp->GetAsArray();
482 return (result != nullptr);
483 }
484 return false;
485 }
486
487 bool HasKey(llvm::StringRef key) const {
488 ConstString key_cs(key);
489 collection::const_iterator search = m_dict.find(key_cs);
490 return search != m_dict.end();
491 }
492
493 void AddItem(llvm::StringRef key, ObjectSP value_sp) {
494 ConstString key_cs(key);
495 m_dict[key_cs] = value_sp;
496 }
497
498 void AddIntegerItem(llvm::StringRef key, uint64_t value) {
499 AddItem(key, std::make_shared<Integer>(value));
500 }
501
502 void AddFloatItem(llvm::StringRef key, double value) {
503 AddItem(key, std::make_shared<Float>(value));
504 }
505
506 void AddStringItem(llvm::StringRef key, llvm::StringRef value) {
507 AddItem(key, std::make_shared<String>(std::move(value)));
508 }
509
510 void AddBooleanItem(llvm::StringRef key, bool value) {
511 AddItem(key, std::make_shared<Boolean>(value));
512 }
513
514 void Dump(Stream &s, bool pretty_print = true) const override;
515
516 protected:
517 typedef std::map<ConstString, ObjectSP> collection;
518 collection m_dict;
519 };
520
521 class Null : public Object {
522 public:
523 Null() : Object(lldb::eStructuredDataTypeNull) {}
524
525 ~Null() override = default;
526
527 bool IsValid() const override { return false; }
528
529 void Dump(Stream &s, bool pretty_print = true) const override;
530 };
531
532 class Generic : public Object {
533 public:
534 explicit Generic(void *object = nullptr)
535 : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {}
536
537 void SetValue(void *value) { m_object = value; }
538
539 void *GetValue() const { return m_object; }
540
541 bool IsValid() const override { return m_object != nullptr; }
542
543 void Dump(Stream &s, bool pretty_print = true) const override;
544
545 private:
546 void *m_object;
547 };
548
549 static ObjectSP ParseJSON(std::string json_text);
550
551 static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
552};
553
554} // namespace lldb_private
555
556#endif // liblldb_StructuredData_h_