Coverage Report

Created: 2023-09-12 09:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Utility/StructuredData.h
Line
Count
Source (jump to first uncovered line)
1
//===-- StructuredData.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_STRUCTUREDDATA_H
10
#define LLDB_UTILITY_STRUCTUREDDATA_H
11
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/Support/JSON.h"
14
15
#include "lldb/Utility/ConstString.h"
16
#include "lldb/Utility/FileSpec.h"
17
#include "lldb/Utility/Stream.h"
18
#include "lldb/lldb-enumerations.h"
19
20
#include <cassert>
21
#include <cstddef>
22
#include <cstdint>
23
#include <functional>
24
#include <map>
25
#include <memory>
26
#include <string>
27
#include <type_traits>
28
#include <utility>
29
#include <variant>
30
#include <vector>
31
32
namespace lldb_private {
33
class Status;
34
}
35
36
namespace lldb_private {
37
38
/// \class StructuredData StructuredData.h "lldb/Utility/StructuredData.h"
39
/// A class which can hold structured data
40
///
41
/// The StructuredData class is designed to hold the data from a JSON or plist
42
/// style file -- a serialized data structure with dictionaries (maps,
43
/// hashes), arrays, and concrete values like integers, floating point
44
/// numbers, strings, booleans.
45
///
46
/// StructuredData does not presuppose any knowledge of the schema for the
47
/// data it is holding; it can parse JSON data, for instance, and other parts
48
/// of lldb can iterate through the parsed data set to find keys and values
49
/// that may be present.
50
51
class StructuredData {
52
  template <typename N> class Integer;
53
54
public:
55
  class Object;
56
  class Array;
57
  using UnsignedInteger = Integer<uint64_t>;
58
  using SignedInteger = Integer<int64_t>;
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<UnsignedInteger> UnsignedIntegerSP;
68
  typedef std::shared_ptr<SignedInteger> SignedIntegerSP;
69
  typedef std::shared_ptr<Float> FloatSP;
70
  typedef std::shared_ptr<Boolean> BooleanSP;
71
  typedef std::shared_ptr<String> StringSP;
72
  typedef std::shared_ptr<Dictionary> DictionarySP;
73
  typedef std::shared_ptr<Generic> GenericSP;
74
75
  typedef std::variant<UnsignedIntegerSP, SignedIntegerSP> IntegerSP;
76
77
  class Object : public std::enable_shared_from_this<Object> {
78
  public:
79
    Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
80
4.20M
        : m_type(t) {}
81
82
4.20M
    virtual ~Object() = default;
83
84
234
    virtual bool IsValid() const { return true; }
85
86
0
    virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; }
87
88
10.7k
    lldb::StructuredDataType GetType() const { return m_type; }
89
90
0
    void SetType(lldb::StructuredDataType t) { m_type = t; }
91
92
343k
    Array *GetAsArray() {
93
343k
      return ((m_type == lldb::eStructuredDataTypeArray)
94
343k
                  ? static_cast<Array *>(this)
95
343k
                  : 
nullptr0
);
96
343k
    }
97
98
800k
    Dictionary *GetAsDictionary() {
99
800k
      return ((m_type == lldb::eStructuredDataTypeDictionary)
100
800k
                  ? static_cast<Dictionary *>(this)
101
18.4E
                  : nullptr);
102
800k
    }
103
104
2.27M
    UnsignedInteger *GetAsUnsignedInteger() {
105
      // NOTE: For backward compatibility, eStructuredDataTypeInteger is
106
      // the same as eStructuredDataTypeUnsignedInteger.
107
2.27M
      return ((m_type == lldb::eStructuredDataTypeInteger ||
108
2.27M
               
m_type == lldb::eStructuredDataTypeUnsignedInteger1
)
109
2.27M
                  ? static_cast<UnsignedInteger *>(this)
110
18.4E
                  : nullptr);
111
2.27M
    }
112
113
1
    SignedInteger *GetAsSignedInteger() {
114
1
      return ((m_type == lldb::eStructuredDataTypeSignedInteger)
115
1
                  ? static_cast<SignedInteger *>(this)
116
1
                  : 
nullptr0
);
117
1
    }
118
119
2.25M
    uint64_t GetUnsignedIntegerValue(uint64_t fail_value = 0) {
120
2.25M
      UnsignedInteger *integer = GetAsUnsignedInteger();
121
18.4E
      return (
(integer != nullptr)2.25M
?
integer->GetValue()2.25M
: fail_value);
122
2.25M
    }
123
124
1
    int64_t GetSignedIntegerValue(int64_t fail_value = 0) {
125
1
      SignedInteger *integer = GetAsSignedInteger();
126
1
      return ((integer != nullptr) ? integer->GetValue() : 
fail_value0
);
127
1
    }
128
129
1
    Float *GetAsFloat() {
130
1
      return ((m_type == lldb::eStructuredDataTypeFloat)
131
1
                  ? static_cast<Float *>(this)
132
1
                  : 
nullptr0
);
133
1
    }
134
135
1
    double GetFloatValue(double fail_value = 0.0) {
136
1
      Float *f = GetAsFloat();
137
1
      return ((f != nullptr) ? f->GetValue() : 
fail_value0
);
138
1
    }
139
140
7.58k
    Boolean *GetAsBoolean() {
141
7.58k
      return ((m_type == lldb::eStructuredDataTypeBoolean)
142
7.58k
                  ? static_cast<Boolean *>(this)
143
7.58k
                  : 
nullptr0
);
144
7.58k
    }
145
146
7.48k
    bool GetBooleanValue(bool fail_value = false) {
147
7.48k
      Boolean *b = GetAsBoolean();
148
7.48k
      return ((b != nullptr) ? b->GetValue() : 
fail_value0
);
149
7.48k
    }
150
151
969k
    String *GetAsString() {
152
969k
      return ((m_type == lldb::eStructuredDataTypeString)
153
969k
                  ? 
static_cast<String *>(this)969k
154
969k
                  : 
nullptr2
);
155
969k
    }
156
157
220k
    llvm::StringRef GetStringValue(const char *fail_value = nullptr) {
158
220k
      String *s = GetAsString();
159
220k
      if (s)
160
220k
        return s->GetValue();
161
162
2
      return fail_value;
163
220k
    }
164
165
1.61k
    Generic *GetAsGeneric() {
166
1.61k
      return ((m_type == lldb::eStructuredDataTypeGeneric)
167
1.61k
                  ? static_cast<Generic *>(this)
168
1.61k
                  : 
nullptr0
);
169
1.61k
    }
170
171
    ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path);
172
173
    void DumpToStdout(bool pretty_print = true) const;
174
175
    virtual void Serialize(llvm::json::OStream &s) const = 0;
176
177
6.43k
    void Dump(lldb_private::Stream &s, bool pretty_print = true) const {
178
6.43k
      llvm::json::OStream jso(s.AsRawOstream(), pretty_print ? 
21
:
06.42k
);
179
6.43k
      Serialize(jso);
180
6.43k
    }
181
182
0
    virtual void GetDescription(lldb_private::Stream &s) const {
183
0
      s.IndentMore();
184
0
      Dump(s, false);
185
0
      s.IndentLess();
186
0
    }
187
188
  private:
189
    lldb::StructuredDataType m_type;
190
  };
