Go to the documentation of this file.
46 #ifndef LLVM_SUPPORT_JSON_H
47 #define LLVM_SUPPORT_JSON_H
105 explicit Object(std::initializer_list<KV> Properties);
113 size_t size()
const {
return M.size(); }
116 std::pair<iterator, bool>
insert(KV
E);
117 template <
typename... Ts>
119 return M.try_emplace(K, std::forward<Ts>(
Args)...);
121 template <
typename... Ts>
149 bool operator==(
const Object &LHS,
const Object &RHS);
151 return !(LHS == RHS);
157 std::vector<Value> V;
165 explicit Array(std::initializer_list<Value> Elements);
166 template <
typename Collection>
explicit Array(
const Collection &
C) {
167 for (
const auto &V :
C)
185 bool empty()
const {
return V.empty(); }
186 size_t size()
const {
return V.size(); }
193 V.emplace_back(std::forward<Args>(A)...);
202 return V.insert(
P, A, Z);
205 return V.emplace(
P, std::forward<Args>(A)...);
305 Value(std::initializer_list<Value> Elements);
307 create<json::Array>(
std::move(Elements));
309 template <
typename Elt>
312 create<json::Object>(
std::move(Properties));
314 template <
typename Elt>
319 assert(
false &&
"Invalid UTF-8 in value used as JSON");
329 create<llvm::StringRef>(V);
331 assert(
false &&
"Invalid UTF-8 in value used as JSON");
339 template <
typename T,
340 typename = std::enable_if_t<std::is_same<T, bool>::value>,
346 template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>,
347 typename = std::enable_if_t<!std::is_same<T, bool>::value>>
349 create<int64_t>(int64_t{
I});
352 template <
typename T,
353 typename = std::enable_if_t<std::is_floating_point<T>::value>,
356 create<double>(
double{
D});
359 template <
typename T,
360 typename = std::enable_if_t<std::is_same<
361 Value, decltype(
toJSON(*(
const T *)
nullptr))>::value>,
412 return as<int64_t>();
418 return as<int64_t>();
420 double D = as<double>();
429 if (
Type == T_String)
432 return as<llvm::StringRef>();
450 void copyFrom(
const Value &M);
454 void moveFrom(
const Value &&M);
458 template <
typename T,
typename... U>
void create(U &&... V) {
459 new (
reinterpret_cast<T *
>(&Union))
T(std::forward<U>(V)...);
461 template <
typename T>
T &
as()
const {
464 void *Storage =
static_cast<void *
>(&Union);
465 return *
static_cast<T *
>(Storage);
500 assert(
false &&
"Invalid UTF-8 in value used as JSON");
507 assert(
false &&
"Invalid UTF-8 in value used as JSON");
519 Owned.reset(
new std::string(*
C.Owned));
529 std::string
str()
const {
return Data.
str(); }
534 std::unique_ptr<std::string> Owned;
554 for (
const auto &
P : Properties) {
557 R.first->getSecond().moveFrom(
std::move(
P.V));
595 Segment(Root *R) : Pointer(reinterpret_cast<uintptr_t>(R)) {}
597 : Pointer(reinterpret_cast<uintptr_t>(
Field.data())),
601 bool isField()
const {
return Pointer != 0; }
602 StringRef
field()
const {
603 return StringRef(
reinterpret_cast<const char *
>(Pointer),
Offset);
606 Root *root()
const {
return reinterpret_cast<Root *
>(
Pointer); }
612 Path(
const Path *Parent, Segment
S) : Parent(Parent), Seg(
S) {}
620 std::vector<Path::Segment> ErrorPath;
647 if (
auto S =
E.getAsString()) {
648 Out = std::string(*
S);
651 P.report(
"expected string");
655 if (
auto S =
E.getAsInteger()) {
659 P.report(
"expected integer");
663 if (
auto S =
E.getAsInteger()) {
667 P.report(
"expected integer");
671 if (
auto S =
E.getAsNumber()) {
675 P.report(
"expected number");
679 if (
auto S =
E.getAsBoolean()) {
683 P.report(
"expected boolean");
687 if (
auto S =
E.getAsNull()) {
691 P.report(
"expected null");
694 template <
typename T>
706 template <
typename T>
708 if (
auto *A =
E.getAsArray()) {
710 Out.resize(A->size());
711 for (
size_t I = 0;
I < A->size(); ++
I)
716 P.report(
"expected array");
719 template <
typename T>
721 if (
auto *
O =
E.getAsObject()) {
723 for (
const auto &KV : *
O)
729 P.report(
"expected object");
754 P.report(
"expected object");
759 operator bool()
const {
return O; }
764 assert(*
this &&
"Must check this is an object before calling map()");
775 assert(*
this &&
"Must check this is an object before calling map()");
786 assert(*
this &&
"Must check this is an object before calling map()");
804 unsigned Line, Column, Offset;
808 ParseError(
const char *Msg,
unsigned Line,
unsigned Column,
unsigned Offset)
809 : Msg(Msg), Line(Line), Column(Column), Offset(Offset) {}
811 OS <<
llvm::formatv(
"[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
820 template <
typename T>
822 auto V =
parse(JSON);
824 return V.takeError();
891 : OS(OS), IndentSize(IndentSize) {
895 assert(Stack.size() == 1 &&
"Unmatched begin()/end()");
896 assert(Stack.back().Ctx == Singleton);
897 assert(Stack.back().HasValue &&
"Did not write top-level value");
942 attributeImpl(
Key, [&] {
value(Contents); });
946 attributeImpl(
Key, [&] {
array(Contents); });
950 attributeImpl(
Key, [&] {
object(Contents); });
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 class represents lattice values for constants.
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.
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
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()
Align max(MaybeAlign Lhs, Align Rhs)
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)