LLVM  14.0.0git
JSON.cpp
Go to the documentation of this file.
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/ADT/STLExtras.h"
12 #include "llvm/Support/Error.h"
13 #include "llvm/Support/Format.h"
15 #include <cctype>
16 
17 namespace llvm {
18 namespace json {
19 
21  return try_emplace(K, nullptr).first->getSecond();
22 }
24  return try_emplace(std::move(K), nullptr).first->getSecond();
25 }
27  auto I = find(K);
28  if (I == end())
29  return nullptr;
30  return &I->second;
31 }
32 const Value *Object::get(StringRef K) const {
33  auto I = find(K);
34  if (I == end())
35  return nullptr;
36  return &I->second;
37 }
39  if (auto *V = get(K))
40  return V->getAsNull();
41  return llvm::None;
42 }
44  if (auto *V = get(K))
45  return V->getAsBoolean();
46  return llvm::None;
47 }
49  if (auto *V = get(K))
50  return V->getAsNumber();
51  return llvm::None;
52 }
54  if (auto *V = get(K))
55  return V->getAsInteger();
56  return llvm::None;
57 }
59  if (auto *V = get(K))
60  return V->getAsString();
61  return llvm::None;
62 }
64  if (auto *V = get(K))
65  return V->getAsObject();
66  return nullptr;
67 }
69  if (auto *V = get(K))
70  return V->getAsObject();
71  return nullptr;
72 }
74  if (auto *V = get(K))
75  return V->getAsArray();
76  return nullptr;
77 }
79  if (auto *V = get(K))
80  return V->getAsArray();
81  return nullptr;
82 }
83 bool operator==(const Object &LHS, const Object &RHS) {
84  if (LHS.size() != RHS.size())
85  return false;
86  for (const auto &L : LHS) {
87  auto R = RHS.find(L.first);
88  if (R == RHS.end() || L.second != R->second)
89  return false;
90  }
91  return true;
92 }
93 
94 Array::Array(std::initializer_list<Value> Elements) {
95  V.reserve(Elements.size());
96  for (const Value &V : Elements) {
97  emplace_back(nullptr);
98  back().moveFrom(std::move(V));
99  }
100 }
101 
102 Value::Value(std::initializer_list<Value> Elements)
103  : Value(json::Array(Elements)) {}
104 
105 void Value::copyFrom(const Value &M) {
106  Type = M.Type;
107  switch (Type) {
108  case T_Null:
109  case T_Boolean:
110  case T_Double:
111  case T_Integer:
112  case T_UINT64:
113  memcpy(&Union, &M.Union, sizeof(Union));
114  break;
115  case T_StringRef:
116  create<StringRef>(M.as<StringRef>());
117  break;
118  case T_String:
119  create<std::string>(M.as<std::string>());
120  break;
121  case T_Object:
122  create<json::Object>(M.as<json::Object>());
123  break;
124  case T_Array:
125  create<json::Array>(M.as<json::Array>());
126  break;
127  }
128 }
129 
130 void Value::moveFrom(const Value &&M) {
131  Type = M.Type;
132  switch (Type) {
133  case T_Null:
134  case T_Boolean:
135  case T_Double:
136  case T_Integer:
137  case T_UINT64:
138  memcpy(&Union, &M.Union, sizeof(Union));
139  break;
140  case T_StringRef:
141  create<StringRef>(M.as<StringRef>());
142  break;
143  case T_String:
144  create<std::string>(std::move(M.as<std::string>()));
145  M.Type = T_Null;
146  break;
147  case T_Object:
148  create<json::Object>(std::move(M.as<json::Object>()));
149  M.Type = T_Null;
150  break;
151  case T_Array:
152  create<json::Array>(std::move(M.as<json::Array>()));
153  M.Type = T_Null;
154  break;
155  }
156 }
157 
158 void Value::destroy() {
159  switch (Type) {
160  case T_Null:
161  case T_Boolean:
162  case T_Double:
163  case T_Integer:
164  case T_UINT64:
165  break;
166  case T_StringRef:
167  as<StringRef>().~StringRef();
168  break;
169  case T_String:
170  as<std::string>().~basic_string();
171  break;
172  case T_Object:
173  as<json::Object>().~Object();
174  break;
175  case T_Array:
176  as<json::Array>().~Array();
177  break;
178  }
179 }
180 
181 bool operator==(const Value &L, const Value &R) {
182  if (L.kind() != R.kind())
183  return false;
184  switch (L.kind()) {
185  case Value::Null:
186  return *L.getAsNull() == *R.getAsNull();
187  case Value::Boolean:
188  return *L.getAsBoolean() == *R.getAsBoolean();
189  case Value::Number:
190  // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323
191  // The same integer must convert to the same double, per the standard.
192  // However we see 64-vs-80-bit precision comparisons with gcc-7 -O3 -m32.
193  // So we avoid floating point promotion for exact comparisons.
194  if (L.Type == Value::T_Integer || R.Type == Value::T_Integer)
195  return L.getAsInteger() == R.getAsInteger();
196  return *L.getAsNumber() == *R.getAsNumber();
197  case Value::String:
198  return *L.getAsString() == *R.getAsString();
199  case Value::Array:
200  return *L.getAsArray() == *R.getAsArray();
201  case Value::Object:
202  return *L.getAsObject() == *R.getAsObject();
203  }
204  llvm_unreachable("Unknown value kind");
205 }
206 
208  // Walk up to the root context, and count the number of segments.
209  unsigned Count = 0;
210  const Path *P;
211  for (P = this; P->Parent != nullptr; P = P->Parent)
212  ++Count;
213  Path::Root *R = P->Seg.root();
214  // Fill in the error message and copy the path (in reverse order).
215  R->ErrorMessage = Msg;
216  R->ErrorPath.resize(Count);
217  auto It = R->ErrorPath.begin();
218  for (P = this; P->Parent != nullptr; P = P->Parent)
219  *It++ = P->Seg;
220 }
221 
223  std::string S;
224  raw_string_ostream OS(S);
225  OS << (ErrorMessage.empty() ? "invalid JSON contents" : ErrorMessage);
226  if (ErrorPath.empty()) {
227  if (!Name.empty())
228  OS << " when parsing " << Name;
229  } else {
230  OS << " at " << (Name.empty() ? "(root)" : Name);
231  for (const Path::Segment &S : llvm::reverse(ErrorPath)) {
232  if (S.isField())
233  OS << '.' << S.field();
234  else
235  OS << '[' << S.index() << ']';
236  }
237  }
239 }
240 
241 namespace {
242 
243 std::vector<const Object::value_type *> sortedElements(const Object &O) {
244  std::vector<const Object::value_type *> Elements;
245  for (const auto &E : O)
246  Elements.push_back(&E);
247  llvm::sort(Elements,
248  [](const Object::value_type *L, const Object::value_type *R) {
249  return L->first < R->first;
250  });
251  return Elements;
252 }
253 
254 // Prints a one-line version of a value that isn't our main focus.
255 // We interleave writes to OS and JOS, exploiting the lack of extra buffering.
256 // This is OK as we own the implementation.
257 void abbreviate(const Value &V, OStream &JOS) {
258  switch (V.kind()) {
259  case Value::Array:
260  JOS.rawValue(V.getAsArray()->empty() ? "[]" : "[ ... ]");
261  break;
262  case Value::Object:
263  JOS.rawValue(V.getAsObject()->empty() ? "{}" : "{ ... }");
264  break;
265  case Value::String: {
266  llvm::StringRef S = *V.getAsString();
267  if (S.size() < 40) {
268  JOS.value(V);
269  } else {
270  std::string Truncated = fixUTF8(S.take_front(37));
271  Truncated.append("...");
272  JOS.value(Truncated);
273  }
274  break;
275  }
276  default:
277  JOS.value(V);
278  }
279 }
280 
281 // Prints a semi-expanded version of a value that is our main focus.
282 // Array/Object entries are printed, but not recursively as they may be huge.
283 void abbreviateChildren(const Value &V, OStream &JOS) {
284  switch (V.kind()) {
285  case Value::Array:
286  JOS.array([&] {
287  for (const auto &I : *V.getAsArray())
288  abbreviate(I, JOS);
289  });
290  break;
291  case Value::Object:
292  JOS.object([&] {
293  for (const auto *KV : sortedElements(*V.getAsObject())) {
294  JOS.attributeBegin(KV->first);
295  abbreviate(KV->second, JOS);
296  JOS.attributeEnd();
297  }
298  });
299  break;
300  default:
301  JOS.value(V);
302  }
303 }
304 
305 } // namespace
306 
308  OStream JOS(OS, /*IndentSize=*/2);
309  // PrintValue recurses down the path, printing the ancestors of our target.
310  // Siblings of nodes along the path are printed with abbreviate(), and the
311  // target itself is printed with the somewhat richer abbreviateChildren().
312  // 'Recurse' is the lambda itself, to allow recursive calls.
313  auto PrintValue = [&](const Value &V, ArrayRef<Segment> Path, auto &Recurse) {
314  // Print the target node itself, with the error as a comment.
315  // Also used if we can't follow our path, e.g. it names a field that
316  // *should* exist but doesn't.
317  auto HighlightCurrent = [&] {
318  std::string Comment = "error: ";
319  Comment.append(ErrorMessage.data(), ErrorMessage.size());
320  JOS.comment(Comment);
321  abbreviateChildren(V, JOS);
322  };
323  if (Path.empty()) // We reached our target.
324  return HighlightCurrent();
325  const Segment &S = Path.back(); // Path is in reverse order.
326  if (S.isField()) {
327  // Current node is an object, path names a field.
328  llvm::StringRef FieldName = S.field();
329  const Object *O = V.getAsObject();
330  if (!O || !O->get(FieldName))
331  return HighlightCurrent();
332  JOS.object([&] {
333  for (const auto *KV : sortedElements(*O)) {
334  JOS.attributeBegin(KV->first);
335  if (FieldName.equals(KV->first))
336  Recurse(KV->second, Path.drop_back(), Recurse);
337  else
338  abbreviate(KV->second, JOS);
339  JOS.attributeEnd();
340  }
341  });
342  } else {
343  // Current node is an array, path names an element.
344  const Array *A = V.getAsArray();
345  if (!A || S.index() >= A->size())
346  return HighlightCurrent();
347  JOS.array([&] {
348  unsigned Current = 0;
349  for (const auto &V : *A) {
350  if (Current++ == S.index())
351  Recurse(V, Path.drop_back(), Recurse);
352  else
353  abbreviate(V, JOS);
354  }
355  });
356  }
357  };
358  PrintValue(R, ErrorPath, PrintValue);
359 }
360 
361 namespace {
362 // Simple recursive-descent JSON parser.
363 class Parser {
364 public:
365  Parser(StringRef JSON)
366  : Start(JSON.begin()), P(JSON.begin()), End(JSON.end()) {}
367 
368  bool checkUTF8() {
369  size_t ErrOffset;
370  if (isUTF8(StringRef(Start, End - Start), &ErrOffset))
371  return true;
372  P = Start + ErrOffset; // For line/column calculation.
373  return parseError("Invalid UTF-8 sequence");
374  }
375 
376  bool parseValue(Value &Out);
377 
378  bool assertEnd() {
379  eatWhitespace();
380  if (P == End)
381  return true;
382  return parseError("Text after end of document");
383  }
384 
385  Error takeError() {
386  assert(Err);
387  return std::move(*Err);
388  }
389 
390 private:
391  void eatWhitespace() {
392  while (P != End && (*P == ' ' || *P == '\r' || *P == '\n' || *P == '\t'))
393  ++P;
394  }
395 
396  // On invalid syntax, parseX() functions return false and set Err.
397  bool parseNumber(char First, Value &Out);
398  bool parseString(std::string &Out);
399  bool parseUnicode(std::string &Out);
400  bool parseError(const char *Msg); // always returns false
401 
402  char next() { return P == End ? 0 : *P++; }
403  char peek() { return P == End ? 0 : *P; }
404  static bool isNumber(char C) {
405  return C == '0' || C == '1' || C == '2' || C == '3' || C == '4' ||
406  C == '5' || C == '6' || C == '7' || C == '8' || C == '9' ||
407  C == 'e' || C == 'E' || C == '+' || C == '-' || C == '.';
408  }
409 
410  Optional<Error> Err;
411  const char *Start, *P, *End;
412 };
413 
414 bool Parser::parseValue(Value &Out) {
415  eatWhitespace();
416  if (P == End)
417  return parseError("Unexpected EOF");
418  switch (char C = next()) {
419  // Bare null/true/false are easy - first char identifies them.
420  case 'n':
421  Out = nullptr;
422  return (next() == 'u' && next() == 'l' && next() == 'l') ||
423  parseError("Invalid JSON value (null?)");
424  case 't':
425  Out = true;
426  return (next() == 'r' && next() == 'u' && next() == 'e') ||
427  parseError("Invalid JSON value (true?)");
428  case 'f':
429  Out = false;
430  return (next() == 'a' && next() == 'l' && next() == 's' && next() == 'e') ||
431  parseError("Invalid JSON value (false?)");
432  case '"': {
433  std::string S;
434  if (parseString(S)) {
435  Out = std::move(S);
436  return true;
437  }
438  return false;
439  }
440  case '[': {
441  Out = Array{};
442  Array &A = *Out.getAsArray();
443  eatWhitespace();
444  if (peek() == ']') {
445  ++P;
446  return true;
447  }
448  for (;;) {
449  A.emplace_back(nullptr);
450  if (!parseValue(A.back()))
451  return false;
452  eatWhitespace();
453  switch (next()) {
454  case ',':
455  eatWhitespace();
456  continue;
457  case ']':
458  return true;
459  default:
460  return parseError("Expected , or ] after array element");
461  }
462  }
463  }
464  case '{': {
465  Out = Object{};
466  Object &O = *Out.getAsObject();
467  eatWhitespace();
468  if (peek() == '}') {
469  ++P;
470  return true;
471  }
472  for (;;) {
473  if (next() != '"')
474  return parseError("Expected object key");
475  std::string K;
476  if (!parseString(K))
477  return false;
478  eatWhitespace();
479  if (next() != ':')
480  return parseError("Expected : after object key");
481  eatWhitespace();
482  if (!parseValue(O[std::move(K)]))
483  return false;
484  eatWhitespace();
485  switch (next()) {
486  case ',':
487  eatWhitespace();
488  continue;
489  case '}':
490  return true;
491  default:
492  return parseError("Expected , or } after object property");
493  }
494  }
495  }
496  default:
497  if (isNumber(C))
498  return parseNumber(C, Out);
499  return parseError("Invalid JSON value");
500  }
501 }
502 
503 bool Parser::parseNumber(char First, Value &Out) {
504  // Read the number into a string. (Must be null-terminated for strto*).
505  SmallString<24> S;
506  S.push_back(First);
507  while (isNumber(peek()))
508  S.push_back(next());
509  char *End;
510  // Try first to parse as integer, and if so preserve full 64 bits.
511  // strtoll returns long long >= 64 bits, so check it's in range too.
512  auto I = std::strtoll(S.c_str(), &End, 10);
513  if (End == S.end() && I >= std::numeric_limits<int64_t>::min() &&
515  Out = int64_t(I);
516  return true;
517  }
518  // If it's not an integer
519  Out = std::strtod(S.c_str(), &End);
520  return End == S.end() || parseError("Invalid JSON value (number?)");
521 }
522 
523 bool Parser::parseString(std::string &Out) {
524  // leading quote was already consumed.
525  for (char C = next(); C != '"'; C = next()) {
526  if (LLVM_UNLIKELY(P == End))
527  return parseError("Unterminated string");
528  if (LLVM_UNLIKELY((C & 0x1f) == C))
529  return parseError("Control character in string");
530  if (LLVM_LIKELY(C != '\\')) {
531  Out.push_back(C);
532  continue;
533  }
534  // Handle escape sequence.
535  switch (C = next()) {
536  case '"':
537  case '\\':
538  case '/':
539  Out.push_back(C);
540  break;
541  case 'b':
542  Out.push_back('\b');
543  break;
544  case 'f':
545  Out.push_back('\f');
546  break;
547  case 'n':
548  Out.push_back('\n');
549  break;
550  case 'r':
551  Out.push_back('\r');
552  break;
553  case 't':
554  Out.push_back('\t');
555  break;
556  case 'u':
557  if (!parseUnicode(Out))
558  return false;
559  break;
560  default:
561  return parseError("Invalid escape sequence");
562  }
563  }
564  return true;
565 }
566 
567 static void encodeUtf8(uint32_t Rune, std::string &Out) {
568  if (Rune < 0x80) {
569  Out.push_back(Rune & 0x7F);
570  } else if (Rune < 0x800) {
571  uint8_t FirstByte = 0xC0 | ((Rune & 0x7C0) >> 6);
572  uint8_t SecondByte = 0x80 | (Rune & 0x3F);
573  Out.push_back(FirstByte);
574  Out.push_back(SecondByte);
575  } else if (Rune < 0x10000) {
576  uint8_t FirstByte = 0xE0 | ((Rune & 0xF000) >> 12);
577  uint8_t SecondByte = 0x80 | ((Rune & 0xFC0) >> 6);
578  uint8_t ThirdByte = 0x80 | (Rune & 0x3F);
579  Out.push_back(FirstByte);
580  Out.push_back(SecondByte);
581  Out.push_back(ThirdByte);
582  } else if (Rune < 0x110000) {
583  uint8_t FirstByte = 0xF0 | ((Rune & 0x1F0000) >> 18);
584  uint8_t SecondByte = 0x80 | ((Rune & 0x3F000) >> 12);
585  uint8_t ThirdByte = 0x80 | ((Rune & 0xFC0) >> 6);
586  uint8_t FourthByte = 0x80 | (Rune & 0x3F);
587  Out.push_back(FirstByte);
588  Out.push_back(SecondByte);
589  Out.push_back(ThirdByte);
590  Out.push_back(FourthByte);
591  } else {
592  llvm_unreachable("Invalid codepoint");
593  }
594 }
595 
596 // Parse a UTF-16 \uNNNN escape sequence. "\u" has already been consumed.
597 // May parse several sequential escapes to ensure proper surrogate handling.
598 // We do not use ConvertUTF.h, it can't accept and replace unpaired surrogates.
599 // These are invalid Unicode but valid JSON (RFC 8259, section 8.2).
600 bool Parser::parseUnicode(std::string &Out) {
601  // Invalid UTF is not a JSON error (RFC 8529ยง8.2). It gets replaced by U+FFFD.
602  auto Invalid = [&] { Out.append(/* UTF-8 */ {'\xef', '\xbf', '\xbd'}); };
603  // Decodes 4 hex digits from the stream into Out, returns false on error.
604  auto Parse4Hex = [this](uint16_t &Out) -> bool {
605  Out = 0;
606  char Bytes[] = {next(), next(), next(), next()};
607  for (unsigned char C : Bytes) {
608  if (!std::isxdigit(C))
609  return parseError("Invalid \\u escape sequence");
610  Out <<= 4;
611  Out |= (C > '9') ? (C & ~0x20) - 'A' + 10 : (C - '0');
612  }
613  return true;
614  };
615  uint16_t First; // UTF-16 code unit from the first \u escape.
616  if (!Parse4Hex(First))
617  return false;
618 
619  // We loop to allow proper surrogate-pair error handling.
620  while (true) {
621  // Case 1: the UTF-16 code unit is already a codepoint in the BMP.
622  if (LLVM_LIKELY(First < 0xD800 || First >= 0xE000)) {
623  encodeUtf8(First, Out);
624  return true;
625  }
626 
627  // Case 2: it's an (unpaired) trailing surrogate.
628  if (LLVM_UNLIKELY(First >= 0xDC00)) {
629  Invalid();
630  return true;
631  }
632 
633  // Case 3: it's a leading surrogate. We expect a trailing one next.
634  // Case 3a: there's no trailing \u escape. Don't advance in the stream.
635  if (LLVM_UNLIKELY(P + 2 > End || *P != '\\' || *(P + 1) != 'u')) {
636  Invalid(); // Leading surrogate was unpaired.
637  return true;
638  }
639  P += 2;
640  uint16_t Second;
641  if (!Parse4Hex(Second))
642  return false;
643  // Case 3b: there was another \u escape, but it wasn't a trailing surrogate.
644  if (LLVM_UNLIKELY(Second < 0xDC00 || Second >= 0xE000)) {
645  Invalid(); // Leading surrogate was unpaired.
646  First = Second; // Second escape still needs to be processed.
647  continue;
648  }
649  // Case 3c: a valid surrogate pair encoding an astral codepoint.
650  encodeUtf8(0x10000 | ((First - 0xD800) << 10) | (Second - 0xDC00), Out);
651  return true;
652  }
653 }
654 
655 bool Parser::parseError(const char *Msg) {
656  int Line = 1;
657  const char *StartOfLine = Start;
658  for (const char *X = Start; X < P; ++X) {
659  if (*X == 0x0A) {
660  ++Line;
661  StartOfLine = X + 1;
662  }
663  }
664  Err.emplace(
665  std::make_unique<ParseError>(Msg, Line, P - StartOfLine, P - Start));
666  return false;
667 }
668 } // namespace
669 
671  Parser P(JSON);
672  Value E = nullptr;
673  if (P.checkUTF8())
674  if (P.parseValue(E))
675  if (P.assertEnd())
676  return std::move(E);
677  return P.takeError();
678 }
679 char ParseError::ID = 0;
680 
681 bool isUTF8(llvm::StringRef S, size_t *ErrOffset) {
682  // Fast-path for ASCII, which is valid UTF-8.
683  if (LLVM_LIKELY(isASCII(S)))
684  return true;
685 
686  const UTF8 *Data = reinterpret_cast<const UTF8 *>(S.data()), *Rest = Data;
687  if (LLVM_LIKELY(isLegalUTF8String(&Rest, Data + S.size())))
688  return true;
689 
690  if (ErrOffset)
691  *ErrOffset = Rest - Data;
692  return false;
693 }
694 
695 std::string fixUTF8(llvm::StringRef S) {
696  // This isn't particularly efficient, but is only for error-recovery.
697  std::vector<UTF32> Codepoints(S.size()); // 1 codepoint per byte suffices.
698  const UTF8 *In8 = reinterpret_cast<const UTF8 *>(S.data());
699  UTF32 *Out32 = Codepoints.data();
700  ConvertUTF8toUTF32(&In8, In8 + S.size(), &Out32, Out32 + Codepoints.size(),
702  Codepoints.resize(Out32 - Codepoints.data());
703  std::string Res(4 * Codepoints.size(), 0); // 4 bytes per codepoint suffice
704  const UTF32 *In32 = Codepoints.data();
705  UTF8 *Out8 = reinterpret_cast<UTF8 *>(&Res[0]);
706  ConvertUTF32toUTF8(&In32, In32 + Codepoints.size(), &Out8, Out8 + Res.size(),
708  Res.resize(reinterpret_cast<char *>(Out8) - Res.data());
709  return Res;
710 }
711 
713  OS << '\"';
714  for (unsigned char C : S) {
715  if (C == 0x22 || C == 0x5C)
716  OS << '\\';
717  if (C >= 0x20) {
718  OS << C;
719  continue;
720  }
721  OS << '\\';
722  switch (C) {
723  // A few characters are common enough to make short escapes worthwhile.
724  case '\t':
725  OS << 't';
726  break;
727  case '\n':
728  OS << 'n';
729  break;
730  case '\r':
731  OS << 'r';
732  break;
733  default:
734  OS << 'u';
736  break;
737  }
738  }
739  OS << '\"';
740 }
741 
743  switch (V.kind()) {
744  case Value::Null:
745  valueBegin();
746  OS << "null";
747  return;
748  case Value::Boolean:
749  valueBegin();
750  OS << (*V.getAsBoolean() ? "true" : "false");
751  return;
752  case Value::Number:
753  valueBegin();
754  if (V.Type == Value::T_Integer)
755  OS << *V.getAsInteger();
756  else if (V.Type == Value::T_UINT64)
757  OS << *V.getAsUINT64();
758  else
759  OS << format("%.*g", std::numeric_limits<double>::max_digits10,
760  *V.getAsNumber());
761  return;
762  case Value::String:
763  valueBegin();
764  quote(OS, *V.getAsString());
765  return;
766  case Value::Array:
767  return array([&] {
768  for (const Value &E : *V.getAsArray())
769  value(E);
770  });
771  case Value::Object:
772  return object([&] {
773  for (const Object::value_type *E : sortedElements(*V.getAsObject()))
774  attribute(E->first, E->second);
775  });
776  }
777 }
778 
779 void llvm::json::OStream::valueBegin() {
780  assert(Stack.back().Ctx != Object && "Only attributes allowed here");
781  if (Stack.back().HasValue) {
782  assert(Stack.back().Ctx != Singleton && "Only one value allowed here");
783  OS << ',';
784  }
785  if (Stack.back().Ctx == Array)
786  newline();
787  flushComment();
788  Stack.back().HasValue = true;
789 }
790 
792  assert(PendingComment.empty() && "Only one comment per value!");
793  PendingComment = Comment;
794 }
795 
796 void OStream::flushComment() {
797  if (PendingComment.empty())
798  return;
799  OS << (IndentSize ? "/* " : "/*");
800  // Be sure not to accidentally emit "*/". Transform to "* /".
801  while (!PendingComment.empty()) {
802  auto Pos = PendingComment.find("*/");
803  if (Pos == StringRef::npos) {
804  OS << PendingComment;
805  PendingComment = "";
806  } else {
807  OS << PendingComment.take_front(Pos) << "* /";
808  PendingComment = PendingComment.drop_front(Pos + 2);
809  }
810  }
811  OS << (IndentSize ? " */" : "*/");
812  // Comments are on their own line unless attached to an attribute value.
813  if (Stack.size() > 1 && Stack.back().Ctx == Singleton) {
814  if (IndentSize)
815  OS << ' ';
816  } else {
817  newline();
818  }
819 }
820 
821 void llvm::json::OStream::newline() {
822  if (IndentSize) {
823  OS.write('\n');
824  OS.indent(Indent);
825  }
826 }
827 
829  valueBegin();
830  Stack.emplace_back();
831  Stack.back().Ctx = Array;
832  Indent += IndentSize;
833  OS << '[';
834 }
835 
837  assert(Stack.back().Ctx == Array);
838  Indent -= IndentSize;
839  if (Stack.back().HasValue)
840  newline();
841  OS << ']';
842  assert(PendingComment.empty());
843  Stack.pop_back();
844  assert(!Stack.empty());
845 }
846 
848  valueBegin();
849  Stack.emplace_back();
850  Stack.back().Ctx = Object;
851  Indent += IndentSize;
852  OS << '{';
853 }
854 
856  assert(Stack.back().Ctx == Object);
857  Indent -= IndentSize;
858  if (Stack.back().HasValue)
859  newline();
860  OS << '}';
861  assert(PendingComment.empty());
862  Stack.pop_back();
863  assert(!Stack.empty());
864 }
865 
867  assert(Stack.back().Ctx == Object);
868  if (Stack.back().HasValue)
869  OS << ',';
870  newline();
871  flushComment();
872  Stack.back().HasValue = true;
873  Stack.emplace_back();
874  Stack.back().Ctx = Singleton;
875  if (LLVM_LIKELY(isUTF8(Key))) {
876  quote(OS, Key);
877  } else {
878  assert(false && "Invalid UTF-8 in attribute key");
879  quote(OS, fixUTF8(Key));
880  }
881  OS.write(':');
882  if (IndentSize)
883  OS.write(' ');
884 }
885 
887  assert(Stack.back().Ctx == Singleton);
888  assert(Stack.back().HasValue && "Attribute must have a value");
889  assert(PendingComment.empty());
890  Stack.pop_back();
891  assert(Stack.back().Ctx == Object);
892 }
893 
895  valueBegin();
896  Stack.emplace_back();
897  Stack.back().Ctx = RawValue;
898  return OS;
899 }
900 
902  assert(Stack.back().Ctx == RawValue);
903  Stack.pop_back();
904 }
905 
906 } // namespace json
907 } // namespace llvm
908 
911  unsigned IndentAmount = 0;
912  if (!Options.empty() && Options.getAsInteger(/*Radix=*/10, IndentAmount))
913  llvm_unreachable("json::Value format options should be an integer");
914  json::OStream(OS, IndentAmount).value(E);
915 }
916 
llvm::json::OStream::comment
void comment(llvm::StringRef)
Emit a JavaScript comment associated with the next printed value.
Definition: JSON.cpp:791
llvm::json::OStream::attributeBegin
void attributeBegin(llvm::StringRef Key)
Definition: JSON.cpp:866
llvm::json::Path::Root
The root is the trivial Path to the root value.
Definition: JSON.h:643
llvm::json::Value
A Value is an JSON value of unknown type.
Definition: JSON.h:289
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::json::Value::kind
Kind kind() const
Definition: JSON.h:388
llvm::json::Value::Boolean
@ Boolean
Definition: JSON.h:293
llvm::json::Value::Object
friend class Object
Definition: JSON.h:480
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::json::OStream::attributeEnd
void attributeEnd()
Definition: JSON.cpp:886
llvm::json::quote
static void quote(llvm::raw_ostream &OS, llvm::StringRef S)
Definition: JSON.cpp:712
llvm::json::Array::emplace_back
void emplace_back(Args &&... A)
Definition: JSON.h:192
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:631
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:59
llvm::StringRef::find
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:314
Error.h
llvm::MachO::Invalid
@ Invalid
Invalid file type.
Definition: InterfaceFile.h:59
llvm::json::Value::getAsNull
llvm::Optional< std::nullptr_t > getAsNull() const
Definition: JSON.h:410
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:414
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:236
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:227
llvm::json::Path::Root::printErrorContext
void printErrorContext(const Value &, llvm::raw_ostream &) const
Print the root value with the error shown inline as a comment.
Definition: JSON.cpp:307
llvm::Optional
Definition: APInt.h:33
llvm::json::Value::Null
@ Null
Definition: JSON.h:292
llvm::msgpack::Type::Array
@ Array
llvm::json::Value::getAsNumber
llvm::Optional< double > getAsNumber() const
Definition: JSON.h:420
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
STLExtras.h
RHS
Value * RHS
Definition: X86PartialReduction.cpp:74
Format.h
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::detail::DenseMapPair< ObjectKey, Value >
llvm::json::Path::report
void report(llvm::StringLiteral Message)
Records that the value at the current path is invalid.
Definition: JSON.cpp:207
peek
static bool peek(struct InternalInstruction *insn, uint8_t &byte)
Definition: X86Disassembler.cpp:184
llvm::json::operator==
bool operator==(const Object &LHS, const Object &RHS)
Definition: JSON.cpp:83
LHS
Value * LHS
Definition: X86PartialReduction.cpp:73
llvm::ConvertUTF32toUTF8
ConversionResult ConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)
Definition: ConvertUTF.cpp:317
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:890
llvm::json::Object::getString
llvm::Optional< llvm::StringRef > getString(StringRef K) const
Definition: JSON.cpp:58
llvm::json::Value::Value
Value(const Value &M)
Definition: JSON.h:303
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::json::OStream::object
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
Definition: JSON.h:950
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
llvm::json::OStream::array
void array(Block Contents)
Emit an array whose elements are emitted in the provided Block.
Definition: JSON.h:944
llvm::json::Object::getObject
const json::Object * getObject(StringRef K) const
Definition: JSON.cpp:63
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:481
First
into llvm powi allowing the code generator to produce balanced multiplication trees First
Definition: README.txt:54
llvm::json::Value::Number
@ Number
Number values can store both int64s and doubles at full precision, depending on what they were constr...
Definition: JSON.h:296
llvm::json::Value::Array
friend class Array
Definition: JSON.h:479
llvm::json::Array
An Array is a JSON array, which contains heterogeneous JSON values.
Definition: JSON.h:156
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
JSON.h
llvm::json::parse
llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
Definition: JSON.cpp:670
llvm::json::Object::try_emplace
std::pair< iterator, bool > try_emplace(const ObjectKey &K, Ts &&... Args)
Definition: JSON.h:118
llvm::None
const NoneType None
Definition: None.h:23
llvm::json::OStream::objectEnd
void objectEnd()
Definition: JSON.cpp:855
llvm::lenientConversion
@ lenientConversion
Definition: ConvertUTF.h:135
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::StringRef::equals
LLVM_NODISCARD bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:186
llvm::json::Object::getNumber
llvm::Optional< double > getNumber(StringRef K) const
Definition: JSON.cpp:48
llvm::OutputFileType::Object
@ Object
llvm::json::Object::find
iterator find(StringRef K)
Definition: JSON.h:128
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:206
llvm::json::Value::getAsArray
const json::Array * getAsArray() const
Definition: JSON.h:465
llvm::json::OStream::rawValueEnd
void rawValueEnd()
Definition: JSON.cpp:901
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::json::OStream
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
Definition: JSON.h:920
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:152
llvm::json::Object::get
Value * get(StringRef K)
Definition: JSON.cpp:26
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::json::OStream::arrayBegin
void arrayBegin()
Definition: JSON.cpp:828
llvm::json::Object::operator[]
Value & operator[](const ObjectKey &K)
Definition: JSON.cpp:20
llvm::json::Value::getAsInteger
llvm::Optional< int64_t > getAsInteger() const
Definition: JSON.h:430
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::pdb::PDB_MemoryType::Stack
@ Stack
llvm::json::Array::back
Value & back()
Definition: JSON.h:175
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::json::fixUTF8
std::string fixUTF8(llvm::StringRef S)
Replaces invalid UTF-8 sequences in S with the replacement character (U+FFFD).
Definition: JSON.cpp:695
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::json::Array::Array
Array()=default
llvm::ConvertUTF8toUTF32
ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)
Convert a partial UTF8 sequence to UTF32.
Definition: ConvertUTF.cpp:710
llvm::write_hex
void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, Optional< size_t > Width=None)
Definition: NativeFormatting.cpp:133
llvm::json::Value::getAsBoolean
llvm::Optional< bool > getAsBoolean() const
Definition: JSON.h:415
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::json::Value::getAsUINT64
llvm::Optional< uint64_t > getAsUINT64() const
Definition: JSON.h:442
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::json::Object::getInteger
llvm::Optional< int64_t > getInteger(StringRef K) const
Definition: JSON.cpp:53
llvm::json::Object::end
iterator end()
Definition: JSON.h:109
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
if
if(llvm_vc STREQUAL "") set(fake_version_inc "$
Definition: CMakeLists.txt:14
llvm::strictConversion
@ strictConversion
Definition: ConvertUTF.h:134
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::json::ParseError::ID
static char ID
Definition: JSON.h:841
ConvertUTF.h
llvm::json::Path::Root::getError
Error getError() const
Returns the last error reported, or else a generic error.
Definition: JSON.cpp:222
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1241
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
llvm::json::Value::getAsObject
const json::Object * getAsObject() const
Definition: JSON.h:459
uint16_t
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::HexPrintStyle::Lower
@ Lower
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1590
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::json::OStream::value
void value(const Value &V)
Emit a self-contained value (number, string, vector<string> etc).
Definition: JSON.cpp:742
llvm::json::Object::getArray
const json::Array * getArray(StringRef K) const
Definition: JSON.cpp:73
llvm::isLegalUTF8String
Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd)
Definition: ConvertUTF.cpp:529
llvm::json::Value::String
@ String
Definition: JSON.h:297
llvm::json::Path::Path
Path(Root &R)
The root may be treated as a Path.
Definition: JSON.h:606
llvm::UTF32
unsigned int UTF32
Definition: ConvertUTF.h:109
llvm::json::OStream::arrayEnd
void arrayEnd()
Definition: JSON.cpp:836
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
LLVM_LIKELY
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:229
llvm::json::isUTF8
bool isUTF8(llvm::StringRef S, size_t *ErrOffset=nullptr)
Returns true if S is valid UTF-8, which is required for use as JSON.
Definition: JSON.cpp:681
llvm::json::ObjectKey
ObjectKey is a used to capture keys in Object.
Definition: JSON.h:521
LLVM_UNLIKELY
#define LLVM_UNLIKELY(EXPR)
Definition: Compiler.h:230
raw_ostream.h
llvm::json::Object
An Object is a JSON object, which maps strings to heterogenous JSON values.
Definition: JSON.h:90
llvm::json::Value::getAsString
llvm::Optional< llvm::StringRef > getAsString() const
Definition: JSON.h:452
llvm::raw_string_ostream::str
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:649
llvm::json::OStream::rawValueBegin
raw_ostream & rawValueBegin()
Definition: JSON.cpp:894
llvm::json::Object::getBoolean
llvm::Optional< bool > getBoolean(StringRef K) const
Definition: JSON.cpp:43
llvm::json::OStream::objectBegin
void objectBegin()
Definition: JSON.cpp:847
llvm::json::Path
A "cursor" marking a position within a Value.
Definition: JSON.h:596
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::UTF8
unsigned char UTF8
Definition: ConvertUTF.h:111
llvm::json::Object::getNull
llvm::Optional< std::nullptr_t > getNull(StringRef K) const
Definition: JSON.cpp:38