191
192
  class Array : public Object {
193
  public:
194
135k
    Array() : Object(lldb::eStructuredDataTypeArray) {}
195
196
135k
    ~Array() override = default;
197
198
    bool
199
17.7k
    ForEach(std::function<bool(Object *object)> const &foreach_callback) const {
200
43.0k
      for (const auto &object_sp : m_items) {
201
43.0k
        if (!foreach_callback(object_sp.get()))
202
0
          return false;
203
43.0k
      }
204
17.7k
      return true;
205
17.7k
    }
206
207
550k
    size_t GetSize() const { return m_items.size(); }
208
209
0
    ObjectSP operator[](size_t idx) {
210
0
      if (idx < m_items.size())
211
0
        return m_items[idx];
212
0
      return ObjectSP();
213
0
    }
214
215
430k
    ObjectSP GetItemAtIndex(size_t idx) const {
216
430k
      assert(idx < GetSize());
217
430k
      if (idx < m_items.size())
218
430k
        return m_items[idx];
219
18.4E
      return ObjectSP();
220
430k
    }
221
222
    template <class IntType>
223
9
    bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
224
9
      ObjectSP value_sp = GetItemAtIndex(idx);
225
9
      if (value_sp.get()) {
226
9
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
227
9
          if (auto signed_value = value_sp->GetAsSignedInteger()) {
228
9
            result = static_cast<IntType>(signed_value->GetValue());
229
9
            return true;
230
9
          }
231
9
        } else {
232
9
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
233
9
            result = static_cast<IntType>(unsigned_value->GetValue());
234
9
            return true;
235
9
          }
236
9
        }
