28 return try_emplace(std::move(K),
nullptr).first->getSecond();
44 return V->getAsNull();
49 return V->getAsBoolean();
54 return V->getAsNumber();
59 return V->getAsInteger();
64 return V->getAsString();
69 return V->getAsObject();
74 return V->getAsObject();
79 return V->getAsArray();
84 return V->getAsArray();
90 V.reserve(Elements.size());
91 for (
const Value &V : Elements) {
93 back().moveFrom(std::move(V));
100void Value::copyFrom(
const Value &M) {
108 memcpy(&Union, &M.Union,
sizeof(Union));
114 create<std::string>(M.as<std::string>());
125void Value::moveFrom(
const Value &&M) {
133 memcpy(&Union, &M.Union,
sizeof(Union));
136 create<StringRef>(M.as<StringRef>());
139 create<std::string>(std::move(M.as<std::string>()));
143 create<json::Object>(std::move(M.as<json::Object>()));
147 create<json::Array>(std::move(M.as<json::Array>()));
153void Value::destroy() {
162 as<StringRef>().~StringRef();
165 as<std::string>().~basic_string();
168 as<json::Object>().~Object();
171 as<json::Array>().~Array();
178#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
186 if (L.kind() != R.kind())
190 return *L.getAsNull() == *R.getAsNull();
192 return *L.getAsBoolean() == *R.getAsBoolean();
198 if (L.Type == Value::T_Integer || R.Type == Value::T_Integer)
199 return L.getAsInteger() == R.getAsInteger();
200 return *L.getAsNumber() == *R.getAsNumber();
202 return *L.getAsString() == *R.getAsString();
204 return *L.getAsArray() == *R.getAsArray();
206 return *L.getAsObject() == *R.getAsObject();
215 for (
P =
this;
P->Parent !=
nullptr;
P =
P->Parent)
219 R->ErrorMessage = Msg;
220 R->ErrorPath.resize(
Count);
221 auto It = R->ErrorPath.begin();
222 for (
P =
this;
P->Parent !=
nullptr;
P =
P->Parent)
229 OS << (ErrorMessage.empty() ?
"invalid JSON contents" : ErrorMessage);
230 if (ErrorPath.empty()) {
232 OS <<
" when parsing " << Name;
234 OS <<
" at " << (Name.empty() ?
"(root)" : Name);
237 OS <<
'.' << S.field();
239 OS <<
'[' << S.index() <<
']';
246 std::vector<const Object::value_type *> Elements;
247 for (
const auto &
E : O)
248 Elements.push_back(&
E);
251 return L->first < R->first;
262 JOS.
rawValue(V.getAsArray()->empty() ?
"[]" :
"[ ... ]");
265 JOS.
rawValue(V.getAsObject()->empty() ?
"{}" :
"{ ... }");
273 Truncated.append(
"...");
274 JOS.
value(Truncated);
289 for (
const auto &
I : *V.getAsArray())
317 auto HighlightCurrent = [&] {
318 std::string Comment =
"error: ";
319 Comment.append(ErrorMessage.data(), ErrorMessage.size());
324 return HighlightCurrent();
325 const Segment &S =
Path.back();
329 const Object *O = V.getAsObject();
330 if (!O || !O->get(FieldName))
331 return HighlightCurrent();
336 Recurse(KV->second,
Path.drop_back(), Recurse);
344 const Array *
A = V.getAsArray();
345 if (!
A || S.index() >=
A->size())
346 return HighlightCurrent();
348 unsigned Current = 0;
349 for (
const auto &V : *
A) {
350 if (Current++ == S.index())
351 Recurse(V,
Path.drop_back(), Recurse);
358 PrintValue(R, ErrorPath, PrintValue);
366 : Start(JSON.begin()),
P(JSON.begin()), End(JSON.end()) {}
372 P = Start + ErrOffset;
373 return parseError(
"Invalid UTF-8 sequence");
376 bool parseValue(
Value &Out);
382 return parseError(
"Text after end of document");
387 return std::move(*Err);
391 void eatWhitespace() {
392 while (
P != End && (*
P ==
' ' || *
P ==
'\r' || *
P ==
'\n' || *
P ==
'\t'))
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);
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 ==
'.';
410 std::optional<Error> Err;
411 const char *
Start, *
P, *End;
415bool Parser::parseValue(
Value &Out) {
418 return parseError(
"Unexpected EOF");
419 switch (
char C = next()) {
423 return (next() ==
'u' && next() ==
'l' && next() ==
'l') ||
424 parseError(
"Invalid JSON value (null?)");
427 return (next() ==
'r' && next() ==
'u' && next() ==
'e') ||
428 parseError(
"Invalid JSON value (true?)");
431 return (next() ==
'a' && next() ==
'l' && next() ==
's' && next() ==
'e') ||
432 parseError(
"Invalid JSON value (false?)");
435 if (parseString(S)) {
443 Array &
A = *Out.getAsArray();
450 A.emplace_back(
nullptr);
451 if (!parseValue(
A.back()))
461 return parseError(
"Expected , or ] after array element");
467 Object &
O = *Out.getAsObject();
475 return parseError(
"Expected object key");
481 return parseError(
"Expected : after object key");
483 if (!parseValue(O[std::move(K)]))
493 return parseError(
"Expected , or } after object property");
499 return parseNumber(
C, Out);
500 return parseError(
"Invalid JSON value");
504bool Parser::parseNumber(
char First,
Value &Out) {
508 while (isNumber(
peek()))
515 int64_t
I = std::strtoll(S.c_str(), &End, 10);
516 if (End == S.end() && errno != ERANGE) {
525 uint64_t UI = std::strtoull(S.c_str(), &End, 10);
526 if (End == S.end() && errno != ERANGE) {
532 Out = std::strtod(S.c_str(), &End);
533 return End == S.end() || parseError(
"Invalid JSON value (number?)");
536bool Parser::parseString(std::string &Out) {
538 for (
char C = next();
C !=
'"';
C = next()) {
540 return parseError(
"Unterminated string");
542 return parseError(
"Control character in string");
548 switch (
C = next()) {
570 if (!parseUnicode(Out))
574 return parseError(
"Invalid escape sequence");
582 Out.push_back(Rune & 0x7F);
583 }
else if (Rune < 0x800) {
584 uint8_t FirstByte = 0xC0 | ((Rune & 0x7C0) >> 6);
585 uint8_t SecondByte = 0x80 | (Rune & 0x3F);
586 Out.push_back(FirstByte);
587 Out.push_back(SecondByte);
588 }
else if (Rune < 0x10000) {
589 uint8_t FirstByte = 0xE0 | ((Rune & 0xF000) >> 12);
590 uint8_t SecondByte = 0x80 | ((Rune & 0xFC0) >> 6);
591 uint8_t ThirdByte = 0x80 | (Rune & 0x3F);
592 Out.push_back(FirstByte);
593 Out.push_back(SecondByte);
594 Out.push_back(ThirdByte);
595 }
else if (Rune < 0x110000) {
596 uint8_t FirstByte = 0xF0 | ((Rune & 0x1F0000) >> 18);
597 uint8_t SecondByte = 0x80 | ((Rune & 0x3F000) >> 12);
598 uint8_t ThirdByte = 0x80 | ((Rune & 0xFC0) >> 6);
599 uint8_t FourthByte = 0x80 | (Rune & 0x3F);
600 Out.push_back(FirstByte);
601 Out.push_back(SecondByte);
602 Out.push_back(ThirdByte);
603 Out.push_back(FourthByte);
613bool Parser::parseUnicode(std::string &Out) {
615 auto Invalid = [&] { Out.append( {
'\xef',
'\xbf',
'\xbd'}); };
617 auto Parse4Hex = [
this](uint16_t &Out) ->
bool {
619 char Bytes[] = {next(), next(), next(), next()};
620 for (
unsigned char C : Bytes) {
621 if (!std::isxdigit(
C))
622 return parseError(
"Invalid \\u escape sequence");
624 Out |= (
C >
'9') ? (
C & ~0x20) -
'A' + 10 : (
C -
'0');
629 if (!Parse4Hex(
First))
654 if (!Parse4Hex(Second))
663 encodeUtf8(0x10000 | ((
First - 0xD800) << 10) | (Second - 0xDC00), Out);
668bool Parser::parseError(
const char *Msg) {
670 const char *StartOfLine =
Start;
671 for (
const char *
X = Start;
X <
P; ++
X) {
678 std::make_unique<ParseError>(Msg, Line,
P - StartOfLine,
P - Start));
689 return P.takeError();
696 OS <<
llvm::formatv(
"[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
709 *ErrOffset = Rest -
Data;
715 std::vector<UTF32> Codepoints(S.
size());
716 const UTF8 *In8 =
reinterpret_cast<const UTF8 *
>(S.
data());
717 UTF32 *Out32 = Codepoints.data();
720 Codepoints.resize(Out32 - Codepoints.data());
721 std::string Res(4 * Codepoints.size(), 0);
722 const UTF32 *In32 = Codepoints.data();
723 UTF8 *Out8 =
reinterpret_cast<UTF8 *
>(&Res[0]);
726 Res.resize(
reinterpret_cast<char *
>(Out8) - Res.data());
732 for (
unsigned char C : S) {
733 if (
C == 0x22 ||
C == 0x5C)
768 OS << (*V.getAsBoolean() ?
"true" :
"false");
772 if (V.Type == Value::T_Integer)
773 OS << *V.getAsInteger();
774 else if (V.Type == Value::T_UINT64)
775 OS << *V.getAsUINT64();
777 OS <<
format(
"%.*g", std::numeric_limits<double>::max_digits10,
782 quote(OS, *V.getAsString());
786 for (
const Value &
E : *V.getAsArray())
797void llvm::json::OStream::valueBegin() {
798 assert(Stack.back().Ctx !=
Object &&
"Only attributes allowed here");
799 if (Stack.back().HasValue) {
800 assert(Stack.back().Ctx != Singleton &&
"Only one value allowed here");
803 if (Stack.back().Ctx == Array)
806 Stack.back().HasValue =
true;
810 assert(PendingComment.empty() &&
"Only one comment per value!");
811 PendingComment = Comment;
814void OStream::flushComment() {
815 if (PendingComment.empty())
817 OS << (IndentSize ?
"/* " :
"/*");
819 while (!PendingComment.empty()) {
820 auto Pos = PendingComment.find(
"*/");
822 OS << PendingComment;
825 OS << PendingComment.take_front(Pos) <<
"* /";
826 PendingComment = PendingComment.drop_front(Pos + 2);
829 OS << (IndentSize ?
" */" :
"*/");
831 if (
Stack.size() > 1 &&
Stack.back().Ctx == Singleton) {
839void llvm::json::OStream::newline() {
848 Stack.emplace_back();
849 Stack.back().Ctx = Array;
850 Indent += IndentSize;
855 assert(Stack.back().Ctx == Array);
856 Indent -= IndentSize;
857 if (Stack.back().HasValue)
860 assert(PendingComment.empty());
867 Stack.emplace_back();
868 Stack.back().Ctx = Object;
869 Indent += IndentSize;
874 assert(Stack.back().Ctx == Object);
875 Indent -= IndentSize;
876 if (Stack.back().HasValue)
879 assert(PendingComment.empty());
885 assert(Stack.back().Ctx == Object);
886 if (Stack.back().HasValue)
890 Stack.back().HasValue =
true;
891 Stack.emplace_back();
892 Stack.back().Ctx = Singleton;
896 assert(
false &&
"Invalid UTF-8 in attribute key");
905 assert(Stack.back().Ctx == Singleton);
906 assert(Stack.back().HasValue &&
"Attribute must have a value");
907 assert(PendingComment.empty());
909 assert(Stack.back().Ctx == Object);
914 Stack.emplace_back();
915 Stack.back().Ctx = RawValue;
920 assert(Stack.back().Ctx == RawValue);
929 unsigned IndentAmount = 0;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
#define LLVM_LIKELY(EXPR)
This file supports working with JSON data.
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static bool peek(struct InternalInstruction *insn, uint8_t &byte)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
static constexpr size_t npos
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
The instances of the Type class are immutable: once they are created, they are never changed.
Type(LLVMContext &C, TypeID tid)
LLVM Value Representation.
An Array is a JSON array, which contains heterogeneous JSON values.
void emplace_back(Args &&...A)
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
void rawValue(llvm::function_ref< void(raw_ostream &)> Contents)
Emit an externally-serialized value.
LLVM_ABI void attributeBegin(llvm::StringRef Key)
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
LLVM_ABI void arrayBegin()
LLVM_ABI void objectBegin()
LLVM_ABI raw_ostream & rawValueBegin()
LLVM_ABI void comment(llvm::StringRef)
Emit a JavaScript comment associated with the next printed value.
void array(Block Contents)
Emit an array whose elements are emitted in the provided Block.
LLVM_ABI void attributeEnd()
LLVM_ABI void value(const Value &V)
Emit a self-contained value (number, string, vector<string> etc).
LLVM_ABI void rawValueEnd()
LLVM_ABI void objectEnd()
ObjectKey is a used to capture keys in Object.
An Object is a JSON object, which maps strings to heterogenous JSON values.
LLVM_ABI std::optional< bool > getBoolean(StringRef K) const
LLVM_ABI Value & operator[](const ObjectKey &K)
LLVM_ABI std::optional< double > getNumber(StringRef K) const
LLVM_ABI const json::Object * getObject(StringRef K) const
LLVM_ABI std::optional< llvm::StringRef > getString(StringRef K) const
Storage::value_type value_type
LLVM_ABI Value * get(StringRef K)
LLVM_ABI std::optional< int64_t > getInteger(StringRef K) const
LLVM_ABI std::optional< std::nullptr_t > getNull(StringRef K) const
std::pair< iterator, bool > try_emplace(const ObjectKey &K, Ts &&... Args)
iterator find(StringRef K)
LLVM_ABI const json::Array * getArray(StringRef K) const
void log(llvm::raw_ostream &OS) const override
Print an error message to an output stream.
The root is the trivial Path to the root value.
LLVM_ABI void printErrorContext(const Value &, llvm::raw_ostream &) const
Print the root value with the error shown inline as a comment.
LLVM_ABI Error getError() const
Returns the last error reported, or else a generic error.
LLVM_ABI void report(llvm::StringLiteral Message)
Records that the value at the current path is invalid.
Path(Root &R)
The root may be treated as a Path.
A Value is an JSON value of unknown type.
LLVM_ABI void print(llvm::raw_ostream &OS) const
LLVM_DUMP_METHOD void dump() const
@ Number
Number values can store both int64s and doubles at full precision, depending on what they were constr...
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
static void abbreviateChildren(const Value &V, OStream &JOS)
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
static void abbreviate(const Value &V, OStream &JOS)
LLVM_ABI bool operator==(const Object &LHS, const Object &RHS)
LLVM_ABI bool isUTF8(llvm::StringRef S, size_t *ErrOffset=nullptr)
Returns true if S is valid UTF-8, which is required for use as JSON.
LLVM_ABI std::vector< const Object::value_type * > sortedElements(const Object &O)
static void quote(llvm::raw_ostream &OS, llvm::StringRef S)
LLVM_ABI std::string fixUTF8(llvm::StringRef S)
Replaces invalid UTF-8 sequences in S with the replacement character (U+FFFD).
static void encodeUtf8(uint32_t Rune, std::string &Out)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)
Convert a partial UTF8 sequence to UTF32.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
LLVM_ABI void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, std::optional< size_t > Width=std::nullopt)
LLVM_ABI ConversionResult ConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)
bool isASCII(char C)
Checks whether character C is valid ASCII (high bit is zero).
LLVM_ABI Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd)