Go to the documentation of this file.
46 #ifndef LLVM_SUPPORT_JSON_H
47 #define LLVM_SUPPORT_JSON_H
106 explicit Object(std::initializer_list<KV> Properties);
114 size_t size()
const {
return M.size(); }
117 std::pair<iterator, bool>
insert(KV
E);
118 template <
typename... Ts>
120 return M.try_emplace(K, std::forward<Ts>(
Args)...);
122 template <
typename... Ts>
158 std::vector<Value> V;
166 explicit Array(std::initializer_list<Value> Elements);
167 template <
typename Collection>
explicit Array(
const Collection &
C) {
168 for (
const auto &V :
C)
186 bool empty()
const {
return V.empty(); }
187 size_t size()
const {
return V.size(); }
194 V.emplace_back(std::forward<Args>(A)...);
203 return V.insert(
P, A, Z);
206 return V.emplace(
P, std::forward<Args>(A)...);
306 Value(std::initializer_list<Value> Elements);
308 create<json::Array>(
std::move(Elements));
310 template <
typename Elt>
313 create<json::Object>(
std::move(Properties));
315 template <
typename Elt>
320 assert(
false &&
"Invalid UTF-8 in value used as JSON");
330 create<llvm::StringRef>(V);
332 assert(
false &&
"Invalid UTF-8 in value used as JSON");
340 template <
typename T,
341 typename = std::enable_if_t<std::is_same<T, bool>::value>,
348 template <
typename T,
349 typename = std::enable_if_t<std::is_same<T, uint64_t>::value>,
350 bool =
false,
bool =
false>
357 template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>,
358 typename = std::enable_if_t<!std::is_same<T, bool>::value>,
359 typename = std::enable_if_t<!std::is_same<T, uint64_t>::value>>
361 create<int64_t>(int64_t{
I});
364 template <
typename T,
365 typename = std::enable_if_t<std::is_floating_point<T>::value>,
368 create<double>(
double{
D});
371 template <
typename T,
372 typename = std::enable_if_t<std::is_same<
373 Value, decltype(
toJSON(*(
const T *)
nullptr))>::value>,
425 return as<int64_t>();
427 return as<uint64_t>();
433 return as<int64_t>();
435 double D = as<double>();
444 if (
Type == T_UINT64)
445 return as<uint64_t>();
446 else if (
Type == T_Integer) {
447 int64_t
N = as<int64_t>();
449 return as<uint64_t>();
454 if (
Type == T_String)
457 return as<llvm::StringRef>();
475 void copyFrom(
const Value &M);
479 void moveFrom(
const Value &&M);
483 template <
typename T,
typename... U>
void create(U &&... V) {
484 new (
reinterpret_cast<T *
>(&Union))
T(std::forward<U>(V)...);
486 template <
typename T>
T &
as()
const {
489 void *Storage =
static_cast<void *
>(&Union);
490 return *
static_cast<T *
>(Storage);
527 assert(
false &&
"Invalid UTF-8 in value used as JSON");
534 assert(
false &&
"Invalid UTF-8 in value used as JSON");
546 Owned.reset(
new std::string(*
C.Owned));
556 std::string
str()
const {
return Data.
str(); }
561 std::unique_ptr<std::string> Owned;
581 for (
const auto &
P : Properties) {
584 R.first->getSecond().moveFrom(
std::move(
P.V));
622 Segment(Root *R) : Pointer(reinterpret_cast<uintptr_t>(R)) {}
624 : Pointer(reinterpret_cast<uintptr_t>(
Field.data())),
625 Offset(static_cast<unsigned>(
Field.
size())) {}
626 Segment(
unsigned Index) : Pointer(0), Offset(Index) {}
628 bool isField()
const {
return Pointer != 0; }
629 StringRef
field()
const {
630 return StringRef(
reinterpret_cast<const char *
>(Pointer), Offset);
633 Root *root()
const {
return reinterpret_cast<Root *
>(
Pointer); }
639 Path(
const Path *Parent, Segment
S) : Parent(Parent), Seg(
S) {}
647 std::vector<Path::Segment> ErrorPath;
674 if (
auto S =
E.getAsString()) {
675 Out = std::string(*
S);
678 P.report(
"expected string");
682 if (
auto S =
E.getAsInteger()) {
686 P.report(
"expected integer");
690 if (
auto S =
E.getAsInteger()) {
694 P.report(
"expected integer");
698 if (
auto S =
E.getAsNumber()) {
702 P.report(
"expected number");
706 if (
auto S =
E.getAsBoolean()) {
710 P.report(
"expected boolean");
714 if (
auto S =
E.getAsUINT64()) {
718 P.report(
"expected uint64_t");
722 if (
auto S =
E.getAsNull()) {
726 P.report(
"expected null");
729 template <
typename T>
741 template <
typename T>
743 if (
auto *A =
E.getAsArray()) {
745 Out.resize(A->size());
746 for (
size_t I = 0;
I < A->size(); ++
I)
751 P.report(
"expected array");
754 template <
typename T>
756 if (
auto *
O =
E.getAsObject()) {
758 for (
const auto &KV : *
O)
764 P.report(
"expected object");
789 P.report(
"expected object");
794 operator bool()
const {
return O; }
799 assert(*
this &&
"Must check this is an object before calling map()");
810 assert(*
this &&
"Must check this is an object before calling map()");
821 assert(*
this &&
"Must check this is an object before calling map()");
839 unsigned Line, Column, Offset;
843 ParseError(
const char *Msg,
unsigned Line,
unsigned Column,
unsigned Offset)
844 : Msg(Msg), Line(Line), Column(Column), Offset(Offset) {}
846 OS <<
llvm::formatv(
"[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
855 template <
typename T>
857 auto V =
parse(JSON);
859 return V.takeError();
926 : OS(OS), IndentSize(IndentSize) {
930 assert(Stack.size() == 1 &&
"Unmatched begin()/end()");
931 assert(Stack.back().Ctx == Singleton);
932 assert(Stack.back().HasValue &&
"Did not write top-level value");
977 attributeImpl(
Key, [&] {
value(Contents); });
981 attributeImpl(
Key, [&] {
array(Contents); });
985 attributeImpl(
Key, [&] {
object(Contents); });
1008 void flushComment();
1024 unsigned IndentSize;
1025 unsigned Indent = 0;
Value & operator[](size_t I)
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.
compiles conv shl5 shl ret i32 or10 it would be better as
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
iterator emplace(const_iterator P, Args &&... A)
const_iterator find(StringRef K) const
void emplace_back(Args &&... A)
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double
friend bool operator==(const Value &, const Value &)
llvm::Optional< std::nullptr_t > getAsNull() const
bool erase(const KeyT &Val)
llvm::function_ref< void()> Block
The instances of the Type class are immutable: once they are created, they are never changed.
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.
void attributeArray(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an array with elements from the Block.
ObjectMapper(const Value &E, Path P)
If O is not an object, this mapper is invalid and an error is reported.
bool map(StringLiteral Prop, T &Out)
Maps a property to a field.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
llvm::Optional< double > getAsNumber() const
Tagged union holding either a T or a Error.
iterator insert(iterator P, const Value &E)
void log(llvm::raw_ostream &OS) const override
Print an error message to an output stream.
void rawValue(llvm::StringRef Contents)
A suitably aligned and sized character array member which can hold elements of any type.
friend bool operator==(const Array &L, const Array &R)
void push_back(const Value &E)
bool map(StringLiteral Prop, llvm::Optional< T > &Out)
Maps a property to a field, if it exists.
void report(llvm::StringLiteral Message)
Records that the value at the current path is invalid.
std::vector< Value >::const_iterator const_iterator
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
DenseMapIterator< ObjectKey, Value, llvm::DenseMapInfo< StringRef >, llvm::detail::DenseMapPair< ObjectKey, Value >, true > const_iterator
bool operator==(const Object &LHS, const Object &RHS)
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
ParseError(const char *Msg, unsigned Line, unsigned Column, unsigned Offset)
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
const_iterator begin() const
llvm::Optional< llvm::StringRef > getString(StringRef K) const
const Value & back() const
Value(const llvm::formatv_object_base &V)
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.
Root(llvm::StringRef Name="")
const json::Object * getObject(StringRef K) const
bool mapOptional(StringLiteral Prop, T &Out)
Maps a property to a field, if it exists.
iterator insert(iterator P, Value &&E)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Value & operator=(Value &&M)
@ 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.
This class implements an extremely fast bulk output stream that can only output to a stream.
const Value & operator[](size_t I) const
Value(json::Array &&Elements)
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)
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
const Value * data() const
llvm::Optional< double > getNumber(StringRef K) const
ObjectKey(const llvm::formatv_object_base &V)
An efficient, type-erasing, non-owning reference to a callable.
std::pair< iterator, bool > try_emplace(ObjectKey &&K, Ts &&... Args)
iterator find(StringRef K)
json::Array * getAsArray()
iterator insert(iterator P, It A, It Z)
const json::Array * getAsArray() const
bool fromJSON(const Value &E, std::string &Out, Path P)
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::detail::DenseMapPair< ObjectKey, Value > value_type
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
Path index(unsigned Index) const
Derives a path for an array element: this[Index].
bool operator!=(const Object &LHS, const Object &RHS)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
ObjectKey(llvm::StringRef S)
std::string fixUTF8(llvm::StringRef S)
Replaces invalid UTF-8 sequences in S with the replacement character (U+FFFD).
Base class for user error types.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
llvm::Optional< bool > getAsBoolean() const
std::vector< Value >::iterator iterator
llvm::Optional< uint64_t > getAsUINT64() const
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
ObjectKey(const ObjectKey &C)
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.
Path field(StringRef Field) const
Derives a path for an object field: this.Field.
Value(const llvm::SmallVectorImpl< char > &V)
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
Value toJSON(const llvm::Optional< T > &Opt)
ObjectKey & operator=(const ObjectKey &C)
const_iterator end() const
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Error getError() const
Returns the last error reported, or else a generic error.
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
Value(const std::map< std::string, Elt > &C)
Lightweight error class with error context and mandatory checking.
void value(const Value &V)
Emit a self-contained value (number, string, vector<string> etc).
const json::Array * getArray(StringRef K) const
detail::ValueMatchesPoly< M > HasValue(M Matcher)
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Value &V)
Serializes this Value to JSON, writing it to the provided stream.
Path(Root &R)
The root may be treated as a Path.
ObjectKey(const llvm::SmallVectorImpl< char > &V)
DenseMapIterator< ObjectKey, Value, llvm::DenseMapInfo< StringRef >, llvm::detail::DenseMapPair< ObjectKey, Value > > iterator
Value(const std::vector< Elt > &C)
json::Object * getAsObject()
const_iterator end() const
const Value & front() const
#define LLVM_LIKELY(EXPR)
Array(const Collection &C)
Value(json::Object &&Properties)
void attributeObject(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an object with attributes from the Block.
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.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
#define LLVM_UNLIKELY(EXPR)
An Object is a JSON object, which maps strings to heterogenous JSON values.
llvm::Optional< llvm::StringRef > getAsString() const
std::pair< iterator, bool > insert(KV E)
raw_ostream & rawValueBegin()
llvm::Optional< bool > getBoolean(StringRef K) const
void push_back(Value &&E)
A "cursor" marking a position within a Value.
LLVM Value Representation.
OStream(llvm::raw_ostream &OS, unsigned IndentSize=0)
void flush()
Flushes the underlying ostream. OStream does not buffer internally.
Root & operator=(Root &&)=delete
Helper for mapping JSON objects onto protocol structs.
reference emplace_back(ArgTypes &&... Args)
const_iterator begin() const
void rawValue(llvm::function_ref< void(raw_ostream &)> Contents)
Emit an externally-serialized value.
bool operator<(const ObjectKey &L, const ObjectKey &R)
llvm::Optional< std::nullptr_t > getNull(StringRef K) const
Value & operator=(const Value &M)