237
9
      }
238
0
      return false;
239
9
    }
bool lldb_private::StructuredData::Array::GetItemAtIndexAsInteger<unsigned int>(unsigned long, unsigned int&) const
Line
Count
Source
223
9
    bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
224
9
      ObjectSP value_sp = GetItemAtIndex(idx);
225
9
      if (value_sp.get()) {
226
9
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
227
9
          if (auto signed_value = value_sp->GetAsSignedInteger()) {
228
9
            result = static_cast<IntType>(signed_value->GetValue());
229
9
            return true;
230
9
          }
231
9
        } else {
232
9
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
233
9
            result = static_cast<IntType>(unsigned_value->GetValue());
234
9
            return true;
235
9
          }
236
9
        }
237
9
      }
238
0
      return false;
239
9
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Array::GetItemAtIndexAsInteger<unsigned long long>(unsigned long, unsigned long long&) const
240
241
    template <class IntType>
242
    bool GetItemAtIndexAsInteger(size_t idx, IntType &result,
243
                                 IntType default_val) const {
244
      bool success = GetItemAtIndexAsInteger(idx, result);
245
      if (!success)
246
        result = default_val;
247
      return success;
248
    }
249
250
41
    bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const {
251
41
      ObjectSP value_sp = GetItemAtIndex(idx);
252
41
      if (value_sp.get()) {
253
41
        if (auto string_value = value_sp->GetAsString()) {
254
41
          result = string_value->GetValue();
255
41
          return true;
256
41
        }
257
41
      }
258
0
      return false;
259
41
    }
260
261
    bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result,
262
0
                                llvm::StringRef default_val) const {
263
0
      bool success = GetItemAtIndexAsString(idx, result);
264
0
      if (!success)
265
0
        result = default_val;
266
0
      return success;
267
0
    }
268
269
86
    bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const {
270
86
      result = nullptr;
271
86
      ObjectSP value_sp = GetItemAtIndex(idx);
272
86
      if (value_sp.get()) {
273
86
        result = value_sp->GetAsDictionary();
274
86
        return (result != nullptr);
275
86
      }
276
0
      return false;
277
86
    }
278
279
0
    bool GetItemAtIndexAsArray(size_t idx, Array *&result) const {
280
0
      result = nullptr;
281
0
      ObjectSP value_sp = GetItemAtIndex(idx);
282
0
      if (value_sp.get()) {
283
0
        result = value_sp->GetAsArray();
284
0
        return (result != nullptr);
285
0
      }
286
0
      return false;
287
0
    }
288
289
18
    void Push(const ObjectSP &item) { m_items.push_back(item); }
290
291
572k
    void AddItem(const ObjectSP &item) { m_items.push_back(item); }
292
293
97.1k
    template <typename T> void AddIntegerItem(T value) {
294
97.1k
      static_assert(std::is_integral<T>::value ||
295
97.1k
                        std::is_floating_point<T>::value,
296
97.1k
                    "value type should be integral");
297
97.1k
      if constexpr (std::numeric_limits<T>::is_signed)
298
0
        AddItem(std::make_shared<SignedInteger>(value));
299
97.1k
      else
300
97.1k
        AddItem(std::make_shared<UnsignedInteger>(value));
301
97.1k
    }
302
303
0
    void AddFloatItem(double value) { AddItem(std::make_shared<Float>(value)); }
