Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Support/JSON.cpp
Line
Count
Source (jump to first uncovered line)
1
//=== JSON.cpp - JSON value, 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
#include "llvm/Support/JSON.h"
10
#include "llvm/Support/ConvertUTF.h"
11
#include "llvm/Support/Format.h"
12
#include <cctype>
13
14
namespace llvm {
15
namespace json {
16
17
0
Value &Object::operator[](const ObjectKey &K) {
18
0
  return try_emplace(K, nullptr).first->getSecond();
19
0
}
20
151k
Value &Object::operator[](ObjectKey &&K) {
21
151k
  return try_emplace(std::move(K), nullptr).first->getSecond();
22
151k
}
23
5
Value *Object::get(StringRef K) {
24
5
  auto I = find(K);
25
5
  if (I == end())
26
1
    return nullptr;
27
4
  return &I->second;
28
4
}
29
7.21k
const Value *Object::get(StringRef K) const {
30
7.21k
  auto I = find(K);
31
7.21k
  if (I == end())
32
62
    return nullptr;
33
7.15k
  return &I->second;
34
7.15k
}
35
3
llvm::Optional<std::nullptr_t> Object::getNull(StringRef K) const {
36
3
  if (auto *V = get(K))
37
2
    return V->getAsNull();
38
1
  return llvm::None;
39
1
}
40
0
llvm::Optional<bool> Object::getBoolean(StringRef K) const {
41
0
  if (auto *V = get(K))
42
0
    return V->getAsBoolean();
43
0
  return llvm::None;
44
0
}
45
1
llvm::Optional<double> Object::getNumber(StringRef K) const {
46
1
  if (auto *V = get(K))
47
1
    return V->getAsNumber();
48
0
  return llvm::None;
49
0
}
50
1
llvm::Optional<int64_t> Object::getInteger(StringRef K) const {
51
1
  if (auto *V = get(K))
52
1
    return V->getAsInteger();
53
0
  return llvm::None;
54
0
}
55
5.50k
llvm::Optional<llvm::StringRef> Object::getString(StringRef K) const {
56
5.50k
  if (auto *V = get(K))
57
5.50k
    return V->getAsString();
58
0
  return llvm::None;
59
0
}
60
12
const json::Object *Object::getObject(StringRef K) const {
61
12
  if (auto *V = get(K))
62
12
    return V->getAsObject();
63
0
  return nullptr;
64
0
}
65
4
json::Object *Object::getObject(StringRef K) {
66
4
  if (auto *V = get(K))
67
3
    return V->getAsObject();
68
1
  return nullptr;
69
1
}
70
535
const json::Array *Object::getArray(StringRef K) const {
71
535
  if (auto *V = get(K))
72
535
    return V->getAsArray();
73
0
  return nullptr;
74
0
}
75
1
json::Array *Object::getArray(StringRef K) {
76
1
  if (auto *V = get(K))
77
1
    return V->getAsArray();
78
0
  return nullptr;
79
0
}
80
6
bool operator==(const Object &LHS, const Object &RHS) {
81
6
  if (LHS.size() != RHS.size())
82
0
    return false;
83
6
  for (const auto &L : LHS) {
84
6
    auto R = RHS.find(L.first);
85
6
    if (R == RHS.end() || L.second != R->second)
86
0
      return false;
87
6
  }
88
6
  return true;
89
6
}
90
91
455
Array::Array(std::initializer_list<Value> Elements) {
92
455
  V.reserve(Elements.size());
93
2.66k
  for (const Value &V : Elements) {
94
2.66k
    emplace_back(nullptr);
95
2.66k
    back().moveFrom(std::move(V));
96
2.66k
  }
97
455
}
98
99
Value::Value(std::initializer_list<Value> Elements)
100
19
    : Value(json::Array(Elements)) {}
Unexecuted instantiation: llvm::json::Value::Value(std::initializer_list<llvm::json::Value>)
llvm::json::Value::Value(std::initializer_list<llvm::json::Value>)
Line
Count
Source
100
19
    : Value(json::Array(Elements)) {}
101
102
179k
void Value::copyFrom(const Value &M) {
103
179k
  Type = M.Type;
104
179k
  switch (Type) {
105
179k
  case T_Null:
106
5.51k
  case T_Boolean:
107
5.51k
  case T_Double:
108
5.51k
  case T_Integer:
109
5.51k
    memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer));
110
5.51k
    break;
111
5.51k
  case T_StringRef:
112
28
    create<StringRef>(M.as<StringRef>());
113
28
    break;
114
171k
  case T_String:
115
171k
    create<std::string>(M.as<std::string>());
116
171k
    break;
117
5.51k
  case T_Object:
118
775
    create<json::Object>(M.as<json::Object>());
119
775
    break;
120
5.51k
  case T_Array:
121
1.05k
    create<json::Array>(M.as<json::Array>());
122
1.05k
    break;
123
179k
  }
124
179k
}
125
126
279k
void Value::moveFrom(const Value &&M) {
127
279k
  Type = M.Type;
128
279k
  switch (Type) {
129
279k
  case T_Null:
130
5.68k
  case T_Boolean:
131
5.68k
  case T_Double:
132
5.68k
  case T_Integer:
133
5.68k
    memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer));
