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();
179 if (L.kind() != R.kind())
183 return *L.getAsNull() == *R.getAsNull();
185 return *L.getAsBoolean() == *R.getAsBoolean();
191 if (L.Type == Value::T_Integer || R.Type == Value::T_Integer)
192 return L.getAsInteger() == R.getAsInteger();
193 return *L.getAsNumber() == *R.getAsNumber();
195 return *L.getAsString() == *R.getAsString();
197 return *L.getAsArray() == *R.getAsArray();
199 return *L.getAsObject() == *R.getAsObject();
208 for (
P =
this;
P->Parent !=
nullptr;
P =
P->Parent)
212 R->ErrorMessage = Msg;
213 R->ErrorPath.resize(
Count);
214 auto It = R->ErrorPath.begin();
215 for (
P =
this;
P->Parent !=
nullptr;
P =
P->Parent)
222 OS << (ErrorMessage.empty() ?
"invalid JSON contents" : ErrorMessage);
223 if (ErrorPath.empty()) {
225 OS <<
" when parsing " << Name;
227 OS <<
" at " << (Name.empty() ?
"(root)" : Name);
230 OS <<
'.' << S.field();
232 OS <<
'[' << S.index() <<
']';
239 std::vector<const Object::value_type *> Elements;
240 for (
const auto &
E : O)
241 Elements.push_back(&
E);
244 return L->first < R->first;
255 JOS.
rawValue(V.getAsArray()->empty() ?
"[]" :
"[ ... ]");
258 JOS.
rawValue(V.getAsObject()->empty() ?
"{}" :
"{ ... }");
266 Truncated.append(
"...");
267 JOS.
value(Truncated);
282 for (
const auto &
I : *V.getAsArray())
310 auto HighlightCurrent = [&] {
311 std::string Comment =
"error: ";
312 Comment.append(ErrorMessage.data(), ErrorMessage.size());
317 return HighlightCurrent();
318 const Segment &S =
Path.back();
322 const Object *O = V.getAsObject();
323 if (!O || !O->get(FieldName))
324 return HighlightCurrent();
329 Recurse(KV->second,
Path.drop_back(), Recurse);
337 const Array *
A = V.getAsArray();
338 if (!
A || S.index() >=
A->size())
339 return HighlightCurrent();
341 unsigned Current = 0;
342 for (
const auto &V : *
A) {
343 if (Current++ == S.index())
344 Recurse(V,
Path.drop_back(), Recurse);
351 PrintValue(R, ErrorPath, PrintValue);
359 : Start(JSON.begin()),
P(JSON.begin()), End(JSON.end()) {}
365 P = Start + ErrOffset;
366 return parseError(
"Invalid UTF-8 sequence");
369 bool parseValue(
Value &Out);
375 return parseError(
"Text after end of document");
380 return std::move(*Err);
384 void eatWhitespace() {
385 while (
P != End && (*
P ==
' ' || *
P ==
'\r' || *
P ==
'\n' || *
P ==
'\t'))
390 bool parseNumber(
char First,
Value &Out);
391 bool parseString(std::string &Out);
392 bool parseUnicode(std::string &Out);
393 bool parseError(
const char *Msg);
395 char next() {
return P == End ? 0 : *
P++; }
396 char peek() {
return P == End ? 0 : *
P; }
397 static bool isNumber(
char C) {
398 return C ==
'0' ||
C ==
'1' ||
C ==
'2' ||
C ==
'3' ||
C ==
'4' ||
399 C ==
'5' ||
C ==
'6' ||
C ==
'7' ||
C ==
'8' ||
C ==
'9' ||
400 C ==
'e' ||
C ==
'E' ||
C ==
'+' ||
C ==
'-' ||
C ==
'.';
403 std::optional<Error> Err;
404 const char *
Start, *
P, *End;
408bool Parser::parseValue(
Value &Out) {
411 return parseError(
"Unexpected EOF");
412 switch (
char C = next()) {
416 return (next() ==
'u' && next() ==
'l' && next() ==
'l') ||
417 parseError(
"Invalid JSON value (null?)");
420 return (next() ==
'r' && next() ==
'u' && next() ==
'e') ||
421 parseError(
"Invalid JSON value (true?)");
424 return (next() ==
'a' && next() ==
'l' && next() ==
's' && next() ==
'e') ||
425 parseError(
"Invalid JSON value (false?)");
428 if (parseString(S)) {
436 Array &
A = *Out.getAsArray();
443 A.emplace_back(
nullptr);
444 if (!parseValue(
A.back()))
454 return parseError(
"Expected , or ] after array element");
460 Object &
O = *Out.getAsObject();
468 return parseError(
"Expected object key");
474 return parseError(
"Expected : after object key");
476 if (!parseValue(O[std::move(K)]))
486 return parseError(
"Expected , or } after object property");
492 return parseNumber(
C, Out);
493 return parseError(
"Invalid JSON value");
497bool Parser::parseNumber(
char First,
Value &Out) {
501 while (isNumber(
peek()))
508 int64_t
I = std::strtoll(S.c_str(), &End, 10);
509 if (End == S.end() && errno != ERANGE) {
518 uint64_t UI = std::strtoull(S.c_str(), &End, 10);
519 if (End == S.end() && errno != ERANGE) {
525 Out = std::strtod(S.c_str(), &End);
526 return End == S.end() || parseError(
"Invalid JSON value (number?)");
529bool Parser::parseString(std::string &Out) {
531 for (
char C = next();
C !=
'"';
C = next()) {
533 return parseError(
"Unterminated string");
535 return parseError(
"Control character in string");
541 switch (
C = next()) {
563 if (!parseUnicode(Out))
567 return parseError(
"Invalid escape sequence");
575 Out.push_back(Rune & 0x7F);
576 }
else if (Rune < 0x800) {
577 uint8_t FirstByte = 0xC0 | ((Rune & 0x7C0) >> 6);
578 uint8_t SecondByte = 0x80 | (Rune & 0x3F);
579 Out.push_back(FirstByte);
580 Out.push_back(SecondByte);
581 }
else if (Rune < 0x10000) {
582 uint8_t FirstByte = 0xE0 | ((Rune & 0xF000) >> 12);
583 uint8_t SecondByte = 0x80 | ((Rune & 0xFC0) >> 6);
584 uint8_t ThirdByte = 0x80 | (Rune & 0x3F);
585 Out.push_back(FirstByte);
586 Out.push_back(SecondByte);
587 Out.push_back(ThirdByte);
588 }
else if (Rune < 0x110000) {
589 uint8_t FirstByte = 0xF0 | ((Rune & 0x1F0000) >> 18);
590 uint8_t SecondByte = 0x80 | ((Rune & 0x3F000) >> 12);
591 uint8_t ThirdByte = 0x80 | ((Rune & 0xFC0) >> 6);
592 uint8_t FourthByte = 0x80 | (Rune & 0x3F);
593 Out.push_back(FirstByte);
594 Out.push_back(SecondByte);
595 Out.push_back(ThirdByte);
596 Out.push_back(FourthByte);
606bool Parser::parseUnicode(std::string &Out) {
608 auto Invalid = [&] { Out.append( {
'\xef',
'\xbf',
'\xbd'}); };
610 auto Parse4Hex = [
this](uint16_t &Out) ->
bool {
612 char Bytes[] = {next(), next(), next(), next()};
613 for (
unsigned char C : Bytes) {
614 if (!std::isxdigit(
C))
615 return parseError(
"Invalid \\u escape sequence");
617 Out |= (
C >
'9') ? (
C & ~0x20) -
'A' + 10 : (
C -
'0');
622 if (!Parse4Hex(
First))
647 if (!Parse4Hex(Second))
656 encodeUtf8(0x10000 | ((
First - 0xD800) << 10) | (Second - 0xDC00), Out);
661bool Parser::parseError(
const char *Msg) {
663 const char *StartOfLine =
Start;
664 for (
const char *
X = Start;
X <
P; ++
X) {
671 std::make_unique<ParseError>(Msg, Line,
P - StartOfLine,
P - Start));
682 return P.takeError();
696 *ErrOffset = Rest -
Data;
702 std::vector<UTF32> Codepoints(S.
size());
703 const UTF8 *In8 =
reinterpret_cast<const UTF8 *
>(S.
data());
704 UTF32 *Out32 = Codepoints.data();
707 Codepoints.resize(Out32 - Codepoints.data());
708 std::string Res(4 * Codepoints.size(), 0);
709 const UTF32 *In32 = Codepoints.data();
710 UTF8 *Out8 =
reinterpret_cast<UTF8 *
>(&Res[0]);
713 Res.resize(
reinterpret_cast<char *
>(Out8) - Res.data());
719 for (
unsigned char C : S) {
720 if (
C == 0x22 ||
C == 0x5C)
755 OS << (*V.getAsBoolean() ?
"true" :
"false");
759 if (V.Type == Value::T_Integer)
760 OS << *V.getAsInteger();
761 else if (V.Type == Value::T_UINT64)
762 OS << *V.getAsUINT64();
764 OS <<
format(
"%.*g", std::numeric_limits<double>::max_digits10,
769 quote(OS, *V.getAsString());
773 for (
const Value &
E : *V.getAsArray())
784void llvm::json::OStream::valueBegin() {
785 assert(Stack.back().Ctx !=
Object &&
"Only attributes allowed here");
786 if (Stack.back().HasValue) {
787 assert(Stack.back().Ctx != Singleton &&
"Only one value allowed here");
790 if (Stack.back().Ctx == Array)
793 Stack.back().HasValue =
true;
797 assert(PendingComment.empty() &&
"Only one comment per value!");
798 PendingComment = Comment;
801void OStream::flushComment() {
802 if (PendingComment.empty())
804 OS << (IndentSize ?
"/* " :
"/*");
806 while (!PendingComment.empty()) {
807 auto Pos = PendingComment.find(
"*/");
809 OS << PendingComment;
812 OS << PendingComment.take_front(Pos) <<
"* /";
813 PendingComment = PendingComment.drop_front(Pos + 2);
816 OS << (IndentSize ?
" */" :
"*/");
818 if (
Stack.size() > 1 &&
Stack.back().Ctx == Singleton) {
826void llvm::json::OStream::newline() {
835 Stack.emplace_back();
836 Stack.back().Ctx = Array;
837 Indent += IndentSize;
842 assert(Stack.back().Ctx == Array);
843 Indent -= IndentSize;
844 if (Stack.back().HasValue)
847 assert(PendingComment.empty());
854 Stack.emplace_back();
855 Stack.back().Ctx = Object;
856 Indent += IndentSize;
861 assert(Stack.back().Ctx == Object);
862 Indent -= IndentSize;
863 if (Stack.back().HasValue)
866 assert(PendingComment.empty());
872 assert(Stack.back().Ctx == Object);
873 if (Stack.back().HasValue)
877 Stack.back().HasValue =
true;
878 Stack.emplace_back();
879 Stack.back().Ctx = Singleton;
883 assert(
false &&
"Invalid UTF-8 in attribute key");
892 assert(Stack.back().Ctx == Singleton);
893 assert(Stack.back().HasValue &&
"Attribute must have a value");
894 assert(PendingComment.empty());
896 assert(Stack.back().Ctx == Object);
901 Stack.emplace_back();
902 Stack.back().Ctx = RawValue;
907 assert(Stack.back().Ctx == RawValue);
916 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_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.
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.
static constexpr size_t npos
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
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
@ 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 reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
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)