304
305
0
    void AddStringItem(llvm::StringRef value) {
306
0
      AddItem(std::make_shared<String>(std::move(value)));
307
0
    }
308
309
0
    void AddBooleanItem(bool value) {
310
0
      AddItem(std::make_shared<Boolean>(value));
311
0
    }
312
313
    void Serialize(llvm::json::OStream &s) const override;
314
315
    void GetDescription(lldb_private::Stream &s) const override;
316
317
  protected:
318
    typedef std::vector<ObjectSP> collection;
319
    collection m_items;
320
  };
321
322
private:
323
  template <typename N> class Integer : public Object {
324
    static_assert(std::is_integral<N>::value, "N must be an integral type");
325
326
  public:
327
    Integer(N i = 0)
328
        : Object(std::numeric_limits<N>::is_signed
329
                     ? lldb::eStructuredDataTypeSignedInteger
330
                     : lldb::eStructuredDataTypeUnsignedInteger),
331
2.49M
          m_value(i) {}
lldb_private::StructuredData::Integer<unsigned long long>::Integer(unsigned long long)
Line
Count
Source
331
2.49M
          m_value(i) {}
lldb_private::StructuredData::Integer<long long>::Integer(long long)
Line
Count
Source
331
3
          m_value(i) {}
332
2.49M
    ~Integer() override = default;
lldb_private::StructuredData::Integer<unsigned long long>::~Integer()
Line
Count
Source
332
2.49M
    ~Integer() override = default;
lldb_private::StructuredData::Integer<long long>::~Integer()
Line
Count
Source
332
3
    ~Integer() override = default;
333
334
    void SetValue(N value) { m_value = value; }
335
336
2.27M
    N GetValue() { return m_value; }
lldb_private::StructuredData::Integer<unsigned long long>::GetValue()
Line
Count
Source
336
2.27M
    N GetValue() { return m_value; }
lldb_private::StructuredData::Integer<long long>::GetValue()
Line
Count
Source
336
2
    N GetValue() { return m_value; }
337
338
109k
    void Serialize(llvm::json::OStream &s) const override {
339
109k
      s.value(static_cast<N>(m_value));
340
109k
    }
lldb_private::StructuredData::Integer<unsigned long long>::Serialize(llvm::json::OStream&) const
Line
Count
Source
338
109k
    void Serialize(llvm::json::OStream &s) const override {
339
109k
      s.value(static_cast<N>(m_value));
340
109k
    }
lldb_private::StructuredData::Integer<long long>::Serialize(llvm::json::OStream&) const
Line
Count
Source
338
1
    void Serialize(llvm::json::OStream &s) const override {
339
1
      s.value(static_cast<N>(m_value));
340
1
    }
341
342
14
    void GetDescription(lldb_private::Stream &s) const override {
343
14
      s.Printf(std::numeric_limits<N>::is_signed ? 
"%" PRId641
:
"%" PRIu6413
,
344
14
               static_cast<N>(m_value));
345
14
    }
lldb_private::StructuredData::Integer<unsigned long long>::GetDescription(lldb_private::Stream&) const
Line
Count
Source
342
13
    void GetDescription(lldb_private::Stream &s) const override {
343
13
      s.Printf(std::numeric_limits<N>::is_signed ? 
"%" PRId640
: "%" PRIu64,
344
13
               static_cast<N>(m_value));
345
13
    }
lldb_private::StructuredData::Integer<long long>::GetDescription(lldb_private::Stream&) const
Line
Count
Source
342
1
    void GetDescription(lldb_private::Stream &s) const override {
343
1
      s.Printf(std::numeric_limits<N>::is_signed ? "%" PRId64 : 
"%" PRIu640
,
344
1
               static_cast<N>(m_value));
345
1
    }
346
347
  protected:
348
    N m_value;
349
  };
350
351
public:
352
  class Float : public Object {
353
  public:
354
    Float(double d = 0.0)
355
194
        : Object(lldb::eStructuredDataTypeFloat), m_value(d) {}
356
357
194
    ~Float() override = default;
358
359
0
    void SetValue(double value) { m_value = value; }
360
361
1
    double GetValue() { return m_value; }
362
363
    void Serialize(llvm::json::OStream &s) const override;
364
365
    void GetDescription(lldb_private::Stream &s) const override;
366
367
  protected:
368
    double m_value;
369
  };
