GCC Middle and Back End API Reference
json.h
Go to the documentation of this file.
1/* JSON trees
2 Copyright (C) 2017-2025 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_JSON_H
22#define GCC_JSON_H
23
24/* Implementation of JSON, a lightweight data-interchange format.
25
26 See http://www.json.org/
27 and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
28 and https://tools.ietf.org/html/rfc7159
29
30 Supports parsing text into a DOM-like tree of json::value *, directly
31 creating such trees, and dumping json::value * to text. */
32
33/* TODO: `libcpp/mkdeps.cc` wants JSON writing support for p1689r5 output;
34 extract this code and move to libiberty. */
35
36namespace json
37{
38
39/* Forward decls of json::value and its subclasses (using indentation
40 to denote inheritance. */
41
42class value;
43 class object;
44 class array;
45 class float_number;
46 class integer_number;
47 class string;
48 class literal;
49
50/* An enum for discriminating the subclasses of json::value. */
51
52enum kind
53{
54 /* class json::object. */
56
57 /* class json::array. */
59
60 /* class json::integer_number. */
62
63 /* class json::float_number. */
65
66 /* class json::string. */
68
69 /* class json::literal uses these three values to identify the
70 particular literal. */
74};
75
76namespace pointer { // json::pointer
77
78/* Implementation of JSON pointer (RFC 6901). */
79
80/* A token within a JSON pointer, expressing the parent of a particular
81 JSON value, and how it is descended from that parent.
82
83 A JSON pointer can be built as a list of these tokens. */
84
85struct token
86{
93
94 token ();
95 token (json::object &parent, const char *member);
96 token (json::array &parent, size_t index);
97 token (const token &other) = delete;
98 token (token &&other) = delete;
99
100 ~token ();
101
102 token &
103 operator= (const token &other) = delete;
104
105 token &
106 operator= (token &&other);
107
109 union u
110 {
111 char *u_member;
112 size_t u_index;
115};
116
117} // namespace json::pointer
118
119/* Base class of JSON value. */
120
121class value
122{
123 public:
124 virtual ~value () {}
125 virtual enum kind get_kind () const = 0;
126 virtual void print (pretty_printer *pp, bool formatted) const = 0;
127 virtual std::unique_ptr<value> clone () const = 0;
128
129 void dump (FILE *, bool formatted) const;
130 void DEBUG_FUNCTION dump () const;
131
132 virtual object *dyn_cast_object () { return nullptr; }
133 virtual string *dyn_cast_string () { return nullptr; }
134
135 static int compare (const json::value &val_a, const json::value &val_b);
136
138
140};
141
142/* Subclass of value for objects: a collection of key/value pairs
143 preserving the ordering in which keys were inserted.
144
145 Preserving the order eliminates non-determinism in the output,
146 making it easier for the user to compare repeated invocations. */
147
148class object : public value
149{
150 public:
151 ~object ();
152
153 enum kind get_kind () const final override { return JSON_OBJECT; }
154 void print (pretty_printer *pp, bool formatted) const final override;
155 std::unique_ptr<value> clone () const final override;
156
157 object *dyn_cast_object () final override { return this; }
158
159 bool is_empty () const { return m_map.is_empty (); }
160
161 void set (const char *key, value *v);
162
163 /* Set the property KEY of this object, requiring V
164 to be of a specific json::value subclass.
165
166 This can be used to enforce type-checking, making it easier
167 to comply with a schema, e.g.
168 obj->set<some_subclass> ("property_name", value)
169 leading to a compile-time error if VALUE is not of the
170 appropriate subclass. */
171 template <typename JsonType>
172 void set (const char *key, std::unique_ptr<JsonType> v)
173 {
174 set (key, v.release ());
175 }
176
177 value *get (const char *key) const;
178
179 void set_string (const char *key, const char *utf8_value);
180 void set_integer (const char *key, long v);
181 void set_float (const char *key, double v);
182
183 /* Set to literal true/false. */
184 void set_bool (const char *key, bool v);
185
186 static int compare (const json::object &obj_a, const json::object &obj_b);
187
188 size_t get_num_keys () const { return m_keys.length (); }
189 const char *get_key (size_t i) const { return m_keys[i]; }
190
191 std::unique_ptr<object> clone_as_object () const;
192
193 private:
194 typedef hash_map <char *, value *,
197
198 /* Keep track of order in which keys were inserted. */
199 auto_vec <const char *> m_keys;
200};
201
202/* Subclass of value for arrays. */
203
204class array : public value
205{
206 public:
207 ~array ();
208
209 enum kind get_kind () const final override { return JSON_ARRAY; }
210 void print (pretty_printer *pp, bool formatted) const final override;
211 std::unique_ptr<value> clone () const final override;
212
213 void append (value *v);
214 void append_string (const char *utf8_value);
215
216 /* Append V to this array, requiring V
217 to be a specific json::value subclass.
218
219 This can be used to enforce type-checking, making it easier
220 to comply with a schema, e.g.
221 arr->append<some_subclass> (value)
222 leading to a compile-time error if VALUE is not of the
223 appropriate subclass. */
224 template <typename JsonType>
225 void append (std::unique_ptr<JsonType> v)
226 {
227 append (v.release ());
228 }
229
230 size_t size () const { return m_elements.length (); }
231 value *operator[] (size_t i) const { return m_elements[i]; }
232
233 value **begin () { return m_elements.begin (); }
234 value **end () { return m_elements.end (); }
235 const value * const *begin () const { return m_elements.begin (); }
236 const value * const *end () const { return m_elements.end (); }
237 size_t length () const { return m_elements.length (); }
238 value *get (size_t idx) const { return m_elements[idx]; }
239
240 private:
242};
243
244/* Subclass of value for floating-point numbers. */
245
246class float_number : public value
247{
248 public:
250
251 enum kind get_kind () const final override { return JSON_FLOAT; }
252 void print (pretty_printer *pp, bool formatted) const final override;
253 std::unique_ptr<value> clone () const final override;
254
255 double get () const { return m_value; }
256
257 private:
258 double m_value;
259};
260
261/* Subclass of value for integer-valued numbers. */
262
263class integer_number : public value
264{
265 public:
267
268 enum kind get_kind () const final override { return JSON_INTEGER; }
269 void print (pretty_printer *pp, bool formatted) const final override;
270 std::unique_ptr<value> clone () const final override;
271
272 long get () const { return m_value; }
273
274 private:
276};
277
278
279/* Subclass of value for strings. */
280
281class string : public value
282{
283 public:
284 explicit string (const char *utf8);
285 string (const char *utf8, size_t len);
287
288 enum kind get_kind () const final override { return JSON_STRING; }
289 void print (pretty_printer *pp, bool formatted) const final override;
290 std::unique_ptr<value> clone () const final override;
291 string *dyn_cast_string () final override { return this; }
292
293 const char *get_string () const { return m_utf8; }
294 size_t get_length () const { return m_len; }
295
296 private:
297 char *m_utf8;
298 size_t m_len;
299};
300
301/* Subclass of value for the three JSON literals "true", "false",
302 and "null". */
303
304class literal : public value
305{
306 public:
308
309 /* Construct literal for a boolean value. */
311
312 enum kind get_kind () const final override { return m_kind; }
313 void print (pretty_printer *pp, bool formatted) const final override;
314 std::unique_ptr<value> clone () const final override;
315
316 private:
318};
319
320} // namespace json
321
322template <>
323template <>
324inline bool
325is_a_helper <json::value *>::test (json::value *)
326{
327 return true;
328}
329
330template <>
331template <>
332inline bool
334{
335 return true;
336}
337
338template <>
339template <>
340inline bool
342{
343 return jv->get_kind () == json::JSON_OBJECT;
344}
345
346template <>
347template <>
348inline bool
350{
351 return jv->get_kind () == json::JSON_OBJECT;
352}
353
354template <>
355template <>
356inline bool
358{
359 return jv->get_kind () == json::JSON_ARRAY;
360}
361
362template <>
363template <>
364inline bool
366{
367 return jv->get_kind () == json::JSON_ARRAY;
368}
369
370template <>
371template <>
372inline bool
374{
375 return jv->get_kind () == json::JSON_FLOAT;
376}
377
378template <>
379template <>
380inline bool
382{
383 return jv->get_kind () == json::JSON_FLOAT;
384}
385
386template <>
387template <>
388inline bool
390{
391 return jv->get_kind () == json::JSON_INTEGER;
392}
393
394template <>
395template <>
396inline bool
398{
399 return jv->get_kind () == json::JSON_INTEGER;
400}
401
402template <>
403template <>
404inline bool
406{
407 return jv->get_kind () == json::JSON_STRING;
408}
409
410template <>
411template <>
412inline bool
414{
415 return jv->get_kind () == json::JSON_STRING;
416}
417
418#if CHECKING_P
419
420namespace selftest {
421
422class location;
423
424extern void assert_print_eq (const location &loc,
425 const json::value &jv,
426 bool formatted,
427 const char *expected_json);
428
429} // namespace selftest
430
431#endif /* #if CHECKING_P */
432
433#endif /* GCC_JSON_H */
Definition vec.h:1667
Definition hash-map.h:40
Definition json.h:205
value ** end()
Definition json.h:234
enum kind get_kind() const final override
Definition json.h:209
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:443
auto_vec< value * > m_elements
Definition json.h:241
void append_string(const char *utf8_value)
Definition json.cc:492
const value *const * end() const
Definition json.h:236
~array()
Definition json.cc:432
size_t size() const
Definition json.h:230
value ** begin()
Definition json.h:233
value * operator[](size_t i) const
Definition json.h:231
size_t length() const
Definition json.h:237
std::unique_ptr< value > clone() const final override
Definition json.cc:471
value * get(size_t idx) const
Definition json.h:238
const value *const * begin() const
Definition json.h:235
void append(value *v)
Definition json.cc:484
Definition json.h:247
enum kind get_kind() const final override
Definition json.h:251
float_number(double value)
Definition json.h:249
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:503
std::unique_ptr< value > clone() const final override
Definition json.cc:512
double get() const
Definition json.h:255
double m_value
Definition json.h:258
Definition json.h:264
long m_value
Definition json.h:275
enum kind get_kind() const final override
Definition json.h:268
integer_number(long value)
Definition json.h:266
long get() const
Definition json.h:272
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:522
std::unique_ptr< value > clone() const final override
Definition json.cc:531
Definition json.h:305
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:576
literal(bool value)
Definition json.h:310
enum kind m_kind
Definition json.h:317
literal(enum kind kind)
Definition json.h:307
std::unique_ptr< value > clone() const final override
Definition json.cc:596
enum kind get_kind() const final override
Definition json.h:312
Definition json.h:149
hash_map< char *, value *, simple_hashmap_traits< nofree_string_hash, value * > > map_t
Definition json.h:195
void set(const char *key, value *v)
Definition json.cc:320
void set_string(const char *key, const char *utf8_value)
Definition json.cc:365
size_t get_num_keys() const
Definition json.h:188
void set_float(const char *key, double v)
Definition json.cc:383
enum kind get_kind() const final override
Definition json.h:153
auto_vec< const char * > m_keys
Definition json.h:199
void set_bool(const char *key, bool v)
Definition json.cc:392
map_t m_map
Definition json.h:196
object * dyn_cast_object() final override
Definition json.h:157
void set_integer(const char *key, long v)
Definition json.cc:374
value * get(const char *key) const
Definition json.cc:350
const char * get_key(size_t i) const
Definition json.h:189
void set(const char *key, std::unique_ptr< JsonType > v)
Definition json.h:172
static int compare(const json::object &obj_a, const json::object &obj_b)
Definition json.cc:400
bool is_empty() const
Definition json.h:159
std::unique_ptr< value > clone() const final override
Definition json.cc:293
~object()
Definition json.cc:242
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:254
std::unique_ptr< object > clone_as_object() const
Definition json.cc:299
Definition json.h:282
string(const char *utf8)
Definition json.cc:540
enum kind get_kind() const final override
Definition json.h:288
~string()
Definition json.h:286
const char * get_string() const
Definition json.h:293
size_t m_len
Definition json.h:298
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:559
char * m_utf8
Definition json.h:297
std::unique_ptr< value > clone() const final override
Definition json.cc:566
size_t get_length() const
Definition json.h:294
string * dyn_cast_string() final override
Definition json.h:291
Definition json.h:122
virtual string * dyn_cast_string()
Definition json.h:133
virtual enum kind get_kind() const =0
virtual std::unique_ptr< value > clone() const =0
virtual object * dyn_cast_object()
Definition json.h:132
static int compare(const json::value &val_a, const json::value &val_b)
Definition json.cc:163
virtual void print(pretty_printer *pp, bool formatted) const =0
void DEBUG_FUNCTION dump() const
Definition json.cc:143
const pointer::token & get_pointer_token() const
Definition json.h:137
pointer::token m_pointer_token
Definition json.h:139
virtual ~value()
Definition json.h:124
Definition pretty-print.h:241
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2009
free(str)
Definition json.h:76
Definition json-parsing.h:27
kind
Definition json.h:53
@ JSON_ARRAY
Definition json.h:58
@ JSON_FALSE
Definition json.h:72
@ JSON_INTEGER
Definition json.h:61
@ JSON_NULL
Definition json.h:73
@ JSON_OBJECT
Definition json.h:55
@ JSON_TRUE
Definition json.h:71
@ JSON_FLOAT
Definition json.h:64
@ JSON_STRING
Definition json.h:67
Definition dump-context.h:31
i
Definition poly-int.h:776
static bool test(const U *p)
Definition is-a.h:211
Definition is-a.h:194
static bool test(U *p)
Definition json.h:86
union json::pointer::token::u m_data
json::value * m_parent
Definition json.h:108
token()
Definition json.cc:79
~token()
Definition json.cc:100
enum kind m_kind
Definition json.h:114
kind
Definition json.h:88
@ object_member
Definition json.h:90
@ array_index
Definition json.h:91
@ root_value
Definition json.h:89
token(token &&other)=delete
token & operator=(const token &other)=delete
token(const token &other)=delete
Definition hash-map-traits.h:33
#define DEBUG_FUNCTION
Definition system.h:1236
Definition json.h:110
char * u_member
Definition json.h:111
size_t u_index
Definition json.h:112