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)
298 Value(std::initializer_list<Value> Elements);
300 create<json::Array>(
std::move(Elements));
302 template <
typename Elt>
305 create<json::Object>(
std::move(Properties));
307 template <
typename Elt>
312 assert(
false &&
"Invalid UTF-8 in value used as JSON");
322 create<llvm::StringRef>(V);
324 assert(
false &&
"Invalid UTF-8 in value used as JSON");
332 template <
typename T,
333 typename = std::enable_if_t<std::is_same<T, bool>::value>,
340 template <
typename T,
341 typename = std::enable_if_t<std::is_same<T, uint64_t>::value>,
342 bool =
false,
bool =
false>
349 template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>,
350 typename = std::enable_if_t<!std::is_same<T, bool>::value>,
351 typename = std::enable_if_t<!std::is_same<T, uint64_t>::value>>
353 create<int64_t>(int64_t{
I});
356 template <
typename T,
357 typename = std::enable_if_t<std::is_floating_point<T>::value>,
360 create<double>(
double{
D});
363 template <
typename T,
364 typename = std::enable_if_t<std::is_same<
365 Value, decltype(
toJSON(*(
const T *)
nullptr))>::value>,
417 return as<int64_t>();
419 return as<uint64_t>();
425 return as<int64_t>();
427 double D = as<double>();
436 if (
Type == T_UINT64)
437 return as<uint64_t>();
438 else if (
Type == T_Integer) {
439 int64_t
N = as<int64_t>();
441 return as<uint64_t>();
446 if (
Type == T_String)
449 return as<llvm::StringRef>();
467 void copyFrom(
const Value &M);
471 void moveFrom(
const Value &&M);
475 template <
typename T,
typename... U>
void create(U &&... V) {
476 new (
reinterpret_cast<T *
>(&Union))
T(std::forward<U>(V)...);
478 template <
typename T>
T &
as()
const {
481 void *Storage =
static_cast<void *
>(&Union);
482 return *
static_cast<T *
>(Storage);
533 V.emplace_back(std::forward<Args>(
A)...);
537 return V.insert(
P,
E);
542 template <
typename It>
544 return V.insert(
P,
A,
Z);
546 template <
typename...
Args>
548 return V.emplace(
P, std::forward<Args>(
A)...);
561 assert(
false &&
"Invalid UTF-8 in value used as JSON");
568 assert(
false &&
"Invalid UTF-8 in value used as JSON");
580 Owned.reset(
new std::string(*
C.Owned));
590 std::string
str()
const {
return Data.
str(); }
595 std::unique_ptr<std::string> Owned;
615 for (
const auto &
P : Properties) {
618 R.first->getSecond().moveFrom(
std::move(
P.V));
656 Segment(Root *R) : Pointer(reinterpret_cast<uintptr_t>(R)) {}
658 : Pointer(reinterpret_cast<uintptr_t>(
Field.data())),
659 Offset(static_cast<unsigned>(
Field.
size())) {}
660 Segment(
unsigned Index) : Pointer(0), Offset(Index) {}
662 bool isField()
const {
return Pointer != 0; }
663 StringRef
field()
const {
664 return StringRef(
reinterpret_cast<const char *
>(Pointer), Offset);
667 Root *root()
const {
return reinterpret_cast<Root *
>(
Pointer); }
673 Path(
const Path *Parent, Segment
S) : Parent(Parent), Seg(
S) {}
681 std::vector<Path::Segment> ErrorPath;
708 if (
auto S =
E.getAsString()) {
709 Out = std::string(*
S);
712 P.report(
"expected string");
716 if (
auto S =
E.getAsInteger()) {
720 P.report(
"expected integer");
724 if (
auto S =
E.getAsInteger()) {
728 P.report(
"expected integer");
732 if (
auto S =
E.getAsNumber()) {
736 P.report(
"expected number");
740 if (
auto S =
E.getAsBoolean()) {
744 P.report(
"expected boolean");
748 if (
auto S =
E.getAsUINT64()) {
752 P.report(
"expected uint64_t");
756 if (
auto S =
E.getAsNull()) {
760 P.report(
"expected null");
763 template <
typename T>
775 template <
typename T>
777 if (
auto *A =
E.getAsArray()) {
779 Out.resize(A->size());
780 for (
size_t I = 0;
I < A->size(); ++
I)
785 P.report(
"expected array");
788 template <
typename T>
790 if (
auto *
O =
E.getAsObject()) {
792 for (
const auto &KV : *
O)
798 P.report(
"expected object");
823 P.report(
"expected object");
828 operator bool()
const {
return O; }
833 assert(*
this &&
"Must check this is an object before calling map()");
844 assert(*
this &&
"Must check this is an object before calling map()");
855 assert(*
this &&
"Must check this is an object before calling map()");
873 unsigned Line, Column, Offset;
877 ParseError(
const char *Msg,
unsigned Line,
unsigned Column,
unsigned Offset)
878 : Msg(Msg), Line(Line), Column(Column), Offset(Offset) {}
880 OS <<
llvm::formatv(
"[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
889 template <
typename T>
891 auto V =
parse(JSON);
893 return V.takeError();
960 : OS(OS), IndentSize(IndentSize) {
964 assert(Stack.size() == 1 &&
"Unmatched begin()/end()");
965 assert(Stack.back().Ctx == Singleton);
966 assert(Stack.back().HasValue &&
"Did not write top-level value");
1011 attributeImpl(
Key, [&] {
value(Contents); });
1015 attributeImpl(
Key, [&] {
array(Contents); });
1019 attributeImpl(
Key, [&] {
object(Contents); });
1042 void flushComment();
1058 unsigned IndentSize;
1059 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
const_iterator find(StringRef K) const
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
void emplace_back(Args &&...A)
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.
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
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.
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.
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.
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()
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.
iterator emplace(const_iterator P, Args &&...A)
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.
iterator insert(iterator P, const Value &E)
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()
#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
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)
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)