370
371
  class Boolean : public Object {
372
  public:
373
    Boolean(bool b = false)
374
13.1k
        : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {}
375
376
13.1k
    ~Boolean() override = default;
377
378
10
    void SetValue(bool value) { m_value = value; }
379
380
7.58k
    bool GetValue() { return m_value; }
381
382
    void Serialize(llvm::json::OStream &s) const override;
383
384
    void GetDescription(lldb_private::Stream &s) const override;
385
386
  protected:
387
    bool m_value;
388
  };
389
390
  class String : public Object {
391
  public:
392
469
    String() : Object(lldb::eStructuredDataTypeString) {}
393
    explicit String(llvm::StringRef S)
394
975k
        : Object(lldb::eStructuredDataTypeString), m_value(S) {}
395
396
469
    void SetValue(llvm::StringRef S) { m_value = std::string(S); }
397
398
969k
    llvm::StringRef GetValue() { return m_value; }
399
400
    void Serialize(llvm::json::OStream &s) const override;
401
402
    void GetDescription(lldb_private::Stream &s) const override;
403
404
  protected:
405
    std::string m_value;
406
  };
407
408
  class Dictionary : public Object {
409
  public:
410
584k
    Dictionary() : Object(lldb::eStructuredDataTypeDictionary) {}
411
412
0
    Dictionary(ObjectSP obj_sp) : Object(lldb::eStructuredDataTypeDictionary) {
413
0
      if (!obj_sp || obj_sp->GetType() != lldb::eStructuredDataTypeDictionary) {
414
0
        SetType(lldb::eStructuredDataTypeInvalid);
415
0
        return;
416
0
      }
417
0
418
0
      Dictionary *dict = obj_sp->GetAsDictionary();
419
0
      m_dict = dict->m_dict;
420
0
    }
421
422
584k
    ~Dictionary() override = default;
423
424
22
    size_t GetSize() const { return m_dict.size(); }
425
426
    void ForEach(std::function<bool(ConstString key, Object *object)> const
427
18.6k
                     &callback) const {
428
288k
      for (const auto &pair : m_dict) {
429
288k
        if (!callback(pair.first, pair.second.get()))
430
0
          break;
431
288k
      }
432
18.6k
    }
433
434
16
    ArraySP GetKeys() const {
435
16
      auto array_sp = std::make_shared<Array>();
436
16
      collection::const_iterator iter;
437
34
      for (iter = m_dict.begin(); iter != m_dict.end(); 
++iter18
) {
438
18
        auto key_object_sp = std::make_shared<String>();
439
18
        key_object_sp->SetValue(iter->first.AsCString());
440
18
        array_sp->Push(key_object_sp);
441
18
      }
442
16
      return array_sp;
443
16
    }
444
445
3.39M
    ObjectSP GetValueForKey(llvm::StringRef key) const {
446
3.39M
      ObjectSP value_sp;
447
3.39M
      if (!key.empty()) {
448
3.39M
        ConstString key_cs(key);
449
3.39M
        collection::const_iterator iter = m_dict.find(key_cs);
450
3.39M
        if (iter != m_dict.end())
451
3.39M
          value_sp = iter->second;
452
3.39M
      }
453
3.39M
      return value_sp;
454
3.39M
    }
455
456
105
    bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {
457
105
      bool success = false;
458
105
      ObjectSP value_sp = GetValueForKey(key);
459
105
      if (value_sp.get()) {
460
105
        Boolean *result_ptr = value_sp->GetAsBoolean();
461
105
        if (result_ptr) {
462
105
          result = result_ptr->GetValue();
463
105
          success = true;
464
105
        }
465
105
      }
466
105
      return success;
467
105
    }
468
      
469
    template <class IntType>
470
25.8k
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
471
25.8k
      ObjectSP value_sp = GetValueForKey(key);
472
25.8k
      if (value_sp) {
473
25.6k
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
474
25.6k
          if (auto 
signed_value0
= value_sp->GetAsSignedInteger()) {
475
0
            result = static_cast<IntType>(signed_value->GetValue());
476
0
            return true;
477
0
          }
478
25.6k
        } else {
479
25.6k
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
480
25.6k
            result = static_cast<IntType>(unsigned_value->GetValue());
481
25.6k
            return true;
482
25.6k
          }
483
25.6k
        }