134
5.68k
    break;
135
5.68k
  case T_StringRef:
136
81
    create<StringRef>(M.as<StringRef>());
137
81
    break;
138
217k
  case T_String:
139
217k
    create<std::string>(std::move(M.as<std::string>()));
140
217k
    M.Type = T_Null;
141
217k
    break;
142
35.2k
  case T_Object:
143
35.2k
    create<json::Object>(std::move(M.as<json::Object>()));
144
35.2k
    M.Type = T_Null;
145
35.2k
    break;
146
20.9k
  case T_Array:
147
20.9k
    create<json::Array>(std::move(M.as<json::Array>()));
148
20.9k
    M.Type = T_Null;
149
20.9k
    break;
150
279k
  }
151
279k
}
152
153
1.02M
void Value::destroy() {
154
1.02M
  switch (Type) {
155
1.02M
  case T_Null:
156
572k
  case T_Boolean:
157
572k
  case T_Double:
158
572k
  case T_Integer:
159
572k
    break;
160
572k
  case T_StringRef:
161
3.66k
    as<StringRef>().~StringRef();
162
3.66k
    break;
163
572k
  case T_String:
164
394k
    as<std::string>().~basic_string();
165
394k
    break;
166
572k
  case T_Object:
167
33.5k
    as<json::Object>().~Object();
168
33.5k
    break;
169
572k
  case T_Array:
170
22.0k
    as<json::Array>().~Array();
171
22.0k
    break;
172
1.02M
  }
173
1.02M
}
174
175
35
bool operator==(const Value &L, const Value &R) {
176
35
  if (L.kind() != R.kind())
177
0
    return false;
178
35
  switch (L.kind()) {
179
35
  case Value::Null:
180
1
    return *L.getAsNull() == *R.getAsNull();
181
35
  case Value::Boolean:
182
2
    return *L.getAsBoolean() == *R.getAsBoolean();
183
35
  case Value::Number:
184
13
    // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
185
13
    // The same integer must convert to the same double, per the standard.
186
13
    // However we see 64-vs-80-bit precision comparisons with gcc-7 -O3 -m32.
187
13
    // So we avoid floating point promotion for exact comparisons.
188
13
    if (L.Type == Value::T_Integer || 
R.Type == Value::T_Integer6
)
189
7
      return L.getAsInteger() == R.getAsInteger();
190
6
    return *L.getAsNumber() == *R.getAsNumber();
191
8
  case Value::String:
192
8
    return *L.getAsString() == *R.getAsString();
193
6
  case Value::Array:
194
6
    return *L.getAsArray() == *R.getAsArray();
195
6
  case Value::Object:
196
5
    return *L.getAsObject() == *R.getAsObject();
197
0
  }
198
0
  llvm_unreachable("Unknown value kind");
199
0
}
200
201
namespace {
202
// Simple recursive-descent JSON parser.
203
class Parser {
204
public:
205
  Parser(StringRef JSON)
206
4.90k
      : Start(JSON.begin()), P(JSON.begin()), End(JSON.end()) {}
207
208
4.90k
  bool checkUTF8() {
209
4.90k
    size_t ErrOffset;
210
4.90k
    if (isUTF8(StringRef(Start, End - Start), &ErrOffset))
211
4.90k
      return true;
212
1
    P = Start + ErrOffset; // For line/column calculation.
213
1
    return parseError("Invalid UTF-8 sequence");
214
1
  }
215
216
  bool parseValue(Value &Out);
217
218
4.88k
  bool assertEnd() {
219
4.88k
    eatWhitespace();
220
4.88k
    if (P == End)
221
4.88k
      return true;
222
1
    return parseError("Text after end of document");
223
1
  }
224
225
17
  Error takeError() {
226
17
    assert(Err);
227
17
    return std::move(*Err);
228
17
  }
229
230
private:
231
1.08M
  void eatWhitespace() {
232
1.12M
    while (P != End && 
(1.11M
*P == ' '1.11M
||
*P == '\r'1.08M
||
*P == '\n'1.08M
||
*P == '\t'1.07M
))
233
39.9k
      ++P;
234
1.08M
  }
235
236
  // On invalid syntax, parseX() functions return false and set Err.
237
  bool parseNumber(char First, Value &Out);
238
  bool parseString(std::string &Out);
239
  bool parseUnicode(std::string &Out);
240
  bool parseError(const char *Msg); // always returns false
241
242
5.94M
  char next() { return P == End ? 
00
: *P++; }
243
49.6k
  char peek() { return P == End ? 
011
:
*P49.6k
; }
244
150
  static bool isNumber(char C) {
245
150
    return C == '0' || 
C == '1'138
||
C == '2'117
||
C == '3'103
||
C == '4'96
||
246
150
           
C == '5'87
||
C == '6'76
||
C == '7'66
||
C == '8'58
||
C == '9'45
||
247
150
           
C == 'e'38
||
C == 'E'33
||
C == '+'33
||
C == '-'31
||
C == '.'30
;
248
150
  }
249
250
  Optional<Error> Err;
251
  const char *Start, *P, *End;
252
};
253
254
263k
bool Parser::parseValue(Value &Out) {
255
263k
  eatWhitespace();
256
263k
  if (P == End)
257
2
    return parseError("Unexpected EOF");
258
263k
  switch (char C = next()) {
259
263k
  // Bare null/true/false are easy - first char identifies them.
260
263k
  case 'n':
261
3
    Out = nullptr;
262
3
    return (next() == 'u' && next() == 'l' && next() == 'l') ||
263
3
           
parseError("Invalid JSON value (null?)")0
;
264
263k
  case 't':
265
2
    Out = true;
266
2
    return (next() == 'r' && next() == 'u' && next() == 'e') ||
267
2
           
parseError("Invalid JSON value (true?)")0
;
268
263k
  case 'f':
269
3
    Out = false;
270
3
    return (next() == 'a' && 
next() == 'l'2
&&
next() == 's'2
&&
next() == 'e'2
) ||
271
3
           
parseError("Invalid JSON value (false?)")1
;
272
263k
  case '"': {
273
214k
    std::string S;
274
214k
    if (parseString(S)) {
275
214k
      Out = std::move(S);
276
214k
      return true;
277
214k
    }
278
4
    return false;
279
4
  }
280
20.3k
  case '[': {
281
20.3k
    Out = Array{};
282
20.3k
    Array &A = *Out.getAsArray();
283
20.3k
    eatWhitespace();
284
20.3k
    if (peek() == ']') {
285
3.89k
      ++P;
286
3.89k
      return true;
287
3.89k
    }
288
111k
    
for (;;)16.4k
{
289
111k
      A.emplace_back(nullptr);
290
111k
      if (!parseValue(A.back()))
291
2
        return false;
292
111k
      eatWhitespace();
293
111k
      switch (next()) {
294
111k
      case ',':
295
95.5k
        eatWhitespace();
296
95.5k
        continue;
297
111k
      case ']':
298
16.4k
        return true;
299
111k
      default:
300
1
        return parseError("Expected , or ] after array element");
301
111k
      }
302
111k
    }
303
16.4k
  }
304
29.2k
  case '{': {
305
29.2k
    Out = Object{};
306
29.2k
    Object &O = *Out.getAsObject();
307
29.2k
    eatWhitespace();
308
29.2k
    if (peek() == '}') {
309
1
      ++P;
310
1
      return true;
311
1
    }
312
146k
    
for (;;)29.2k
{
313
146k
      if (next() != '"')
314
3
        return parseError("Expected object key");
315
146k
      std::string K;
316
146k
      if (!parseString(K))
317
0
        return false;
318
146k
      eatWhitespace();
319
146k
      if (next() != ':')
320
1
        return parseError("Expected : after object key");
321
146k
      eatWhitespace();
322
146k
      if (!parseValue(O[std::move(K)]))
323
0
        return false;
324
146k
      eatWhitespace();
325
146k
      switch (next()) {
326
146k
      case ',':
327
117k
        eatWhitespace();
328
117k
        continue;
329
146k
      case '}':
330
29.2k
        return true;
331
146k
      default:
332
1
        return parseError("Expected , or } after object property");
333
146k
      }
334
146k
    }
335
29.2k
  }
336
29.2k
  default:
337
22
    if (isNumber(C))
338
21
      return parseNumber(C, Out);
339
1
    return parseError("Invalid JSON value");
340
263k
  }
341
263k
}
342
343
21
bool Parser::parseNumber(char First, Value &Out) {
344
21
  // Read the number into a string. (Must be null-terminated for strto*).
345
21
  SmallString<24> S;
346
21
  S.push_back(First);
347
128
  while (isNumber(peek()))
348
107
    S.push_back(next());
349
21
  char *End;
350
21
  // Try first to parse as integer, and if so preserve full 64 bits.
351
21
  // strtoll returns long long >= 64 bits, so check it's in range too.
352
21
  auto I = std::strtoll(S.c_str(), &End, 10);
353
21
  if (End == S.end() && 
I >= std::numeric_limits<int64_t>::min()12
&&
354
21
      
I <= std::numeric_limits<int64_t>::max()12
) {
355
12
    Out = int64_t(I);
356
12
    return true;
357
12
  }
358
9
  // If it's not an integer
359
9
  Out = std::strtod(S.c_str(), &End);
360
9
  return End == S.end() || 
parseError("Invalid JSON value (number?)")1
;
361
9
}
362
363
361k
bool Parser::parseString(std::string &Out) {
364
361k
  // leading quote was already consumed.
365
5.11M
  for (char C = next(); C != '"'; 
C = next()4.75M
) {
366
4.75M
    if (LLVM_UNLIKELY(P == End))
367
4.75M
      
return parseError("Unterminated string")1
;
368
4.75M
    if (LLVM_UNLIKELY((C & 0x1f) == C))
369
4.75M
      
return parseError("Control character in string")1
;
370
4.75M
    if (LLVM_LIKELY(C != '\\')) {
371
4.74M
      Out.push_back(C);
372
4.74M
      continue;
373
4.74M
    }
374
9.10k
    // Handle escape sequence.
375
9.10k
    switch (C = next()) {
376
9.10k
    case '"':
377
9.10k
    case '\\':
378
9.10k
    case '/':
379
9.10k
      Out.push_back(C);
380
9.10k
      break;
381
9.10k
    case 'b':
382
1
      Out.push_back('\b');
383
1
      break;
384
9.10k
    case 'f':
385
1
      Out.push_back('\f');
386
1
      break;
387
9.10k
    case 'n':
388
2
      Out.push_back('\n');
389
2
      break;
390
9.10k
    case 'r':
391
1
      Out.push_back('\r');
392
1
      break;
393
9.10k
    case 't':
394
1
      Out.push_back('\t');
395
1
      break;
396
9.10k
    case 'u':
397
7
      if (!parseUnicode(Out))
398
1
        return false;
399
6
      break;
400
6
    default:
401
1
      return parseError("Invalid escape sequence");
402
9.10k
    }
403
9.10k
  }
404
361k
  return true;
405
361k
}
406
407
4
static void encodeUtf8(uint32_t Rune, std::string &Out) {
408
4
  if (Rune < 0x80) {
409
2
    Out.push_back(Rune & 0x7F);
410
2
  } else if (Rune < 0x800) {
411
0
    uint8_t FirstByte = 0xC0 | ((Rune & 0x7C0) >> 6);
412
0
    uint8_t SecondByte = 0x80 | (Rune & 0x3F);
413
0
    Out.push_back(FirstByte);
414
0
    Out.push_back(SecondByte);
415
2
  } else if (Rune < 0x10000) {
416
0
    uint8_t FirstByte = 0xE0 | ((Rune & 0xF000) >> 12);
417
0
    uint8_t SecondByte = 0x80 | ((Rune & 0xFC0) >> 6);
418
0
    uint8_t ThirdByte = 0x80 | (Rune & 0x3F);
419
0
    Out.push_back(FirstByte);
420
0
    Out.push_back(SecondByte);
421
0
    Out.push_back(ThirdByte);
422
2
  } else if (Rune < 0x110000) {
423
2
    uint8_t FirstByte = 0xF0 | ((Rune & 0x1F0000) >> 18);
424
2
    uint8_t SecondByte = 0x80 | ((Rune & 0x3F000) >> 12);
425
2
    uint8_t ThirdByte = 0x80 | ((Rune & 0xFC0) >> 6);
426
2
    uint8_t FourthByte = 0x80 | (Rune & 0x3F);
427
2
    Out.push_back(FirstByte);
428
2
    Out.push_back(SecondByte);
429
2
    Out.push_back(ThirdByte);
430
2
    Out.push_back(FourthByte);
431
2
  } else {
432
0
    llvm_unreachable("Invalid codepoint");
433
0
  }
434
4
}
435
436
// Parse a UTF-16 \uNNNN escape sequence. "\u" has already been consumed.
437
// May parse several sequential escapes to ensure proper surrogate handling.
438
// We do not use ConvertUTF.h, it can't accept and replace unpaired surrogates.
439
// These are invalid Unicode but valid JSON (RFC 8259, section 8.2).
440
7
bool Parser::parseUnicode(std::string &Out) {
441
7
  // Invalid UTF is not a JSON error (RFC 8529ยง8.2). It gets replaced by U+FFFD.
442
7
  auto Invalid = [&] 
{ Out.append(/* UTF-8 */ {'\xef', '\xbf', '\xbd'}); }3
;
443
7
  // Decodes 4 hex digits from the stream into Out, returns false on error.
444
10
  auto Parse4Hex = [this](uint16_t &Out) -> bool {
445
10
    Out = 0;
446
10
    char Bytes[] = {next(), next(), next(), next()};
447
37
    for (unsigned char C : Bytes) {
448
37
      if (!std::isxdigit(C))
449
1
        return parseError("Invalid \\u escape sequence");
450
36
      Out <<= 4;
451
36
      Out |= (C > '9') ? 
(C & ~0x20) - 'A' + 1010
:
(C - '0')26
;
452
36
    }
453
10
    
return true9
;
454
10
  };
455
7
  uint16_t First; // UTF-16 code unit from the first \u escape.
456
7
  if (!Parse4Hex(First))
457
1
    return false;
458
6
459
6
  // We loop to allow proper surrogate-pair error handling.
460
7
  
while (6
true) {
461
7
    // Case 1: the UTF-16 code unit is already a codepoint in the BMP.
462
7
    if (LLVM_LIKELY(First < 0xD800 || First >= 0xE000)) {
463
2
      encodeUtf8(First, Out);
464
2
      return true;
465
2
    }
466
5
467
5
    // Case 2: it's an (unpaired) trailing surrogate.
468
5
    if (LLVM_UNLIKELY(First >= 0xDC00)) {
469
1
      Invalid();
470
1
      return true;
471
1
    }
472
4
473
4
    // Case 3: it's a leading surrogate. We expect a trailing one next.
474
4
    // Case 3a: there's no trailing \u escape. Don't advance in the stream.
475
4
    if (LLVM_UNLIKELY(P + 2 > End || *P != '\\' || *(P + 1) != 'u')) {
476
1
      Invalid(); // Leading surrogate was unpaired.
477
1
      return true;
478
1
    }
479
3
    P += 2;
480
3
    uint16_t Second;
481
3
    if (!Parse4Hex(Second))
482
0
      return false;
483
3
    // Case 3b: there was another \u escape, but it wasn't a trailing surrogate.
484
3
    if (LLVM_UNLIKELY(Second < 0xDC00 || Second >= 0xE000)) {
485
1
      Invalid();      // Leading surrogate was unpaired.
486
1
      First = Second; // Second escape still needs to be processed.
487
1
      continue;
488
1
    }
489
2
    // Case 3c: a valid surrogate pair encoding an astral codepoint.
490
2
    encodeUtf8(0x10000 | ((First - 0xD800) << 10) | (Second - 0xDC00), Out);
491
2
    return true;
492
2
  }
493
6
}
494
495
17
bool Parser::parseError(const char *Msg) {
496
17
  int Line = 1;
497
17
  const char *StartOfLine = Start;
498
93
  for (const char *X = Start; X < P; 
++X76
) {
499
76
    if (*X == 0x0A) {
500
3
      ++Line;
501
3
      StartOfLine = X + 1;
502
3
    }
503
76
  }
504
17
  Err.emplace(
505
17
      llvm::make_unique<ParseError>(Msg, Line, P - StartOfLine, P - Start));
506
17
  return false;
507
17
}
508
} // namespace
509
510
4.90k
Expected<Value> parse(StringRef JSON) {
511
4.90k
  Parser P(JSON);
512
4.90k
  Value E = nullptr;
513
4.90k
  if (P.checkUTF8())
514
4.90k
    if (P.parseValue(E))
515
4.88k
      if (P.assertEnd())
516
4.88k
        return std::move(E);
517
17
  return P.takeError();
518
17
}
519
char ParseError::ID = 0;
520
521
3.48k
static std::vector<const Object::value_type *> sortedElements(const Object &O) {
522
3.48k
  std::vector<const Object::value_type *> Elements;
523
3.48k
  for (const auto &E : O)
524
7.77k
    Elements.push_back(&E);
525
3.48k
  llvm::sort(Elements,
526
9.47k
             [](const Object::value_type *L, const Object::value_type *R) {
527
9.47k
               return L->first < R->first;
528
9.47k
             });
529
3.48k
  return Elements;
530
3.48k
}
531
532
1.07M
bool isUTF8(llvm::StringRef S, size_t *ErrOffset) {
533
1.07M
  // Fast-path for ASCII, which is valid UTF-8.
534
1.07M
  if (LLVM_LIKELY(isASCII(S)))
535
1.07M
    
return true1.07M
;
536
19
537
19
  const UTF8 *Data = reinterpret_cast<const UTF8 *>(S.data()), *Rest = Data;
538
19
  if (LLVM_LIKELY(isLegalUTF8String(&Rest, Data + S.size())))
539
19
    
return true13
;
540
6
541
6
  if (ErrOffset)
542
1
    *ErrOffset = Rest - Data;
543
6
  return false;
544
6
}
545
546
11
std::string fixUTF8(llvm::StringRef S) {
547
11
  // This isn't particularly efficient, but is only for error-recovery.
548
11
  std::vector<UTF32> Codepoints(S.size()); // 1 codepoint per byte suffices.
549
11
  const UTF8 *In8 = reinterpret_cast<const UTF8 *>(S.data());
550
11
  UTF32 *Out32 = Codepoints.data();
551
11
  ConvertUTF8toUTF32(&In8, In8 + S.size(), &Out32, Out32 + Codepoints.size(),
552
11
                     lenientConversion);
553
11
  Codepoints.resize(Out32 - Codepoints.data());
554
11
  std::string Res(4 * Codepoints.size(), 0); // 4 bytes per codepoint suffice
555
11
  const UTF32 *In32 = Codepoints.data();
556
11
  UTF8 *Out8 = reinterpret_cast<UTF8 *>(&Res[0]);
557
11
  ConvertUTF32toUTF8(&In32, In32 + Codepoints.size(), &Out8, Out8 + Res.size(),
558
11
                     strictConversion);
559
11
  Res.resize(reinterpret_cast<char *>(Out8) - Res.data());
560
11
  return Res;
561
11
}
562
563
53.0k
static void quote(llvm::raw_ostream &OS, llvm::StringRef S) {
564
53.0k
  OS << '\"';
565
369k
  for (unsigned char C : S) {
566
369k
    if (C == 0x22 || 
C == 0x5C369k
)
567
32
      OS << '\\';
568
369k
    if (C >= 0x20) {
569
369k
      OS << C;
570
369k
      continue;
571
369k
    }
572
23
    OS << '\\';
573
23
    switch (C) {
574
23
    // A few characters are common enough to make short escapes worthwhile.
575
23
    case '\t':
576
3
      OS << 't';
577
3
      break;
578
23
    case '\n':
579
6
      OS << 'n';
580
6
      break;
581
23
    case '\r':
582
3
      OS << 'r';
583
3
      break;
584
23
    default:
585
11
      OS << 'u';
586
11
      llvm::write_hex(OS, C, llvm::HexPrintStyle::Lower, 4);
587
11
      break;
588
23
    }
589
23
  }
590
53.0k
  OS << '\"';
591
53.0k
}
592
593
35.0k
void llvm::json::OStream::value(const Value &V) {
594
35.0k
  switch (V.kind()) {
595
35.0k
  case Value::Null:
596
44
    valueBegin();
597
44
    OS << "null";
598
44
    return;
599
35.0k
  case Value::Boolean:
600
3.69k
    valueBegin();
601
3.69k
    OS << (*V.getAsBoolean() ? 
"true"3.48k
:
"false"209
);
602
3.69k
    return;
603
35.0k
  case Value::Number:
604
15.3k
    valueBegin();
605
15.3k
    if (V.Type == Value::T_Integer)
606
15.1k
      OS << *V.getAsInteger();
607
154
    else
608
154
      OS << format("%.*g", std::numeric_limits<double>::max_digits10,
609
154
                   *V.getAsNumber());
610
15.3k
    return;
611
35.0k
  case Value::String:
612
11.8k
    valueBegin();
613
11.8k
    quote(OS, *V.getAsString());
614
11.8k
    return;
615
35.0k
  case Value::Array:
616
650
    return array([&] {
617
650
      for (const Value &E : *V.getAsArray())
618
3.26k
        value(E);
619
650
    });
620
35.0k
  case Value::Object:
621
3.48k
    return object([&] {
622
3.48k
      for (const Object::value_type *E : sortedElements(*V.getAsObject()))
623
7.77k
        attribute(E->first, E->second);
624
3.48k
    });
625
35.0k
  }
626
35.0k
}
627
628
47.2k
void llvm::json::OStream::valueBegin() {
629
47.2k
  assert(Stack.back().Ctx != Object && "Only attributes allowed here");
630
47.2k
  if (Stack.back().HasValue) {
631
3.75k
    assert(Stack.back().Ctx != Singleton && "Only one value allowed here");
632
3.75k
    OS << ',';
633
3.75k
  }
634
47.2k
  if (Stack.back().Ctx == Array)
635
5.79k
    newline();
636
47.2k
  Stack.back().HasValue = true;
637
47.2k
}
638
639
62.9k
void llvm::json::OStream::newline() {
640
62.9k
  if (IndentSize) {
641
57.0k
    OS.write('\n');
642
57.0k
    OS.indent(Indent);
643
57.0k
  }
644
62.9k
}
645
646
2.08k
void llvm::json::OStream::arrayBegin() {
647
2.08k
  valueBegin();
648
2.08k
  Stack.emplace_back();
649
2.08k
  Stack.back().Ctx = Array;
650
2.08k
  Indent += IndentSize;
651
2.08k
  OS << '[';
652
2.08k
}
653
654
2.08k
void llvm::json::OStream::arrayEnd() {
655
2.08k
  assert(Stack.back().Ctx == Array);
656
2.08k
  Indent -= IndentSize;
657
2.08k
  if (Stack.back().HasValue)
658
2.04k
    newline();
659
2.08k
  OS << ']';
660
2.08k
  Stack.pop_back();
661
2.08k
  assert(!Stack.empty());
662
2.08k
}
663
664
14.2k
void llvm::json::OStream::objectBegin() {
665
14.2k
  valueBegin();
666
14.2k
  Stack.emplace_back();
667
14.2k
  Stack.back().Ctx = Object;
668
14.2k
  Indent += IndentSize;
669
14.2k
  OS << '{';
670
14.2k
}
671
672
14.2k
void llvm::json::OStream::objectEnd() {
673
14.2k
  assert(Stack.back().Ctx == Object);
674
14.2k
  Indent -= IndentSize;
675
14.2k
  if (Stack.back().HasValue)
676
13.8k
    newline();
677
14.2k
  OS << '}';
678
14.2k
  Stack.pop_back();
679
14.2k
  assert(!Stack.empty());
680
14.2k
}
681
682
41.2k
void llvm::json::OStream::attributeBegin(llvm::StringRef Key) {
683
41.2k
  assert(Stack.back().Ctx == Object);
684
41.2k
  if (Stack.back().HasValue)
685
27.3k
    OS << ',';
686
41.2k
  newline();
687
41.2k
  Stack.back().HasValue = true;
688
41.2k
  Stack.emplace_back();
689
41.2k
  Stack.back().Ctx = Singleton;
690
41.2k
  if (LLVM_LIKELY(isUTF8(Key))) {
691
41.2k
    quote(OS, Key);
692
41.2k
  } else {
693
0
    assert(false && "Invalid UTF-8 in attribute key");
694
0
    quote(OS, fixUTF8(Key));
695
0
  }
696
41.2k
  OS.write(':');
697
41.2k
  if (IndentSize)
698
39.6k
    OS.write(' ');
699
41.2k
}
700
701
41.2k
void llvm::json::OStream::attributeEnd() {
702
41.2k
  assert(Stack.back().Ctx == Singleton);
703
41.2k
  assert(Stack.back().HasValue && "Attribute must have a value");
704
41.2k
  Stack.pop_back();
705
41.2k
  assert(Stack.back().Ctx == Object);
706
41.2k
}
707
708
} // namespace json
709
} // namespace llvm
710
711
void llvm::format_provider<llvm::json::Value>::format(
712
72
    const llvm::json::Value &E, raw_ostream &OS, StringRef Options) {
713
72
  unsigned IndentAmount = 0;
714
72
  if (!Options.empty() && 
Options.getAsInteger(/*Radix=*/10, IndentAmount)39
)
715
72
    
llvm_unreachable0
("json::Value format options should be an integer");
716
72
  json::OStream(OS, IndentAmount).value(E);
717
72
}
718