46#ifndef LLVM_SUPPORT_JSON_H
47#define LLVM_SUPPORT_JSON_H
80 std::is_integral_v<T> && std::is_unsigned_v<T> &&
94template <
typename T>
Value toJSON(
const std::optional<T> &Opt);
113 explicit Object(std::initializer_list<KV> Properties);
120 bool empty()
const {
return M.empty(); }
121 size_t size()
const {
return M.size(); }
124 std::pair<iterator, bool>
insert(KV
E);
125 template <
typename... Ts>
127 return M.try_emplace(K, std::forward<Ts>(Args)...);
129 template <
typename... Ts>
131 return M.try_emplace(std::move(K), std::forward<Ts>(Args)...);
167 std::vector<Value> V;
175 LLVM_ABI explicit Array(std::initializer_list<Value> Elements);
176 template <
typename Collection>
explicit Array(
const Collection &
C) {
177 for (
const auto &V :
C)
308 create<json::Array>(std::move(Elements));
310 template <
typename Elt>
313 create<json::Object>(std::move(Properties));
315 template <
typename Elt>
318 Value(std::string V) : Type(T_String) {
320 assert(
false &&
"Invalid UTF-8 in value used as JSON");
323 create<std::string>(std::move(V));
326 :
Value(
std::string(V.begin(), V.end())) {}
330 create<llvm::StringRef>(V);
332 assert(
false &&
"Invalid UTF-8 in value used as JSON");
337 Value(std::nullptr_t) : Type(T_Null) {}
340 template <
typename T,
typename = std::enable_if_t<std::is_same_v<T,
bool>>,
347 template <
typename T,
typename = std::enable_if_t<is_u
int_64_bit_v<T>>>
354 template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>,
355 typename = std::enable_if_t<!std::is_same_v<T,
bool>>,
356 typename = std::enable_if_t<!is_u
int_64_bit_v<T>>>
358 create<int64_t>(int64_t{
I});
361 template <
typename T,
362 typename = std::enable_if_t<std::is_floating_point_v<T>>,
365 create<double>(
double{
D});
368 template <
typename T,
369 typename = std::enable_if_t<
370 std::is_same_v<
Value,
decltype(
toJSON(*(
const T *)
nullptr))>>,
381 moveFrom(std::move(M));
423 return as<int64_t>();
425 return as<uint64_t>();
431 return as<int64_t>();
439 double D = as<double>();
441 D >=
double(std::numeric_limits<int64_t>::min()) &&
442 D <=
double(std::numeric_limits<int64_t>::max())))
448 if (Type == T_UINT64)
449 return as<uint64_t>();
450 else if (Type == T_Integer) {
451 int64_t
N = as<int64_t>();
453 return as<uint64_t>();
458 if (Type == T_String)
461 return as<llvm::StringRef>();
465 return LLVM_LIKELY(Type == T_Object) ? &as<json::Object>() :
nullptr;
468 return LLVM_LIKELY(Type == T_Object) ? &as<json::Object>() :
nullptr;
471 return LLVM_LIKELY(Type == T_Array) ? &as<json::Array>() :
nullptr;
474 return LLVM_LIKELY(Type == T_Array) ? &as<json::Array>() :
nullptr;
478#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
495 template <
typename T,
typename... U>
void create(U &&... V) {
496#if LLVM_ADDRESS_SANITIZER_BUILD
508 new (
reinterpret_cast<T *
>(&Union))
T(std::forward<U>(V)...);
510 template <
typename T>
T &as()
const {
513 void *Storage =
static_cast<void *
>(&Union);
514 return *
static_cast<T *
>(Storage);
519 enum ValueType :
char16_t {
565 V.emplace_back(std::forward<Args>(
A)...);
569 return V.insert(
P,
E);
572 return V.insert(
P, std::move(
E));
574template <
typename It>
576 return V.insert(
P,
A, Z);
578template <
typename... Args>
580 return V.emplace(
P, std::forward<Args>(
A)...);
593 assert(
false &&
"Invalid UTF-8 in value used as JSON");
594 *Owned =
fixUTF8(std::move(*Owned));
600 assert(
false &&
"Invalid UTF-8 in value used as JSON");
612 Owned.reset(
new std::string(*
C.Owned));
622 std::string
str()
const {
return Data.str(); }
627 std::unique_ptr<std::string> Owned;
647 for (
const auto &
P : Properties) {
650 R.first->getSecond().moveFrom(std::move(
P.V));
660LLVM_ABI std::vector<const Object::value_type *>
691 Segment(Root *R) : Pointer(reinterpret_cast<uintptr_t>(R)) {}
693 : Pointer(reinterpret_cast<uintptr_t>(
Field.
data())),
695 Segment(
unsigned Index) : Pointer(0),
Offset(Index) {}
697 bool isField()
const {
return Pointer != 0; }
698 StringRef field()
const {
699 return StringRef(
reinterpret_cast<const char *
>(Pointer), Offset);
701 unsigned index()
const {
return Offset; }
702 Root *root()
const {
return reinterpret_cast<Root *
>(Pointer); }
708 Path(
const Path *Parent, Segment S) : Parent(Parent), Seg(S) {}
716 std::vector<Path::Segment> ErrorPath;
743 if (
auto S =
E.getAsString()) {
744 Out = std::string(*S);
747 P.report(
"expected string");
751 if (
auto S =
E.getAsInteger()) {
755 P.report(
"expected integer");
759 if (
auto S =
E.getAsInteger()) {
763 P.report(
"expected integer");
767 if (
auto S =
E.getAsNumber()) {
771 P.report(
"expected number");
775 if (
auto S =
E.getAsBoolean()) {
779 P.report(
"expected boolean");
783 if (
auto S =
E.getAsInteger()) {
787 P.report(
"expected unsigned integer");
791 if (
auto S =
E.getAsUINT64()) {
795 P.report(
"expected uint64_t");
799 if (
auto S =
E.getAsNull()) {
803 P.report(
"expected null");
815 Out = std::move(Result);
820 if (
auto *
A =
E.getAsArray()) {
822 Out.resize(
A->size());
823 for (
size_t I = 0;
I <
A->size(); ++
I)
828 P.report(
"expected array");
833 if (
auto *O =
E.getAsObject()) {
835 for (
const auto &KV : *O)
841 P.report(
"expected object");
866 P.report(
"expected object");
871 operator bool()
const {
return O; }
876 assert(*
this &&
"Must check this is an object before calling map()");
877 if (
const Value *
E = O->get(Prop))
879 P.field(Prop).report(
"missing value");
887 assert(*
this &&
"Must check this is an object before calling map()");
888 if (
const Value *
E = O->get(Prop))
898 assert(*
this &&
"Must check this is an object before calling map()");
899 if (
const Value *
E = O->get(Prop))
916 unsigned Line, Column, Offset;
920 ParseError(
const char *Msg,
unsigned Line,
unsigned Column,
unsigned Offset)
921 : Msg(Msg), Line(Line), Column(Column), Offset(Offset) {}
923 OS <<
llvm::formatv(
"[{0}:{1}, byte={2}]: {3}", Line, Column, Offset, Msg);
934 auto V =
parse(JSON);
936 return V.takeError();
940 return std::move(Result);
1003 : OS(OS), IndentSize(IndentSize) {
1004 Stack.emplace_back();
1007 assert(Stack.size() == 1 &&
"Unmatched begin()/end()");
1008 assert(Stack.back().Ctx == Singleton);
1009 assert(Stack.back().HasValue &&
"Did not write top-level value");
1054 attributeImpl(
Key, [&] {
value(Contents); });
1058 attributeImpl(
Key, [&] {
array(Contents); });
1062 attributeImpl(
Key, [&] {
object(Contents); });
1095 Context Ctx = Singleton;
1096 bool HasValue =
false;
1098 llvm::SmallVector<State, 16> Stack;
1099 llvm::StringRef PendingComment;
1100 llvm::raw_ostream &OS;
1101 unsigned IndentSize;
1102 unsigned Indent = 0;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_UNLIKELY(EXPR)
#define __asan_unpoison_memory_region(p, size)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
#define LLVM_LIKELY(EXPR)
This file defines the DenseMap class.
OptimizedStructLayoutField Field
This file defines the SmallVector class.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Base class for user error types.
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.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
An Array is a JSON array, which contains heterogeneous JSON values.
void emplace_back(Args &&...A)
friend bool operator==(const Array &L, const Array &R)
std::vector< Value >::const_iterator const_iterator
Value & operator[](size_t I)
iterator emplace(const_iterator P, Args &&...A)
std::vector< Value >::iterator iterator
iterator insert(const_iterator P, const Value &E)
void push_back(const Value &E)
Array(const Collection &C)
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.
void attributeObject(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an object with attributes from the Block.
OStream(llvm::raw_ostream &OS, unsigned IndentSize=0)
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).
void flush()
Flushes the underlying ostream. OStream does not buffer internally.
LLVM_ABI void arrayBegin()
LLVM_ABI void objectBegin()
LLVM_ABI raw_ostream & rawValueBegin()
void attributeArray(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an array with elements from the Block.
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()
void rawValue(llvm::StringRef Contents)
LLVM_ABI void value(const Value &V)
Emit a self-contained value (number, string, vector<string> etc).
LLVM_ABI void rawValueEnd()
llvm::function_ref< void()> Block
LLVM_ABI void objectEnd()
ObjectKey is a used to capture keys in Object.
ObjectKey & operator=(ObjectKey &&)=default
ObjectKey(const ObjectKey &C)
ObjectKey(const llvm::formatv_object_base &V)
ObjectKey(llvm::StringRef S)
operator llvm::StringRef() const
ObjectKey & operator=(const ObjectKey &C)
ObjectKey(const llvm::SmallVectorImpl< char > &V)
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.
bool mapOptional(StringLiteral Prop, T &Out)
Maps a property to a field, if it exists.
bool map(StringLiteral Prop, std::optional< T > &Out)
Maps a property to a field, if it exists.
An Object is a JSON object, which maps strings to heterogenous JSON values.
LLVM_ABI std::optional< bool > getBoolean(StringRef K) const
const_iterator end() 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)
std::pair< iterator, bool > try_emplace(ObjectKey &&K, Ts &&... Args)
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)
friend bool operator==(const Object &LHS, const Object &RHS)
const_iterator begin() const
Storage::iterator iterator
const_iterator find(StringRef K) const
Storage::const_iterator const_iterator
iterator find(StringRef K)
std::pair< iterator, bool > insert(KV E)
LLVM_ABI const json::Array * getArray(StringRef K) const
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
void log(llvm::raw_ostream &OS) const override
Print an error message to an output stream.
ParseError(const char *Msg, unsigned Line, unsigned Column, unsigned Offset)
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.
Root & operator=(const Root &)=delete
LLVM_ABI Error getError() const
Returns the last error reported, or else a generic error.
Root(const Root &)=delete
Root & operator=(Root &&)=delete
Root(llvm::StringRef Name="")
A "cursor" marking a position within a Value.
Path index(unsigned Index) const
Derives a path for an array element: this[Index].
LLVM_ABI void report(llvm::StringLiteral Message)
Records that the value at the current path is invalid.
Path field(StringRef Field) const
Derives a path for an object field: this.Field.
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
Value(json::Object &&Properties)
Value(const std::vector< Elt > &C)
std::optional< bool > getAsBoolean() const
std::optional< double > getAsNumber() const
std::optional< uint64_t > getAsUINT64() const
Value & operator=(Value &&M)
Value & operator=(const Value &M)
LLVM_DUMP_METHOD void dump() const
Value(const llvm::formatv_object_base &V)
json::Object * getAsObject()
std::optional< int64_t > getAsInteger() const
Value(const llvm::SmallVectorImpl< char > &V)
Value(const std::map< std::string, Elt > &C)
LLVM_ABI friend bool operator==(const Value &, const Value &)
json::Array * getAsArray()
Value(json::Array &&Elements)
@ Number
Number values can store both int64s and doubles at full precision, depending on what they were constr...
std::optional< llvm::StringRef > getAsString() const
std::optional< std::nullptr_t > getAsNull() const
const json::Object * getAsObject() const
const json::Array * getAsArray() const
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
constexpr bool is_uint_64_bit_v
Value toJSON(const std::optional< T > &Opt)
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
bool operator<(const ObjectKey &L, const ObjectKey &R)
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.
bool fromJSON(const Value &E, std::string &Out, Path P)
LLVM_ABI std::vector< const Object::value_type * > sortedElements(const Object &O)
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Value &V)
Serializes this Value to JSON, writing it to the provided stream.
LLVM_ABI std::string fixUTF8(llvm::StringRef S)
Replaces invalid UTF-8 sequences in S with the replacement character (U+FFFD).
bool operator!=(const Object &LHS, const Object &RHS)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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
FunctionAddr VTableAddr uintptr_t uintptr_t Data
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
Implement std::hash so that hash_code can be used in STL containers.
A suitably aligned and sized character array member which can hold elements of any type.