484
25.6k
      }
485
139
      return false;
486
25.8k
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned long long>(llvm::StringRef, unsigned long long&) const
Line
Count
Source
470
25.3k
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
471
25.3k
      ObjectSP value_sp = GetValueForKey(key);
472
25.3k
      if (value_sp) {
473
25.3k
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
474
25.3k
          if (auto signed_value = value_sp->GetAsSignedInteger()) {
475
25.3k
            result = static_cast<IntType>(signed_value->GetValue());
476
25.3k
            return true;
477
25.3k
          }
478
25.3k
        } else {
479
25.3k
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
480
25.3k
            result = static_cast<IntType>(unsigned_value->GetValue());
481
25.3k
            return true;
482
25.3k
          }
483
25.3k
        }
484
25.3k
      }
485
30
      return false;
486
25.3k
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned int>(llvm::StringRef, unsigned int&) const
Line
Count
Source
470
366
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
471
366
      ObjectSP value_sp = GetValueForKey(key);
472
366
      if (value_sp) {
473
257
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
474
257
          if (auto signed_value = value_sp->GetAsSignedInteger()) {
475
257
            result = static_cast<IntType>(signed_value->GetValue());
476
257
            return true;
477
257
          }
478
257
        } else {
479
257
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
480
257
            result = static_cast<IntType>(unsigned_value->GetValue());
481
257
            return true;
482
257
          }
483
257
        }
484
257
      }
485
109
      return false;
486
366
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned short>(llvm::StringRef, unsigned short&) const
Line
Count
Source
470
5
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
471
5
      ObjectSP value_sp = GetValueForKey(key);
472
5
      if (value_sp) {
473
5
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
474
5
          if (auto signed_value = value_sp->GetAsSignedInteger()) {
475
5
            result = static_cast<IntType>(signed_value->GetValue());
476
5
            return true;
477
5
          }
478
5
        } else {
479
5
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
480
5
            result = static_cast<IntType>(unsigned_value->GetValue());
481
5
            return true;
482
5
          }
483
5
        }
484
5
      }
485
0
      return false;
486
5
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Format>(llvm::StringRef, lldb::Format&) const
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Encoding>(llvm::StringRef, lldb::Encoding&) const
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned long>(llvm::StringRef, unsigned long&) const
Line
Count
Source
470
85
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
471
85
      ObjectSP value_sp = GetValueForKey(key);
472
85
      if (value_sp) {
473
85
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
474
85
          if (auto signed_value = value_sp->GetAsSignedInteger()) {
475
85
            result = static_cast<IntType>(signed_value->GetValue());
476
85
            return true;
477
85
          }
478
85
        } else {
479
85
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
480
85
            result = static_cast<IntType>(unsigned_value->GetValue());
481
85
            return true;
482
85
          }
483
85
        }
484
85
      }
485
0
      return false;
486
85
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::StopReason>(llvm::StringRef, lldb::StopReason&) const
Line
Count
Source
470
3
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
471
3
      ObjectSP value_sp = GetValueForKey(key);
472
3
      if (value_sp) {
473
3
        if constexpr (std::numeric_limits<IntType>::is_signed) 
{0
474
3
          if (auto signed_value = value_sp->GetAsSignedInteger()) {
475
3
            result = static_cast<IntType>(signed_value->GetValue());
476
3
            return true;
477
3
          }
478
3
        } else {
479
3
          if (auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
480
3
            result = static_cast<IntType>(unsigned_value->GetValue());
481
3
            return true;
482
3
          }
483
3
        }
484
3
      }
485
0
      return false;
486
3
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<int>(llvm::StringRef, int&) const
487
488
    template <class IntType>
