Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/JSON.h
Line
Count
Source (jump to first uncovered line)
1
//===--- JSON.h - JSON values, parsing and serialization -------*- 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
/// \file
10
/// This file supports working with JSON data.
11
///
12
/// It comprises:
13
///
14
/// - classes which hold dynamically-typed parsed JSON structures
15
///   These are value types that can be composed, inspected, and modified.
16
///   See json::Value, and the related types json::Object and json::Array.
17
///
18
/// - functions to parse JSON text into Values, and to serialize Values to text.
19
///   See parse(), operator<<, and format_provider.
20
///
21
/// - a convention and helpers for mapping between json::Value and user-defined
22
///   types. See fromJSON(), ObjectMapper, and the class comment on Value.
23
///
24
/// - an output API json::OStream which can emit JSON without materializing
25
///   all structures as json::Value.
26
///
27
/// Typically, JSON data would be read from an external source, parsed into
28
/// a Value, and then converted into some native data structure before doing
29
/// real work on it. (And vice versa when writing).
30
///
31
/// Other serialization mechanisms you may consider:
32
///
33
/// - YAML is also text-based, and more human-readable than JSON. It's a more
34
///   complex format and data model, and YAML parsers aren't ubiquitous.
35
///   YAMLParser.h is a streaming parser suitable for parsing large documents
36
///   (including JSON, as YAML is a superset). It can be awkward to use
37
///   directly. YAML I/O (YAMLTraits.h) provides data mapping that is more
38
///   declarative than the toJSON/fromJSON conventions here.
39
///
40
/// - LLVM bitstream is a space- and CPU- efficient binary format. Typically it
41
///   encodes LLVM IR ("bitcode"), but it can be a container for other data.
42
///   Low-level reader/writer libraries are in Bitstream/Bitstream*.h
43
///
44
//===---------------------------------------------------------------------===//
45
46
#ifndef LLVM_SUPPORT_JSON_H
47
#define LLVM_SUPPORT_JSON_H
48
49
#include "llvm/ADT/DenseMap.h"
50
#include "llvm/ADT/SmallVector.h"
51
#include "llvm/ADT/StringRef.h"
52
#include "llvm/Support/Error.h"
53
#include "llvm/Support/FormatVariadic.h"
54
#include "llvm/Support/raw_ostream.h"
55
#include <map>
56
57
namespace llvm {
58
namespace json {
59
60
// === String encodings ===
61
//
62
// JSON strings are character sequences (not byte sequences like std::string).
63
// We need to know the encoding, and for simplicity only support UTF-8.
64
//
65
//   - When parsing, invalid UTF-8 is a syntax error like any other
66
//
67
//   - When creating Values from strings, callers must ensure they are UTF-8.
68
//        with asserts on, invalid UTF-8 will crash the program
69
//        with asserts off, we'll substitute the replacement character (U+FFFD)
70
//     Callers can use json::isUTF8() and json::fixUTF8() for validation.
71
//
72
//   - When retrieving strings from Values (e.g. asString()), the result will
73
//     always be valid UTF-8.
74
75
/// Returns true if \p S is valid UTF-8, which is required for use as JSON.
76
/// If it returns false, \p Offset is set to a byte offset near the first error.
77
bool isUTF8(llvm::StringRef S, size_t *ErrOffset = nullptr);
78
/// Replaces invalid UTF-8 sequences in \p S with the replacement character
79
/// (U+FFFD). The returned string is valid UTF-8.
80
/// This is much slower than isUTF8, so test that first.
81
std::string fixUTF8(llvm::StringRef S);
82
83
class Array;
84
class ObjectKey;
85
class Value;
86
template <typename T> Value toJSON(const llvm::Optional<T> &Opt);
87
88
/// An Object is a JSON object, which maps strings to heterogenous JSON values.
89
/// It simulates DenseMap<ObjectKey, Value>. ObjectKey is a maybe-owned string.
90
class Object {
91
  using Storage = DenseMap<ObjectKey, Value, llvm::DenseMapInfo<StringRef>>;
92
  Storage M;
93
94
public:
95
  using key_type = ObjectKey;
96
  using mapped_type = Value;
97
  using value_type = Storage::value_type;
98
  using iterator = Storage::iterator;
99
  using const_iterator = Storage::const_iterator;
100
101
29.8k
  Object() = default;
102
  // KV is a trivial key-value struct for list-initialization.
103
  // (using std::pair forces extra copies).
104
  struct KV;
105
  explicit Object(std::initializer_list<KV> Properties);
106
107
0
  iterator begin() { return M.begin(); }
108
3.48k
  const_iterator begin() const { return M.begin(); }
109
5
  iterator end() { return M.end(); }
110
10.7k
  const_iterator end() const { return M.end(); }
111
112
0
  bool empty() const { return M.empty(); }
113
12
  size_t size() const { return M.size(); }
114
115
0
  void clear() { M.clear(); }
116
  std::pair<iterator, bool> insert(KV E);
117
  template <typename... Ts>
118
3.56k
  std::pair<iterator, bool> try_emplace(const ObjectKey &K, Ts &&... Args) {
119
3.56k
    return M.try_emplace(K, std::forward<Ts>(Args)...);
120
3.56k
  }
121
  template <typename... Ts>
122
151k
  std::pair<iterator, bool> try_emplace(ObjectKey &&K, Ts &&... Args) {
123
151k
    return M.try_emplace(std::move(K), std::forward<Ts>(Args)...);
124
151k
  }
std::__1::pair<llvm::DenseMapIterator<llvm::json::ObjectKey, llvm::json::Value, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::json::ObjectKey, llvm::json::Value>, false>, bool> llvm::json::Object::try_emplace<std::nullptr_t>(llvm::json::ObjectKey&&, std::nullptr_t&&)
Line
Count
Source
122
151k
  std::pair<iterator, bool> try_emplace(ObjectKey &&K, Ts &&... Args) {
123
151k
    return M.try_emplace(std::move(K), std::forward<Ts>(Args)...);
124
151k
  }
std::__1::pair<llvm::DenseMapIterator<llvm::json::ObjectKey, llvm::json::Value, llvm::DenseMapInfo<llvm::StringRef>, llvm::detail::DenseMapPair<llvm::json::ObjectKey, llvm::json::Value>, false>, bool> llvm::json::Object::try_emplace<llvm::json::Value>(llvm::json::ObjectKey&&, llvm::json::Value&&)
Line
Count
Source
122
10
  std::pair<iterator, bool> try_emplace(ObjectKey &&K, Ts &&... Args) {
123
10
    return M.try_emplace(std::move(K), std::forward<Ts>(Args)...);
124
10
  }
125
126
5
  iterator find(StringRef K) { return M.find_as(K); }
127
7.22k
  const_iterator find(StringRef K) const { return M.find_as(K); }
128
  // operator[] acts as if Value was default-constructible as null.
129
  Value &operator[](const ObjectKey &K);
130
  Value &operator[](ObjectKey &&K);
131
  // Look up a property, returning nullptr if it doesn't exist.
132
  Value *get(StringRef K);
133
  const Value *get(StringRef K) const;
134
  // Typed accessors return None/nullptr if
135
  //   - the property doesn't exist
136
  //   - or it has the wrong type
137
  llvm::Optional<std::nullptr_t> getNull(StringRef K) const;
138
  llvm::Optional<bool> getBoolean(StringRef K) const;
139
  llvm::Optional<double> getNumber(StringRef K) const;
140
  llvm::Optional<int64_t> getInteger(StringRef K) const;
141
  llvm::Optional<llvm::StringRef> getString(StringRef K) const;
142
  const json::Object *getObject(StringRef K) const;
143
  json::Object *getObject(StringRef K);
144
  const json::Array *getArray(StringRef K) const;
145
  json::Array *getArray(StringRef K);
146
};
147
bool operator==(const Object &LHS, const Object &RHS);
148
0
inline bool operator!=(const Object &LHS, const Object &RHS) {
149
0
  return !(LHS == RHS);
150
0
}
151
152
/// An Array is a JSON array, which contains heterogeneous JSON values.
153
/// It simulates std::vector<Value>.
154
class Array {
155
  std::vector<Value> V;
156
157
public:
158
  using value_type = Value;
159
  using iterator = std::vector<Value>::iterator;
160
  using const_iterator = std::vector<Value>::const_iterator;
161
162
20.7k
  Array() = default;
163
  explicit Array(std::initializer_list<Value> Elements);
164
  template <typename Collection> explicit Array(const Collection &C) {
165
    for (const auto &V : C)
166
      emplace_back(V);
167
  }
168
169
  Value &operator[](size_t I) { return V[I]; }
170
808
  const Value &operator[](size_t I) const { return V[I]; }
171
0
  Value &front() { return V.front(); }
172
0
  const Value &front() const { return V.front(); }
173
114k
  Value &back() { return V.back(); }
174
0
  const Value &back() const { return V.back(); }
175
0
  Value *data() { return V.data(); }
176
0
  const Value *data() const { return V.data(); }
177
178
39
  iterator begin() { return V.begin(); }
179
650
  const_iterator begin() const { return V.begin(); }
180
39
  iterator end() { return V.end(); }
181
650
  const_iterator end() const { return V.end(); }
182
183
313
  bool empty() const { return V.empty(); }
184
667
  size_t size() const { return V.size(); }
185
0
  void reserve(size_t S) { V.reserve(S); }
186
187
0
  void clear() { V.clear(); }
188
0
  void push_back(const Value &E) { V.push_back(E); }
189
547
  void push_back(Value &&E) { V.push_back(std::move(E)); }
190
114k
  template <typename... Args> void emplace_back(Args &&... A) {
191
114k
    V.emplace_back(std::forward<Args>(A)...);
192
114k
  }
193
0
  void pop_back() { V.pop_back(); }
194
  // FIXME: insert() takes const_iterator since C++11, old libstdc++ disagrees.
195
0
  iterator insert(iterator P, const Value &E) { return V.insert(P, E); }
196
0
  iterator insert(iterator P, Value &&E) {
197
0
    return V.insert(P, std::move(E));
198
0
  }
199
  template <typename It> iterator insert(iterator P, It A, It Z) {
200
    return V.insert(P, A, Z);
201
  }
202
  template <typename... Args> iterator emplace(const_iterator P, Args &&... A) {
203
    return V.emplace(P, std::forward<Args>(A)...);
204
  }
205
206
7
  friend bool operator==(const Array &L, const Array &R) { return L.V == R.V; }
207
};
208
0
inline bool operator!=(const Array &L, const Array &R) { return !(L == R); }
209
210
/// A Value is an JSON value of unknown type.
211
/// They can be copied, but should generally be moved.
212
///
213
/// === Composing values ===
214
///
215
/// You can implicitly construct Values from:
216
///   - strings: std::string, SmallString, formatv, StringRef, char*
217
///              (char*, and StringRef are references, not copies!)
218
///   - numbers
219
///   - booleans
220
///   - null: nullptr
221
///   - arrays: {"foo", 42.0, false}
222
///   - serializable things: types with toJSON(const T&)->Value, found by ADL
223
///
224
/// They can also be constructed from object/array helpers:
225
///   - json::Object is a type like map<ObjectKey, Value>
226
///   - json::Array is a type like vector<Value>
227
/// These can be list-initialized, or used to build up collections in a loop.
228
/// json::ary(Collection) converts all items in a collection to Values.
229
///
230
/// === Inspecting values ===
231
///
232
/// Each Value is one of the JSON kinds:
233
///   null    (nullptr_t)
234
///   boolean (bool)
235
///   number  (double or int64)
236
///   string  (StringRef)
237
///   array   (json::Array)
238
///   object  (json::Object)
239
///
240
/// The kind can be queried directly, or implicitly via the typed accessors:
241
///   if (Optional<StringRef> S = E.getAsString()
242
///     assert(E.kind() == Value::String);
243
///
244
/// Array and Object also have typed indexing accessors for easy traversal:
245
///   Expected<Value> E = parse(R"( {"options": {"font": "sans-serif"}} )");
246
///   if (Object* O = E->getAsObject())
247
///     if (Object* Opts = O->getObject("options"))
248
///       if (Optional<StringRef> Font = Opts->getString("font"))
249
///         assert(Opts->at("font").kind() == Value::String);
250
///
251
/// === Converting JSON values to C++ types ===
252
///
253
/// The convention is to have a deserializer function findable via ADL:
254
///     fromJSON(const json::Value&, T&)->bool
255
/// Deserializers are provided for:
256
///   - bool
257
///   - int and int64_t
258
///   - double
259
///   - std::string
260
///   - vector<T>, where T is deserializable
261
///   - map<string, T>, where T is deserializable
262
///   - Optional<T>, where T is deserializable
263
/// ObjectMapper can help writing fromJSON() functions for object types.
264
///
265
/// For conversion in the other direction, the serializer function is:
266
///    toJSON(const T&) -> json::Value
267
/// If this exists, then it also allows constructing Value from T, and can
268
/// be used to serialize vector<T>, map<string, T>, and Optional<T>.
269
///
270
/// === Serialization ===
271
///
272
/// Values can be serialized to JSON:
273
///   1) raw_ostream << Value                    // Basic formatting.
274
///   2) raw_ostream << formatv("{0}", Value)    // Basic formatting.
275
///   3) raw_ostream << formatv("{0:2}", Value)  // Pretty-print with indent 2.
276
///
277
/// And parsed:
278
///   Expected<Value> E = json::parse("[1, 2, null]");
279
///   assert(E && E->kind() == Value::Array);
280
class Value {
281
public:
282
  enum Kind {
283
    Null,
284
    Boolean,
285
    /// Number values can store both int64s and doubles at full precision,
286
    /// depending on what they were constructed/parsed from.
287
    Number,
288
    String,
289
    Array,
290
    Object,
291
  };
292
293
  // It would be nice to have Value() be null. But that would make {} null too.
294
179k
  Value(const Value &M) { copyFrom(M); }
295
5.45k
  Value(Value &&M) { moveFrom(std::move(M)); }
296
  Value(std::initializer_list<Value> Elements);
297
20.9k
  Value(json::Array &&Elements) : Type(T_Array) {
298
20.9k
    create<json::Array>(std::move(Elements));
299
20.9k
  }
300
  template <typename Elt>
301
  Value(const std::vector<Elt> &C) : Value(json::Array(C)) {}
302
32.7k
  Value(json::Object &&Properties) : Type(T_Object) {
303
32.7k
    create<json::Object>(std::move(Properties));
304
32.7k
  }
305
  template <typename Elt>
306
  Value(const std::map<std::string, Elt> &C) : Value(json::Object(C)) {}
307
  // Strings: types with value semantics. Must be valid UTF-8.
308
222k
  Value(std::string V) : Type(T_String) {
309
222k
    if (LLVM_UNLIKELY(!isUTF8(V))) {
310
0
      assert(false && "Invalid UTF-8 in value used as JSON");
311
0
      V = fixUTF8(std::move(V));
312
0
    }
313
222k
    create<std::string>(std::move(V));
314
222k
  }
315
  Value(const llvm::SmallVectorImpl<char> &V)
316
6
      : Value(std::string(V.begin(), V.end())) {}
Unexecuted instantiation: llvm::json::Value::Value(llvm::SmallVectorImpl<char> const&)
llvm::json::Value::Value(llvm::SmallVectorImpl<char> const&)
Line
Count
Source
316
6
      : Value(std::string(V.begin(), V.end())) {}
317
0
  Value(const llvm::formatv_object_base &V) : Value(V.str()) {}
318
  // Strings: types with reference semantics. Must be valid UTF-8.
319
3.55k
  Value(StringRef V) : Type(T_StringRef) {
320
3.55k
    create<llvm::StringRef>(V);
321
3.55k
    if (LLVM_UNLIKELY(!isUTF8(V))) {
322
1
      assert(false && "Invalid UTF-8 in value used as JSON");
323
1
      *this = Value(fixUTF8(V));
324
1
    }
325
3.55k
  }
326
3.25k
  Value(const char *V) : Value(StringRef(V)) {}
Unexecuted instantiation: llvm::json::Value::Value(char const*)
llvm::json::Value::Value(char const*)
Line
Count
Source
326
3.25k
  Value(const char *V) : Value(StringRef(V)) {}
327
274k
  Value(std::nullptr_t) : Type(T_Null) {}
328
  // Boolean (disallow implicit conversions).
329
  // (The last template parameter is a dummy to keep templates distinct.)
330
  template <
331
      typename T,
332
      typename = typename std::enable_if<std::is_same<T, bool>::value>::type,
333
      bool = false>
334
3.69k
  Value(T B) : Type(T_Boolean) {
335
3.69k
    create<bool>(B);
336
3.69k
  }
337
  // Integers (except boolean). Must be non-narrowing convertible to int64_t.
338
  template <
339
      typename T,
340
      typename = typename std::enable_if<std::is_integral<T>::value>::type,
341
      typename = typename std::enable_if<!std::is_same<T, bool>::value>::type>
342
15.1k
  Value(T I) : Type(T_Integer) {
343
15.1k
    create<int64_t>(int64_t{I});
344
15.1k
  }
llvm::json::Value::Value<long long, void, void>(long long)
Line
Count
Source
342
1.14k
  Value(T I) : Type(T_Integer) {
343
1.14k
    create<int64_t>(int64_t{I});
344
1.14k
  }
llvm::json::Value::Value<int, void, void>(int)
Line
Count
Source
342
192
  Value(T I) : Type(T_Integer) {
343
192
    create<int64_t>(int64_t{I});
344
192
  }
llvm::json::Value::Value<unsigned int, void, void>(unsigned int)
Line
Count
Source
342
13.8k
  Value(T I) : Type(T_Integer) {
343
13.8k
    create<int64_t>(int64_t{I});
344
13.8k
  }
345
  // Floating point. Must be non-narrowing convertible to double.
346
  template <typename T,
347
            typename =
348
                typename std::enable_if<std::is_floating_point<T>::value>::type,
349
            double * = nullptr>
350
157
  Value(T D) : Type(T_Double) {
351
157
    create<double>(double{D});
352
157
  }
353
  // Serializable types: with a toJSON(const T&)->Value function, found by ADL.
354
  template <typename T,
355
            typename = typename std::enable_if<std::is_same<
356
                Value, decltype(toJSON(*(const T *)nullptr))>::value>,
357
            Value * = nullptr>
358
  Value(const T &V) : Value(toJSON(V)) {}
359
360
0
  Value &operator=(const Value &M) {
361
0
    destroy();
362
0
    copyFrom(M);
363
0
    return *this;
364
0
  }
365
267k
  Value &operator=(Value &&M) {
366
267k
    destroy();
367
267k
    moveFrom(std::move(M));
368
267k
    return *this;
369
267k
  }
370
757k
  ~Value() { destroy(); }
371
372
35.1k
  Kind kind() const {
373
35.1k
    switch (Type) {
374
35.1k
    case T_Null:
375
47
      return Null;
376
35.1k
    case T_Boolean:
377
3.69k
      return Boolean;
378
35.1k
    case T_Double:
379
15.3k
    case T_Integer:
380
15.3k
      return Number;
381
15.3k
    case T_String:
382
11.8k
    case T_StringRef:
383
11.8k
      return String;
384
11.8k
    case T_Object:
385
3.49k
      return Object;
386
11.8k
    case T_Array:
387
668
      return Array;
388
0
    }
389
0
    llvm_unreachable("Unknown kind");
390
0
  }
391
392
  // Typed accessors return None/nullptr if the Value is not of this type.
393
5
  llvm::Optional<std::nullptr_t> getAsNull() const {
394
5
    if (LLVM_LIKELY(Type == T_Null))
395
5
      
return nullptr3
;
396
2
    return llvm::None;
397
2
  }
398
3.70k
  llvm::Optional<bool> getAsBoolean() const {
399
3.70k
    if (LLVM_LIKELY(Type == T_Boolean))
400
3.70k
      
return as<bool>()3.69k
;
401
1
    return llvm::None;
402
1
  }
403
172
  llvm::Optional<double> getAsNumber() const {
404
172
    if (LLVM_LIKELY(Type == T_Double))
405
172
      
return as<double>()170
;
406
2
    if (LLVM_LIKELY(Type == T_Integer))
407
2
      return as<int64_t>();
408
0
    return llvm::None;
409
0
  }
410
  // Succeeds if the Value is a Number, and exactly representable as int64_t.
411
15.1k
  llvm::Optional<int64_t> getAsInteger() const {
412
15.1k
    if (LLVM_LIKELY(Type == T_Integer))
413
15.1k
      
return as<int64_t>()15.1k
;
414
4
    if (LLVM_LIKELY(Type == T_Double)) {
415
4
      double D = as<double>();
416
4
      if (LLVM_LIKELY(std::modf(D, &D) == 0.0 &&
417
4
                      D >= double(std::numeric_limits<int64_t>::min()) &&
418
4
                      D <= double(std::numeric_limits<int64_t>::max())))
419
4
        
return D1
;
420
3
    }
421
3
    return llvm::None;
422
3
  }
423
17.3k
  llvm::Optional<llvm::StringRef> getAsString() const {
424
17.3k
    if (Type == T_String)
425
13.8k
      return llvm::StringRef(as<std::string>());
426
3.56k
    if (LLVM_LIKELY(Type == T_StringRef))
427
3.56k
      
return as<llvm::StringRef>()3.56k
;
428
3
    return llvm::None;
429
3
  }
430
4.35k
  const json::Object *getAsObject() const {
431
4.35k
    return LLVM_LIKELY(Type == T_Object) ? 
&as<json::Object>()4.35k
:
nullptr1
;
432
4.35k
  }
433
34.1k
  json::Object *getAsObject() {
434
34.1k
    return LLVM_LIKELY(Type == T_Object) ? 
&as<json::Object>()34.1k
:
nullptr6
;
435
34.1k
  }
436
1.19k
  const json::Array *getAsArray() const {
437
1.19k
    return LLVM_LIKELY(Type == T_Array) ? &as<json::Array>() : 
nullptr0
;
438
1.19k
  }
439
20.3k
  json::Array *getAsArray() {
440
20.3k
    return LLVM_LIKELY(Type == T_Array) ? &as<json::Array>() : 
nullptr0
;
441
20.3k
  }
442
443
private:
444
  void destroy();
445
  void copyFrom(const Value &M);
446
  // We allow moving from *const* Values, by marking all members as mutable!
447
  // This hack is needed to support initializer-list syntax efficiently.
448
  // (std::initializer_list<T> is a container of const T).
449
  void moveFrom(const Value &&M);
450
  friend class Array;
451
  friend class Object;
452
453
746k
  template <typename T, typename... U> void create(U &&... V) {
454
746k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
746k
  }
void llvm::json::Value::create<bool, bool&>(bool&&&)
Line
Count
Source
453
3.69k
  template <typename T, typename... U> void create(U &&... V) {
454
3.69k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
3.69k
  }
void llvm::json::Value::create<long long, long long>(long long&&)
Line
Count
Source
453
15.1k
  template <typename T, typename... U> void create(U &&... V) {
454
15.1k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
15.1k
  }
void llvm::json::Value::create<double, double>(double&&)
Line
Count
Source
453
157
  template <typename T, typename... U> void create(U &&... V) {
454
157
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
157
  }
void llvm::json::Value::create<llvm::json::Array, llvm::json::Array>(llvm::json::Array&&)
Line
Count
Source
453
41.8k
  template <typename T, typename... U> void create(U &&... V) {
454
41.8k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
41.8k
  }
void llvm::json::Value::create<llvm::json::Object, llvm::json::Object>(llvm::json::Object&&)
Line
Count
Source
453
68.0k
  template <typename T, typename... U> void create(U &&... V) {
454
68.0k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
68.0k
  }
void llvm::json::Value::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Line
Count
Source
453
440k
  template <typename T, typename... U> void create(U &&... V) {
454
440k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
440k
  }
void llvm::json::Value::create<llvm::StringRef, llvm::StringRef&>(llvm::StringRef&&&)
Line
Count
Source
453
3.66k
  template <typename T, typename... U> void create(U &&... V) {
454
3.66k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
3.66k
  }
void llvm::json::Value::create<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&&)
Line
Count
Source
453
171k
  template <typename T, typename... U> void create(U &&... V) {
454
171k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
171k
  }
void llvm::json::Value::create<llvm::json::Object, llvm::json::Object&>(llvm::json::Object&&&)
Line
Count
Source
453
775
  template <typename T, typename... U> void create(U &&... V) {
454
775
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
775
  }
void llvm::json::Value::create<llvm::json::Array, llvm::json::Array&>(llvm::json::Array&&&)
Line
Count
Source
453
1.05k
  template <typename T, typename... U> void create(U &&... V) {
454
1.05k
    new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
455
1.05k
  }
456
997k
  template <typename T> T &as() const {
457
997k
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
997k
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
997k
    void *Storage = static_cast<void *>(Union.buffer);
460
997k
    return *static_cast<T *>(Storage);
461
997k
  }
bool& llvm::json::Value::as<bool>() const
Line
Count
Source
456
3.69k
  template <typename T> T &as() const {
457
3.69k
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
3.69k
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
3.69k
    void *Storage = static_cast<void *>(Union.buffer);
460
3.69k
    return *static_cast<T *>(Storage);
461
3.69k
  }
double& llvm::json::Value::as<double>() const
Line
Count
Source
456
174
  template <typename T> T &as() const {
457
174
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
174
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
174
    void *Storage = static_cast<void *>(Union.buffer);
460
174
    return *static_cast<T *>(Storage);
461
174
  }
long long& llvm::json::Value::as<long long>() const
Line
Count
Source
456
15.1k
  template <typename T> T &as() const {
457
15.1k
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
15.1k
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
15.1k
    void *Storage = static_cast<void *>(Union.buffer);
460
15.1k
    return *static_cast<T *>(Storage);
461
15.1k
  }
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >& llvm::json::Value::as<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Line
Count
Source
456
797k
  template <typename T> T &as() const {
457
797k
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
797k
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
797k
    void *Storage = static_cast<void *>(Union.buffer);
460
797k
    return *static_cast<T *>(Storage);
461
797k
  }
llvm::StringRef& llvm::json::Value::as<llvm::StringRef>() const
Line
Count
Source
456
7.33k
  template <typename T> T &as() const {
457
7.33k
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
7.33k
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
7.33k
    void *Storage = static_cast<void *>(Union.buffer);
460
7.33k
    return *static_cast<T *>(Storage);
461
7.33k
  }
llvm::json::Object& llvm::json::Value::as<llvm::json::Object>() const
Line
Count
Source
456
108k
  template <typename T> T &as() const {
457
108k
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
108k
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
108k
    void *Storage = static_cast<void *>(Union.buffer);
460
108k
    return *static_cast<T *>(Storage);
461
108k
  }
llvm::json::Array& llvm::json::Value::as<llvm::json::Array>() const
Line
Count
Source
456
65.5k
  template <typename T> T &as() const {
457
65.5k
    // Using this two-step static_cast via void * instead of reinterpret_cast
458
65.5k
    // silences a -Wstrict-aliasing false positive from GCC6 and earlier.
459
65.5k
    void *Storage = static_cast<void *>(Union.buffer);
460
65.5k
    return *static_cast<T *>(Storage);
461
65.5k
  }
462
463
  friend class OStream;
464
465
  enum ValueType : char {
466
    T_Null,
467
    T_Boolean,
468
    T_Double,
469
    T_Integer,
470
    T_StringRef,
471
    T_String,
472
    T_Object,
473
    T_Array,
474
  };
475
  // All members mutable, see moveFrom().
476
  mutable ValueType Type;
477
  mutable llvm::AlignedCharArrayUnion<bool, double, int64_t, llvm::StringRef,
478
                                      std::string, json::Array, json::Object>
479
      Union;
480
  friend bool operator==(const Value &, const Value &);
481
};
482
483
bool operator==(const Value &, const Value &);
484
6
inline bool operator!=(const Value &L, const Value &R) { return !(L == R); }
485
486
/// ObjectKey is a used to capture keys in Object. Like Value but:
487
///   - only strings are allowed
488
///   - it's optimized for the string literal case (Owned == nullptr)
489
/// Like Value, strings must be UTF-8. See isUTF8 documentation for details.
490
class ObjectKey {
491
public:
492
7.72k
  ObjectKey(const char *S) : ObjectKey(StringRef(S)) {}
Unexecuted instantiation: llvm::json::ObjectKey::ObjectKey(char const*)
llvm::json::ObjectKey::ObjectKey(char const*)
Line
Count
Source
492
7.72k
  ObjectKey(const char *S) : ObjectKey(StringRef(S)) {}
493
146k
  ObjectKey(std::string S) : Owned(new std::string(std::move(S))) {
494
146k
    if (LLVM_UNLIKELY(!isUTF8(*Owned))) {
495
0
      assert(false && "Invalid UTF-8 in value used as JSON");
496
0
      *Owned = fixUTF8(std::move(*Owned));
497
0
    }
498
146k
    Data = *Owned;
499
146k
  }
500
659k
  ObjectKey(llvm::StringRef S) : Data(S) {
501
659k
    if (LLVM_UNLIKELY(!isUTF8(Data))) {
502
1
      assert(false && "Invalid UTF-8 in value used as JSON");
503
1
      *this = ObjectKey(fixUTF8(S));
504
1
    }
505
659k
  }
506
  ObjectKey(const llvm::SmallVectorImpl<char> &V)
507
0
      : ObjectKey(std::string(V.begin(), V.end())) {}
508
0
  ObjectKey(const llvm::formatv_object_base &V) : ObjectKey(V.str()) {}
509
510
2.14M
  ObjectKey(const ObjectKey &C) { *this = C; }
511
0
  ObjectKey(ObjectKey &&C) : ObjectKey(static_cast<const ObjectKey &&>(C)) {}
512
2.14M
  ObjectKey &operator=(const ObjectKey &C) {
513
2.14M
    if (C.Owned) {
514
1.22k
      Owned.reset(new std::string(*C.Owned));
515
1.22k
      Data = *Owned;
516
2.14M
    } else {
517
2.14M
      Data = C.Data;
518
2.14M
    }
519
2.14M
    return *this;
520
2.14M
  }
521
151k
  ObjectKey &operator=(ObjectKey &&) = default;
522
523
6.33M
  operator llvm::StringRef() const { return Data; }
524
0
  std::string str() const { return Data.str(); }
525
526
private:
527
  // FIXME: this is unneccesarily large (3 pointers). Pointer + length + owned
528
  // could be 2 pointers at most.
529
  std::unique_ptr<std::string> Owned;
530
  llvm::StringRef Data;
531
};
532
533
0
inline bool operator==(const ObjectKey &L, const ObjectKey &R) {
534
0
  return llvm::StringRef(L) == llvm::StringRef(R);
535
0
}
536
0
inline bool operator!=(const ObjectKey &L, const ObjectKey &R) {
537
0
  return !(L == R);
538
0
}
539
9.47k
inline bool operator<(const ObjectKey &L, const ObjectKey &R) {
540
9.47k
  return StringRef(L) < StringRef(R);
541
9.47k
}
542
543
struct Object::KV {
544
  ObjectKey K;
545
  Value V;
546
};
547
548
2.88k
inline Object::Object(std::initializer_list<KV> Properties) {
549
3.56k
  for (const auto &P : Properties) {
550
3.56k
    auto R = try_emplace(P.K, nullptr);
551
3.56k
    if (R.second)
552
3.56k
      R.first->getSecond().moveFrom(std::move(P.V));
553
3.56k
  }
554
2.88k
}
555
10
inline std::pair<Object::iterator, bool> Object::insert(KV E) {
556
10
  return try_emplace(std::move(E.K), std::move(E.V));
557
10
}
558
559
// Standard deserializers are provided for primitive types.
560
// See comments on Value.
561
inline bool fromJSON(const Value &E, std::string &Out) {
562
  if (auto S = E.getAsString()) {
563
    Out = *S;
564
    return true;
565
  }
566
  return false;
567
}
568
inline bool fromJSON(const Value &E, int &Out) {
569
  if (auto S = E.getAsInteger()) {
570
    Out = *S;
571
    return true;
572
  }
573
  return false;
574
}
575
0
inline bool fromJSON(const Value &E, int64_t &Out) {
576
0
  if (auto S = E.getAsInteger()) {
577
0
    Out = *S;
578
0
    return true;
579
0
  }
580
0
  return false;
581
0
}
582
0
inline bool fromJSON(const Value &E, double &Out) {
583
0
  if (auto S = E.getAsNumber()) {
584
0
    Out = *S;
585
0
    return true;
586
0
  }
587
0
  return false;
588
0
}
589
inline bool fromJSON(const Value &E, bool &Out) {
590
  if (auto S = E.getAsBoolean()) {
591
    Out = *S;
592
    return true;
593
  }
594
  return false;
595
}
596
template <typename T> bool fromJSON(const Value &E, llvm::Optional<T> &Out) {
597
  if (E.getAsNull()) {
598
    Out = llvm::None;
599
    return true;
600
  }
601
  T Result;
602
  if (!fromJSON(E, Result))
603
    return false;
604
  Out = std::move(Result);
605
  return true;
606
}
607
template <typename T> bool fromJSON(const Value &E, std::vector<T> &Out) {
608
  if (auto *A = E.getAsArray()) {
609
    Out.clear();
610
    Out.resize(A->size());
611
    for (size_t I = 0; I < A->size(); ++I)
612
      if (!fromJSON((*A)[I], Out[I]))
613
        return false;
614
    return true;
615
  }
616
  return false;
617
}
618
template <typename T>
619
bool fromJSON(const Value &E, std::map<std::string, T> &Out) {
620
  if (auto *O = E.getAsObject()) {
621
    Out.clear();
622
    for (const auto &KV : *O)
623
      if (!fromJSON(KV.second, Out[llvm::StringRef(KV.first)]))
624
        return false;
625
    return true;
626
  }
627
  return false;
628
}
629
630
// Allow serialization of Optional<T> for supported T.
631
template <typename T> Value toJSON(const llvm::Optional<T> &Opt) {
632
  return Opt ? Value(*Opt) : Value(nullptr);
633
}
634
635
/// Helper for mapping JSON objects onto protocol structs.
636
///
637
/// Example:
638
/// \code
639
///   bool fromJSON(const Value &E, MyStruct &R) {
640
///     ObjectMapper O(E);
641
///     if (!O || !O.map("mandatory_field", R.MandatoryField))
642
///       return false;
643
///     O.map("optional_field", R.OptionalField);
644
///     return true;
645
///   }
646
/// \endcode
647
class ObjectMapper {
648
public:
649
  ObjectMapper(const Value &E) : O(E.getAsObject()) {}
650
651
  /// True if the expression is an object.
652
  /// Must be checked before calling map().
653
  operator bool() { return O; }
654
655
  /// Maps a property to a field, if it exists.
656
  template <typename T> bool map(StringRef Prop, T &Out) {
657
    assert(*this && "Must check this is an object before calling map()");
658
    if (const Value *E = O->get(Prop))
659
      return fromJSON(*E, Out);
660
    return false;
661
  }
662
663
  /// Maps a property to a field, if it exists.
664
  /// (Optional requires special handling, because missing keys are OK).
665
  template <typename T> bool map(StringRef Prop, llvm::Optional<T> &Out) {
666
    assert(*this && "Must check this is an object before calling map()");
667
    if (const Value *E = O->get(Prop))
668
      return fromJSON(*E, Out);
669
    Out = llvm::None;
670
    return true;
671
  }
672
673
private:
674
  const Object *O;
675
};
676
677
/// Parses the provided JSON source, or returns a ParseError.
678
/// The returned Value is self-contained and owns its strings (they do not refer
679
/// to the original source).
680
llvm::Expected<Value> parse(llvm::StringRef JSON);
681
682
class ParseError : public llvm::ErrorInfo<ParseError> {
683
  const char *Msg;
684
  unsigned Line, Column, Offset;
685
686
public:
687
  static char ID;
688
  ParseError(const char *Msg, unsigned Line, unsigned Column, unsigned Offset)
689
17
      : Msg(Msg), Line(Line), Column(Column), Offset(Offset) {}
690
16
  void log(llvm::raw_ostream &OS) const override {
691
16
    OS << llvm::formatv("[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
692
16
  }
693
0
  std::error_code convertToErrorCode() const override {
694
0
    return llvm::inconvertibleErrorCode();
695
0
  }
696
};
697
698
/// json::OStream allows writing well-formed JSON without materializing
699
/// all structures as json::Value ahead of time.
700
/// It's faster, lower-level, and less safe than OS << json::Value.
701
///
702
/// Only one "top-level" object can be written to a stream.
703
/// Simplest usage involves passing lambdas (Blocks) to fill in containers:
704
///
705
///   json::OStream J(OS);
706
///   J.array([&]{
707
///     for (const Event &E : Events)
708
///       J.object([&] {
709
///         J.attribute("timestamp", int64_t(E.Time));
710
///         J.attributeArray("participants", [&] {
711
///           for (const Participant &P : E.Participants)
712
///             J.string(P.toString());
713
///         });
714
///       });
715
///   });
716
///
717
/// This would produce JSON like:
718
///
719
///   [
720
///     {
721
///       "timestamp": 19287398741,
722
///       "participants": [
723
///         "King Kong",
724
///         "Miley Cyrus",
725
///         "Cleopatra"
726
///       ]
727
///     },
728
///     ...
729
///   ]
730
///
731
/// The lower level begin/end methods (arrayBegin()) are more flexible but
732
/// care must be taken to pair them correctly:
733
///
734
///   json::OStream J(OS);
735
//    J.arrayBegin();
736
///   for (const Event &E : Events) {
737
///     J.objectBegin();
738
///     J.attribute("timestamp", int64_t(E.Time));
739
///     J.attributeBegin("participants");
740
///     for (const Participant &P : E.Participants)
741
///       J.value(P.toString());
742
///     J.attributeEnd();
743
///     J.objectEnd();
744
///   }
745
///   J.arrayEnd();
746
///
747
/// If the call sequence isn't valid JSON, asserts will fire in debug mode.
748
/// This can be mismatched begin()/end() pairs, trying to emit attributes inside
749
/// an array, and so on.
750
/// With asserts disabled, this is undefined behavior.
751
class OStream {
752
 public:
753
  using Block = llvm::function_ref<void()>;
754
  // If IndentSize is nonzero, output is pretty-printed.
755
  explicit OStream(llvm::raw_ostream &OS, unsigned IndentSize = 0)
756
196
      : OS(OS), IndentSize(IndentSize) {
757
196
    Stack.emplace_back();
758
196
  }
759
196
  ~OStream() {
760
196
    assert(Stack.size() == 1 && "Unmatched begin()/end()");
761
196
    assert(Stack.back().Ctx == Singleton);
762
196
    assert(Stack.back().HasValue && "Did not write top-level value");
763
196
  }
764
765
  /// Flushes the underlying ostream. OStream does not buffer internally.
766
0
  void flush() { OS.flush(); }
767
768
  // High level functions to output a value.
769
  // Valid at top-level (exactly once), in an attribute value (exactly once),
770
  // or in an array (any number of times).
771
772
  /// Emit a self-contained value (number, string, vector<string> etc).
773
  void value(const Value &V);
774
  /// Emit an array whose elements are emitted in the provided Block.
775
662
  void array(Block Contents) {
776
662
    arrayBegin();
777
662
    Contents();
778
662
    arrayEnd();
779
662
  }
780
  /// Emit an object whose elements are emitted in the provided Block.
781
11.7k
  void object(Block Contents) {
782
11.7k
    objectBegin();
783
11.7k
    Contents();
784
11.7k
    objectEnd();
785
11.7k
  }
786
787
  // High level functions to output object attributes.
788
  // Valid only within an object (any number of times).
789
790
  /// Emit an attribute whose value is self-contained (number, vector<int> etc).
791
31.6k
  void attribute(llvm::StringRef Key, const Value& Contents) {
792
31.6k
    attributeImpl(Key, [&] { value(Contents); });
793
31.6k
  }
794
  /// Emit an attribute whose value is an array with elements from the Block.
795
12
  void attributeArray(llvm::StringRef Key, Block Contents) {
796
12
    attributeImpl(Key, [&] { array(Contents); });
797
12
  }
798
  /// Emit an attribute whose value is an object with attributes from the Block.
799
8.18k
  void attributeObject(llvm::StringRef Key, Block Contents) {
800
8.18k
    attributeImpl(Key, [&] { object(Contents); });
801
8.18k
  }
802
803
  // Low-level begin/end functions to output arrays, objects, and attributes.
804
  // Must be correctly paired. Allowed contexts are as above.
805
806
  void arrayBegin();
807
  void arrayEnd();
808
  void objectBegin();
809
  void objectEnd();
810
  void attributeBegin(llvm::StringRef Key);
811
  void attributeEnd();
812
813
 private:
814
39.8k
  void attributeImpl(llvm::StringRef Key, Block Contents) {
815
39.8k
    attributeBegin(Key);
816
39.8k
    Contents();
817
39.8k
    attributeEnd();
818
39.8k
  }
819
820
  void valueBegin();
821
  void newline();
822
823
  enum Context {
824
    Singleton, // Top level, or object attribute.
825
    Array,
826
    Object,
827
  };
828
  struct State {
829
    Context Ctx = Singleton;
830
    bool HasValue = false;
831
  };
832
  llvm::SmallVector<State, 16> Stack; // Never empty.
833
  llvm::raw_ostream &OS;
834
  unsigned IndentSize;
835
  unsigned Indent = 0;
836
};
837
838
/// Serializes this Value to JSON, writing it to the provided stream.
839
/// The formatting is compact (no extra whitespace) and deterministic.
840
/// For pretty-printing, use the formatv() format_provider below.
841
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Value &V) {
842
  OStream(OS).value(V);
843
  return OS;
844
}
845
} // namespace json
846
847
/// Allow printing json::Value with formatv().
848
/// The default style is basic/compact formatting, like operator<<.
849
/// A format string like formatv("{0:2}", Value) pretty-prints with indent 2.
850
template <> struct format_provider<llvm::json::Value> {
851
  static void format(const llvm::json::Value &, raw_ostream &, StringRef);
852
};
853
} // namespace llvm
854
855
#endif