Go to the documentation of this file.
41 return V->getAsNull();
46 return V->getAsBoolean();
51 return V->getAsNumber();
56 return V->getAsInteger();
61 return V->getAsString();
66 return V->getAsObject();
71 return V->getAsObject();
76 return V->getAsArray();
81 return V->getAsArray();
85 if (
LHS.size() !=
RHS.size())
87 for (
const auto &L :
LHS) {
88 auto R =
RHS.find(L.first);
89 if (R ==
RHS.end() || L.second != R->second)
96 V.reserve(Elements.size());
97 for (
const Value &V : Elements) {
106 void Value::copyFrom(
const Value &M) {
114 memcpy(&Union, &
M.Union,
sizeof(Union));
120 create<std::string>(
M.as<std::string>());
131 void Value::moveFrom(
const Value &&M) {
139 memcpy(&Union, &
M.Union,
sizeof(Union));
142 create<StringRef>(
M.as<StringRef>());
145 create<std::string>(
std::move(
M.as<std::string>()));
149 create<json::Object>(
std::move(
M.as<json::Object>()));
153 create<json::Array>(
std::move(
M.as<json::Array>()));
159 void Value::destroy() {
168 as<StringRef>().~StringRef();
171 as<std::string>().~basic_string();
174 as<json::Object>().~Object();
177 as<json::Array>().~Array();
183 if (L.
kind() != R.kind())
195 if (L.Type == Value::T_Integer || R.Type == Value::T_Integer)
212 for (
P =
this;
P->Parent !=
nullptr;
P =
P->Parent)
216 R->ErrorMessage =
Msg;
217 R->ErrorPath.resize(Count);
218 auto It = R->ErrorPath.begin();
219 for (
P =
this;
P->Parent !=
nullptr;
P =
P->Parent)
226 OS << (ErrorMessage.
empty() ?
"invalid JSON contents" : ErrorMessage);
227 if (ErrorPath.empty()) {
229 OS <<
" when parsing " << Name;
231 OS <<
" at " << (Name.
empty() ?
"(root)" : Name);
234 OS <<
'.' <<
S.field();
236 OS <<
'[' <<
S.index() <<
']';
244 std::vector<const Object::value_type *> sortedElements(
const Object &
O) {
245 std::vector<const Object::value_type *> Elements;
246 for (
const auto &
E :
O)
247 Elements.push_back(&
E);
250 return L->first < R->first;
258 void abbreviate(
const Value &V, OStream &JOS) {
261 JOS.rawValue(V.getAsArray()->empty() ?
"[]" :
"[ ... ]");
264 JOS.rawValue(V.getAsObject()->empty() ?
"{}" :
"{ ... }");
271 std::string Truncated =
fixUTF8(
S.take_front(37));
272 Truncated.append(
"...");
273 JOS.value(Truncated);
284 void abbreviateChildren(
const Value &V, OStream &JOS) {
288 for (
const auto &
I : *V.getAsArray())
294 for (
const auto *KV : sortedElements(*V.getAsObject())) {
295 JOS.attributeBegin(KV->first);
296 abbreviate(KV->second, JOS);
318 auto HighlightCurrent = [&] {
319 std::string Comment =
"error: ";
320 Comment.append(ErrorMessage.data(), ErrorMessage.size());
322 abbreviateChildren(V, JOS);
325 return HighlightCurrent();
326 const Segment &
S =
Path.back();
331 if (!
O || !
O->get(FieldName))
332 return HighlightCurrent();
334 for (
const auto *KV : sortedElements(*
O)) {
337 Recurse(KV->second,
Path.drop_back(), Recurse);
339 abbreviate(KV->second, JOS);
346 if (!A ||
S.index() >= A->size())
347 return HighlightCurrent();
349 unsigned Current = 0;
350 for (
const auto &V : *A) {
351 if (Current++ ==
S.index())
352 Recurse(V,
Path.drop_back(), Recurse);
359 PrintValue(R, ErrorPath, PrintValue);
373 P = Start + ErrOffset;
374 return parseError(
"Invalid UTF-8 sequence");
377 bool parseValue(
Value &Out);
383 return parseError(
"Text after end of document");
392 void eatWhitespace() {
393 while (
P != End && (*
P ==
' ' || *
P ==
'\r' || *
P ==
'\n' || *
P ==
'\t'))
398 bool parseNumber(
char First,
Value &Out);
399 bool parseString(std::string &Out);
400 bool parseUnicode(std::string &Out);
401 bool parseError(
const char *
Msg);
403 char next() {
return P == End ? 0 : *
P++; }
404 char peek() {
return P == End ? 0 : *
P; }
405 static bool isNumber(
char C) {
406 return C ==
'0' ||
C ==
'1' ||
C ==
'2' ||
C ==
'3' ||
C ==
'4' ||
407 C ==
'5' ||
C ==
'6' ||
C ==
'7' ||
C ==
'8' ||
C ==
'9' ||
408 C ==
'e' ||
C ==
'E' ||
C ==
'+' ||
C ==
'-' ||
C ==
'.';
412 const char *Start, *
P, *End;
415 bool 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");
493 return parseError(
"Expected , or } after object property");
499 return parseNumber(
C, Out);
500 return parseError(
"Invalid JSON value");
504 bool 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?)");
536 bool 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");
580 static void encodeUtf8(
uint32_t Rune, std::string &Out) {
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);
613 bool 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))
635 if (
LLVM_LIKELY(First < 0xD800 || First >= 0xE000)) {
636 encodeUtf8(First, Out);
654 if (!Parse4Hex(Second))
663 encodeUtf8(0x10000 | ((First - 0xD800) << 10) | (Second - 0xDC00), Out);
668 bool 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));
690 return P.takeError();
704 *ErrOffset = Rest -
Data;
710 std::vector<UTF32> Codepoints(
S.size());
711 const UTF8 *In8 =
reinterpret_cast<const UTF8 *
>(
S.data());
712 UTF32 *Out32 = Codepoints.data();
715 Codepoints.resize(Out32 - Codepoints.data());
716 std::string Res(4 * Codepoints.size(), 0);
717 const UTF32 *In32 = Codepoints.data();
718 UTF8 *Out8 =
reinterpret_cast<UTF8 *
>(&Res[0]);
721 Res.resize(
reinterpret_cast<char *
>(Out8) - Res.data());
727 for (
unsigned char C :
S) {
728 if (
C == 0x22 ||
C == 0x5C)
767 if (V.Type == Value::T_Integer)
769 else if (V.Type == Value::T_UINT64)
772 OS <<
format(
"%.*g", std::numeric_limits<double>::max_digits10,
787 attribute(
E->first,
E->second);
792 void llvm::json::OStream::valueBegin() {
793 assert(Stack.back().Ctx !=
Object &&
"Only attributes allowed here");
794 if (Stack.back().HasValue) {
795 assert(Stack.back().Ctx != Singleton &&
"Only one value allowed here");
798 if (Stack.back().Ctx == Array)
801 Stack.back().HasValue =
true;
805 assert(PendingComment.empty() &&
"Only one comment per value!");
806 PendingComment = Comment;
809 void OStream::flushComment() {
810 if (PendingComment.empty())
812 OS << (IndentSize ?
"/* " :
"/*");
814 while (!PendingComment.empty()) {
815 auto Pos = PendingComment.find(
"*/");
817 OS << PendingComment;
820 OS << PendingComment.take_front(Pos) <<
"* /";
821 PendingComment = PendingComment.drop_front(Pos + 2);
824 OS << (IndentSize ?
" */" :
"*/");
826 if (
Stack.size() > 1 &&
Stack.back().Ctx == Singleton) {
834 void llvm::json::OStream::newline() {
843 Stack.emplace_back();
844 Stack.back().Ctx =
Array;
845 Indent += IndentSize;
851 Indent -= IndentSize;
852 if (Stack.back().HasValue)
855 assert(PendingComment.empty());
862 Stack.emplace_back();
863 Stack.back().Ctx =
Object;
864 Indent += IndentSize;
870 Indent -= IndentSize;
871 if (Stack.back().HasValue)
874 assert(PendingComment.empty());
881 if (Stack.back().HasValue)
885 Stack.back().HasValue =
true;
886 Stack.emplace_back();
887 Stack.back().Ctx = Singleton;
891 assert(
false &&
"Invalid UTF-8 in attribute key");
900 assert(Stack.back().Ctx == Singleton);
901 assert(Stack.back().HasValue &&
"Attribute must have a value");
902 assert(PendingComment.empty());
909 Stack.emplace_back();
910 Stack.back().Ctx = RawValue;
915 assert(Stack.back().Ctx == RawValue);
924 unsigned IndentAmount = 0;
void comment(llvm::StringRef)
Emit a JavaScript comment associated with the next printed value.
void attributeBegin(llvm::StringRef Key)
The root is the trivial Path to the root value.
A Value is an JSON value of unknown type.
This is an optimization pass for GlobalISel generic memory operations.
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
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
static void quote(llvm::raw_ostream &OS, llvm::StringRef S)
void emplace_back(Args &&... A)
A raw_ostream that writes to an std::string.
static constexpr size_t npos
@ Invalid
Invalid file type.
llvm::Optional< std::nullptr_t > getAsNull() const
The instances of the Type class are immutable: once they are created, they are never changed.
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
void printErrorContext(const Value &, llvm::raw_ostream &) const
Print the root value with the error shown inline as a comment.
llvm::Optional< double > getAsNumber() const
Tagged union holding either a T or a Error.
void report(llvm::StringLiteral Message)
Records that the value at the current path is invalid.
static bool peek(struct InternalInstruction *insn, uint8_t &byte)
bool operator==(const Object &LHS, const Object &RHS)
ConversionResult ConvertUTF32toUTF8(const UTF32 **sourceStart, const UTF32 *sourceEnd, UTF8 **targetStart, UTF8 *targetEnd, ConversionFlags flags)
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
llvm::Optional< llvm::StringRef > getString(StringRef K) const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
(vector float) vec_cmpeq(*A, *B) C
void array(Block Contents)
Emit an array whose elements are emitted in the provided Block.
const json::Object * getObject(StringRef K) const
into llvm powi allowing the code generator to produce balanced multiplication trees First
@ Number
Number values can store both int64s and doubles at full precision, depending on what they were constr...
An Array is a JSON array, which contains heterogeneous JSON values.
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
This class implements an extremely fast bulk output stream that can only output to a stream.
llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
std::pair< iterator, bool > try_emplace(const ObjectKey &K, Ts &&... Args)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
LLVM_NODISCARD bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
llvm::Optional< double > getNumber(StringRef K) const
iterator find(StringRef K)
const json::Array * getAsArray() const
bar al al movzbl eax ret Missed when stored in a memory object
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
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
Value & operator[](const ObjectKey &K)
llvm::Optional< int64_t > getAsInteger() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::string fixUTF8(llvm::StringRef S)
Replaces invalid UTF-8 sequences in S with the replacement character (U+FFFD).
<%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(<
ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, const UTF8 *sourceEnd, UTF32 **targetStart, UTF32 *targetEnd, ConversionFlags flags)
Convert a partial UTF8 sequence to UTF32.
void write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style, Optional< size_t > Width=None)
llvm::Optional< bool > getAsBoolean() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
llvm::Optional< uint64_t > getAsUINT64() const
StringRef - Represent a constant reference to a string, i.e.
llvm::Optional< int64_t > getInteger(StringRef K) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
if(llvm_vc STREQUAL "") set(fake_version_inc "$
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
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
const CustomOperand< const MCSubtargetInfo & > Msg[]
Error getError() const
Returns the last error reported, or else a generic error.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
const json::Object * getAsObject() const
Lightweight error class with error context and mandatory checking.
void sort(IteratorTy Start, IteratorTy End)
void value(const Value &V)
Emit a self-contained value (number, string, vector<string> etc).
const json::Array * getArray(StringRef K) const
Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd)
Path(Root &R)
The root may be treated as a Path.
#define LLVM_LIKELY(EXPR)
bool isUTF8(llvm::StringRef S, size_t *ErrOffset=nullptr)
Returns true if S is valid UTF-8, which is required for use as JSON.
ObjectKey is a used to capture keys in Object.
#define LLVM_UNLIKELY(EXPR)
An Object is a JSON object, which maps strings to heterogenous JSON values.
llvm::Optional< llvm::StringRef > getAsString() const
std::string & str()
Returns the string's reference.
raw_ostream & rawValueBegin()
llvm::Optional< bool > getBoolean(StringRef K) const
A "cursor" marking a position within a Value.
LLVM Value Representation.
llvm::Optional< std::nullptr_t > getNull(StringRef K) const