489
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result,
490
1.25k
                                 IntType default_val) const {
491
1.25k
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
492
1.25k
      if (!success)
493
127
        result = default_val;
494
1.25k
      return success;
495
1.25k
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Format>(llvm::StringRef, lldb::Format&, lldb::Format) const
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Encoding>(llvm::StringRef, lldb::Encoding&, lldb::Encoding) const
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned int>(llvm::StringRef, unsigned int&, unsigned int) const
Line
Count
Source
490
252
                                 IntType default_val) const {
491
252
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
492
252
      if (!success)
493
103
        result = default_val;
494
252
      return success;
495
252
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<int>(llvm::StringRef, int&, int) const
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned long long>(llvm::StringRef, unsigned long long&, unsigned long long) const
Line
Count
Source
490
999
                                 IntType default_val) const {
491
999
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
492
999
      if (!success)
493
24
        result = default_val;
494
999
      return success;
495
999
    }
496
497
    bool GetValueForKeyAsString(llvm::StringRef key,
498
24.7k
                                llvm::StringRef &result) const {
499
24.7k
      ObjectSP value_sp = GetValueForKey(key);
500
24.7k
      if (value_sp.get()) {
501
24.6k
        if (auto string_value = value_sp->GetAsString()) {
502
24.6k
          result = string_value->GetValue();
503
24.6k
          return true;
504
24.6k
        }
505
24.6k
      }
506
117
      return false;
507
24.7k
    }
508
509
    bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result,
510
84
                                const char *default_val) const {
511
84
      bool success = GetValueForKeyAsString(key, result);
512
84
      if (!success) {
513
0
        if (default_val)
514
0
          result = default_val;
515
0
        else
516
0
          result = llvm::StringRef();
517
0
      }
518
84
      return success;
519
84
    }
520
521
    bool GetValueForKeyAsDictionary(llvm::StringRef key,
522
138
                                    Dictionary *&result) const {
523
138
      result = nullptr;
524
138
      ObjectSP value_sp = GetValueForKey(key);
525
138
      if (value_sp.get()) {
526
107
        result = value_sp->GetAsDictionary();
527
107
        return (result != nullptr);
528
107
      }
529
31
      return false;
530
138
    }
531
532
150
    bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const {
533
150
      result = nullptr;
534
150
      ObjectSP value_sp = GetValueForKey(key);
535
150
      if (value_sp.get()) {
536
43
        result = value_sp->GetAsArray();
537
43
        return (result != nullptr);
538
43
      }
539
107
      return false;
540
150
    }
541
542
1.97M
    bool HasKey(llvm::StringRef key) const {
543
1.97M
      ConstString key_cs(key);
544
1.97M
      collection::const_iterator search = m_dict.find(key_cs);
545
1.97M
      return search != m_dict.end();
546
1.97M
    }
547
548
3.60M
    void AddItem(llvm::StringRef key, ObjectSP value_sp) {
549
3.60M
      ConstString key_cs(key);
550
3.60M
      m_dict[key_cs] = std::move(value_sp);
551
3.60M
    }
552
553
11.8k
    template <typename T> void AddIntegerItem(llvm::StringRef key, T value) {
554
11.8k
      static_assert(std::is_integral<T>::value ||
555
11.8k
                        std::is_floating_point<T>::value,
556
11.8k
                    "value type should be integral");
557
11.8k
      if constexpr (std::numeric_limits<T>::is_signed)
558
0
        AddItem(key, std::make_shared<SignedInteger>(value));
559
11.8k
      else
560
11.8k
        AddItem(key, std::make_shared<UnsignedInteger>(value));
561
11.8k
    }
void lldb_private::StructuredData::Dictionary::AddIntegerItem<unsigned long long>(llvm::StringRef, unsigned long long)
Line
Count
Source
553
6.75k
    template <typename T> void AddIntegerItem(llvm::StringRef key, T value) {
554
6.75k
      static_assert(std::is_integral<T>::value ||
555
6.75k
                        std::is_floating_point<T>::value,
556
6.75k
                    "value type should be integral");
557
6.75k
      if constexpr (std::numeric_limits<T>::is_signed)
558
0
        AddItem(key, std::make_shared<SignedInteger>(value));
559
6.75k
      else
560
6.75k
        AddItem(key, std::make_shared<UnsignedInteger>(value));
561
6.75k
    }
Unexecuted instantiation: void lldb_private::StructuredData::Dictionary::AddIntegerItem<int>(llvm::StringRef, int)
Unexecuted instantiation: void lldb_private::StructuredData::Dictionary::AddIntegerItem<long long>(llvm::StringRef, long long)
void lldb_private::StructuredData::Dictionary::AddIntegerItem<unsigned int>(llvm::StringRef, unsigned int)
Line
Count
Source
553
49
    template <typename T> void AddIntegerItem(llvm::StringRef key, T value) {
554
49
      static_assert(std::is_integral<T>::value ||
555
49
                        std::is_floating_point<T>::value,
556
49
                    "value type should be integral");
557
49
      if constexpr (std::numeric_limits<T>::is_signed)
558
0
        AddItem(key, std::make_shared<SignedInteger>(value));
559
49
      else
560
49
        AddItem(key, std::make_shared<UnsignedInteger>(value));
561
49
    }
void lldb_private::StructuredData::Dictionary::AddIntegerItem<unsigned short>(llvm::StringRef, unsigned short)
Line
Count
Source
553
5.02k
    template <typename T> void AddIntegerItem(llvm::StringRef key, T value) {
554
5.02k
      static_assert(std::is_integral<T>::value ||
555
5.02k
                        std::is_floating_point<T>::value,
556
5.02k
                    "value type should be integral");
557
5.02k
      if constexpr (std::numeric_limits<T>::is_signed)
558
0
        AddItem(key, std::make_shared<SignedInteger>(value));
559
5.02k
      else
560
5.02k
        AddItem(key, std::make_shared<UnsignedInteger>(value));
561
5.02k
    }
Unexecuted instantiation: void lldb_private::StructuredData::Dictionary::AddIntegerItem<unsigned long>(llvm::StringRef, unsigned long)
562
563
0
    void AddFloatItem(llvm::StringRef key, double value) {
564
0
      AddItem(key, std::make_shared<Float>(value));
565
0
    }
566
567
1.36k
    void AddStringItem(llvm::StringRef key, llvm::StringRef value) {
568
1.36k
      AddItem(key, std::make_shared<String>(std::move(value)));
569
1.36k
    }
570
571
3.13k
    void AddBooleanItem(llvm::StringRef key, bool value) {
572
3.13k
      AddItem(key, std::make_shared<Boolean>(value));
573
3.13k
    }
574
575
    void Serialize(llvm::json::OStream &s) const override;
576
577
    void GetDescription(lldb_private::Stream &s) const override;
578
579
  protected:
580
    typedef std::map<ConstString, ObjectSP> collection;
581
    collection m_dict;
582
  };
583
584
  class Null : public Object {
585
  public:
586
25
    Null() : Object(lldb::eStructuredDataTypeNull) {}
587
588
25
    ~Null() override = default;
589
590
0
    bool IsValid() const override { return false; }
591
592
    void Serialize(llvm::json::OStream &s) const override;
593
594
    void GetDescription(lldb_private::Stream &s) const override;
595
  };
596
597
  class Generic : public Object {
598
  public:
599
    explicit Generic(void *object = nullptr)
600
253
        : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {}
601
602
0
    void SetValue(void *value) { m_object = value; }
603
604
3.84k
    void *GetValue() const { return m_object; }
605
606
0
    bool IsValid() const override { return m_object != nullptr; }
607
608
    void Serialize(llvm::json::OStream &s) const override;
609
610
    void GetDescription(lldb_private::Stream &s) const override;
611
612
  private:
613
    void *m_object;
614
  };
615
616
  static ObjectSP ParseJSON(llvm::StringRef json_text);
617
  static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
618
  static bool IsRecordType(const ObjectSP object_sp);
619
};
620
621
} // namespace lldb_private
622
623
#endif // LLDB_UTILITY_STRUCTUREDDATA_H