GCC Middle and Back End API Reference
json.h
Go to the documentation of this file.
1/* JSON trees
2 Copyright (C) 2017-2026 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#include "label-text.h"
25
26/* Implementation of JSON, a lightweight data-interchange format.
27
28 See http://www.json.org/
29 and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
30 and https://tools.ietf.org/html/rfc7159
31
32 Supports parsing text into a DOM-like tree of json::value *, directly
33 creating such trees, and dumping json::value * to text. */
34
35/* TODO: `libcpp/mkdeps.cc` wants JSON writing support for p1689r5 output;
36 extract this code and move to libiberty. */
37
38namespace json
39{
40
41/* Forward decls of json::value and its subclasses (using indentation
42 to denote inheritance. */
43
44class value;
45 class object;
46 class array;
47 class float_number;
48 class integer_number;
49 class string;
50 class literal;
51
52/* An enum for discriminating the subclasses of json::value. */
53
54enum kind
55{
56 /* class json::object. */
58
59 /* class json::array. */
61
62 /* class json::integer_number. */
64
65 /* class json::float_number. */
67
68 /* class json::string. */
70
71 /* class json::literal uses these three values to identify the
72 particular literal. */
76};
77
78namespace pointer { // json::pointer
79
80/* Implementation of JSON pointer (RFC 6901). */
81
82/* A token within a JSON pointer, expressing the parent of a particular
83 JSON value, and how it is descended from that parent.
84
85 A JSON pointer can be built as a list of these tokens. */
86
87struct token
88{
95
96 token ();
97 token (json::object &parent, const char *member);
98 token (json::array &parent, size_t index);
99 token (const token &other) = delete;
100 token (token &&other) = delete;
101
102 ~token ();
103
104 token &
105 operator= (const token &other) = delete;
106
107 token &
108 operator= (token &&other);
109
110 void print (pretty_printer *pp) const;
111
113 union u
114 {
115 char *u_member;
116 size_t u_index;
119};
120
121} // namespace json::pointer
122
123/* Typesafe way to work with properties in JSON objects. */
124
125template <typename Traits>
127{
128 explicit property (const char *key)
129 : m_key (label_text::borrow (key))
130 {}
131
132 explicit property (const char *key_prefix, const char *key)
133 : m_key (label_text::take (concat (key_prefix, key, nullptr)))
134 {}
135
136 label_text m_key;
137};
138
144
145template <typename EnumType>
147{
148 typedef EnumType enum_t;
149
151 static bool maybe_get_value_from_string (const char *, enum_t &out);
152 static const char *get_string_for_value (enum_t value);
153};
154
155template <typename EnumType>
157
158/* Base class of JSON value. */
159
160class value
161{
162 public:
163 virtual ~value () {}
164 virtual enum kind get_kind () const = 0;
165 virtual void print (pretty_printer *pp, bool formatted) const = 0;
166 virtual std::unique_ptr<value> clone () const = 0;
167
168 void dump (FILE *, bool formatted) const;
169 void DEBUG_FUNCTION dump () const;
170
171 virtual object *dyn_cast_object () { return nullptr; }
172 virtual array *dyn_cast_array () { return nullptr; }
173 virtual integer_number *dyn_cast_integer_number () { return nullptr; }
174 virtual string *dyn_cast_string () { return nullptr; }
175
176 static int compare (const json::value &val_a, const json::value &val_b);
177
179 void print_pointer (pretty_printer *pp) const;
180
182};
183
184/* Subclass of value for objects: a collection of key/value pairs
185 preserving the ordering in which keys were inserted.
186
187 Preserving the order eliminates non-determinism in the output,
188 making it easier for the user to compare repeated invocations. */
189
190class object : public value
191{
192 public:
193 ~object ();
194
195 typedef hash_map <char *, value *,
197
198 enum kind get_kind () const final override { return JSON_OBJECT; }
199 void print (pretty_printer *pp, bool formatted) const final override;
200 std::unique_ptr<value> clone () const final override;
201
202 object *dyn_cast_object () final override { return this; }
203
204 bool is_empty () const { return m_map.is_empty (); }
205
206 void set (const char *key, value *v);
207
208 /* Set the property KEY of this object, requiring V
209 to be of a specific json::value subclass.
210
211 This can be used to enforce type-checking, making it easier
212 to comply with a schema, e.g.
213 obj->set<some_subclass> ("property_name", value)
214 leading to a compile-time error if VALUE is not of the
215 appropriate subclass. */
216 template <typename JsonType>
217 void set (const char *key, std::unique_ptr<JsonType> v)
218 {
219 set (key, v.release ());
220 }
221
222 value *get (const char *key) const;
223 const map_t &get_map () const { return m_map; }
224
225 void set_string (const char *key, const char *utf8_value);
226 void set_integer (const char *key, long v);
227 void set_float (const char *key, double v);
228
229 /* Set to literal true/false. */
230 void set_bool (const char *key, bool v);
231
232 /* Typesafe access to properties by name (such as from a schema). */
233 void set_string (const string_property &property, const char *utf8_value);
234 void set_integer (const integer_property &property, long value);
235 void set_bool (const bool_property &property, bool value);
237 std::unique_ptr<json::array> value);
238 template <typename EnumType>
240 EnumType &out) const;
241 template <typename EnumType>
243 EnumType value);
244
245 static int compare (const json::object &obj_a, const json::object &obj_b);
246
247 size_t get_num_keys () const { return m_keys.length (); }
248 const char *get_key (size_t i) const { return m_keys[i]; }
249
250 std::unique_ptr<object> clone_as_object () const;
251
252 private:
254
255 /* Keep track of order in which keys were inserted. */
256 auto_vec <const char *> m_keys;
257};
258
259/* Subclass of value for arrays. */
260
261class array : public value
262{
263 public:
264 ~array ();
265
266 enum kind get_kind () const final override { return JSON_ARRAY; }
267 void print (pretty_printer *pp, bool formatted) const final override;
268 std::unique_ptr<value> clone () const final override;
269
270 array *dyn_cast_array () final override { return this; }
271
272 void append (value *v);
273 void append_string (const char *utf8_value);
274
275 /* Append V to this array, requiring V
276 to be a specific json::value subclass.
277
278 This can be used to enforce type-checking, making it easier
279 to comply with a schema, e.g.
280 arr->append<some_subclass> (value)
281 leading to a compile-time error if VALUE is not of the
282 appropriate subclass. */
283 template <typename JsonType>
284 void append (std::unique_ptr<JsonType> v)
285 {
286 append (v.release ());
287 }
288
289 size_t size () const { return m_elements.length (); }
290 value *operator[] (size_t i) const { return m_elements[i]; }
291
292 value **begin () { return m_elements.begin (); }
293 value **end () { return m_elements.end (); }
294 const value * const *begin () const { return m_elements.begin (); }
295 const value * const *end () const { return m_elements.end (); }
296 size_t length () const { return m_elements.length (); }
297 value *get (size_t idx) const { return m_elements[idx]; }
298
299 private:
301};
302
303/* Subclass of value for floating-point numbers. */
304
305class float_number : public value
306{
307 public:
309
310 enum kind get_kind () const final override { return JSON_FLOAT; }
311 void print (pretty_printer *pp, bool formatted) const final override;
312 std::unique_ptr<value> clone () const final override;
313
314 double get () const { return m_value; }
315
316 private:
317 double m_value;
318};
319
320/* Subclass of value for integer-valued numbers. */
321
322class integer_number : public value
323{
324 public:
326
327 enum kind get_kind () const final override { return JSON_INTEGER; }
328 void print (pretty_printer *pp, bool formatted) const final override;
329 std::unique_ptr<value> clone () const final override;
330
331 integer_number *dyn_cast_integer_number () final override { return this; }
332
333 long get () const { return m_value; }
334
335 private:
337};
338
339
340/* Subclass of value for strings. */
341
342class string : public value
343{
344 public:
345 explicit string (const char *utf8);
346 string (const char *utf8, size_t len);
348
349 enum kind get_kind () const final override { return JSON_STRING; }
350 void print (pretty_printer *pp, bool formatted) const final override;
351 std::unique_ptr<value> clone () const final override;
352 string *dyn_cast_string () final override { return this; }
353
354 const char *get_string () const { return m_utf8; }
355 size_t get_length () const { return m_len; }
356
357 private:
358 char *m_utf8;
359 size_t m_len;
360};
361
362/* Subclass of value for the three JSON literals "true", "false",
363 and "null". */
364
365class literal : public value
366{
367 public:
369
370 /* Construct literal for a boolean value. */
372
373 enum kind get_kind () const final override { return m_kind; }
374 void print (pretty_printer *pp, bool formatted) const final override;
375 std::unique_ptr<value> clone () const final override;
376
377 private:
379};
380
381
382template <typename EnumType>
383inline bool
384object::maybe_get_enum (const enum_property<EnumType> &property,
385 EnumType &out) const
386{
387 if (value *jv = get (property.m_key.get ()))
388 if (string *jstr = jv->dyn_cast_string ())
389 {
390 if (enum_traits<EnumType>::maybe_get_value_from_string
391 (jstr->get_string (), out))
392 return true;
393 }
394 return false;
395}
396
397template <typename EnumType>
398inline void
400 EnumType value)
401{
402 const char *str
404 set_string (property.m_key.get (), str);
405}
406
407} // namespace json
408
409template <>
410template <>
411inline bool
413{
414 return true;
415}
416
417template <>
418template <>
419inline bool
421{
422 return true;
423}
424
425template <>
426template <>
427inline bool
429{
430 return jv->get_kind () == json::JSON_OBJECT;
431}
432
433template <>
434template <>
435inline bool
437{
438 return jv->get_kind () == json::JSON_OBJECT;
439}
440
441template <>
442template <>
443inline bool
445{
446 return jv->get_kind () == json::JSON_ARRAY;
447}
448
449template <>
450template <>
451inline bool
453{
454 return jv->get_kind () == json::JSON_ARRAY;
455}
456
457template <>
458template <>
459inline bool
461{
462 return jv->get_kind () == json::JSON_FLOAT;
463}
464
465template <>
466template <>
467inline bool
469{
470 return jv->get_kind () == json::JSON_FLOAT;
471}
472
473template <>
474template <>
475inline bool
477{
478 return jv->get_kind () == json::JSON_INTEGER;
479}
480
481template <>
482template <>
483inline bool
485{
486 return jv->get_kind () == json::JSON_INTEGER;
487}
488
489template <>
490template <>
491inline bool
493{
494 return jv->get_kind () == json::JSON_STRING;
495}
496
497template <>
498template <>
499inline bool
501{
502 return jv->get_kind () == json::JSON_STRING;
503}
504
505template <>
506template <>
507inline bool
509{
510 return (jv->get_kind () == json::JSON_TRUE
511 || jv->get_kind () == json::JSON_FALSE
512 || jv->get_kind () == json::JSON_NULL);
513}
514
515template <>
516template <>
517inline bool
519{
520 return (jv->get_kind () == json::JSON_TRUE
521 || jv->get_kind () == json::JSON_FALSE
522 || jv->get_kind () == json::JSON_NULL);
523}
524
525#if CHECKING_P
526
527namespace selftest {
528
529class location;
530
531extern void assert_print_eq (const location &loc,
532 const json::value &jv,
533 bool formatted,
534 const char *expected_json);
535
536} // namespace selftest
537
538#endif /* #if CHECKING_P */
539
540#endif /* GCC_JSON_H */
Definition vec.h:1667
Definition hash-map.h:40
Definition json.h:262
value ** end()
Definition json.h:293
enum kind get_kind() const final override
Definition json.h:266
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:527
auto_vec< value * > m_elements
Definition json.h:300
void append_string(const char *utf8_value)
Definition json.cc:576
array * dyn_cast_array() final override
Definition json.h:270
const value *const * end() const
Definition json.h:295
~array()
Definition json.cc:516
size_t size() const
Definition json.h:289
value ** begin()
Definition json.h:292
value * operator[](size_t i) const
Definition json.h:290
size_t length() const
Definition json.h:296
std::unique_ptr< value > clone() const final override
Definition json.cc:555
value * get(size_t idx) const
Definition json.h:297
const value *const * begin() const
Definition json.h:294
void append(value *v)
Definition json.cc:568
void append(std::unique_ptr< JsonType > v)
Definition json.h:284
Definition json.h:306
enum kind get_kind() const final override
Definition json.h:310
float_number(double value)
Definition json.h:308
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:587
std::unique_ptr< value > clone() const final override
Definition json.cc:596
double get() const
Definition json.h:314
double m_value
Definition json.h:317
Definition json.h:323
long m_value
Definition json.h:336
enum kind get_kind() const final override
Definition json.h:327
integer_number(long value)
Definition json.h:325
long get() const
Definition json.h:333
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:606
std::unique_ptr< value > clone() const final override
Definition json.cc:615
integer_number * dyn_cast_integer_number() final override
Definition json.h:331
Definition json.h:366
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:660
literal(bool value)
Definition json.h:371
enum kind m_kind
Definition json.h:378
literal(enum kind kind)
Definition json.h:368
std::unique_ptr< value > clone() const final override
Definition json.cc:680
enum kind get_kind() const final override
Definition json.h:373
Definition json.h:191
hash_map< char *, value *, simple_hashmap_traits< nofree_string_hash, value * > > map_t
Definition json.h:196
bool maybe_get_enum(const enum_property< EnumType > &property, EnumType &out) const
Definition json.h:384
void set(const char *key, value *v)
Definition json.cc:379
const map_t & get_map() const
Definition json.h:223
void set_array_of_string(const array_of_string_property &property, std::unique_ptr< json::array > value)
Definition json.cc:475
void set_string(const char *key, const char *utf8_value)
Definition json.cc:424
size_t get_num_keys() const
Definition json.h:247
void set_float(const char *key, double v)
Definition json.cc:442
enum kind get_kind() const final override
Definition json.h:198
auto_vec< const char * > m_keys
Definition json.h:256
void set_bool(const char *key, bool v)
Definition json.cc:451
map_t m_map
Definition json.h:253
object * dyn_cast_object() final override
Definition json.h:202
void set_integer(const char *key, long v)
Definition json.cc:433
value * get(const char *key) const
Definition json.cc:409
const char * get_key(size_t i) const
Definition json.h:248
void set_enum(const enum_property< EnumType > &property, EnumType value)
Definition json.h:399
void set(const char *key, std::unique_ptr< JsonType > v)
Definition json.h:217
static int compare(const json::object &obj_a, const json::object &obj_b)
Definition json.cc:484
bool is_empty() const
Definition json.h:204
std::unique_ptr< value > clone() const final override
Definition json.cc:352
~object()
Definition json.cc:301
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:313
std::unique_ptr< object > clone_as_object() const
Definition json.cc:358
Definition json.h:343
string(const char *utf8)
Definition json.cc:624
enum kind get_kind() const final override
Definition json.h:349
~string()
Definition json.h:347
const char * get_string() const
Definition json.h:354
size_t m_len
Definition json.h:359
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:643
char * m_utf8
Definition json.h:358
std::unique_ptr< value > clone() const final override
Definition json.cc:650
size_t get_length() const
Definition json.h:355
string * dyn_cast_string() final override
Definition json.h:352
Definition json.h:161
virtual string * dyn_cast_string()
Definition json.h:174
virtual enum kind get_kind() const =0
virtual std::unique_ptr< value > clone() const =0
virtual object * dyn_cast_object()
Definition json.h:171
void print_pointer(pretty_printer *pp) const
Definition json.cc:276
static int compare(const json::value &val_a, const json::value &val_b)
Definition json.cc:199
virtual void print(pretty_printer *pp, bool formatted) const =0
virtual integer_number * dyn_cast_integer_number()
Definition json.h:173
void DEBUG_FUNCTION dump() const
Definition json.cc:179
const pointer::token & get_pointer_token() const
Definition json.h:178
pointer::token m_pointer_token
Definition json.h:181
virtual array * dyn_cast_array()
Definition json.h:172
virtual ~value()
Definition json.h:163
Definition pretty-print.h:241
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2009
free(str)
Definition json.h:78
Definition cfghooks.h:27
property< literal > bool_property
Definition json.h:141
property< value > json_property
Definition json.h:142
property< integer_number > integer_property
Definition json.h:140
kind
Definition json.h:55
@ JSON_ARRAY
Definition json.h:60
@ JSON_FALSE
Definition json.h:74
@ JSON_INTEGER
Definition json.h:63
@ JSON_NULL
Definition json.h:75
@ JSON_OBJECT
Definition json.h:57
@ JSON_TRUE
Definition json.h:73
@ JSON_FLOAT
Definition json.h:66
@ JSON_STRING
Definition json.h:69
property< array > array_of_string_property
Definition json.h:143
property< string > string_property
Definition json.h:139
property< enum_traits< EnumType > > enum_property
Definition json.h:156
Definition dump-context.h:31
if(N >=2) for(unsigned int i
i
Definition poly-int.h:776
static bool test(U *p)
Definition json.h:147
EnumType enum_t
Definition json.h:148
static enum_t get_unknown_value()
static bool maybe_get_value_from_string(const char *, enum_t &out)
static const char * get_string_for_value(enum_t value)
Definition json.h:88
void print(pretty_printer *pp) const
Definition json.cc:126
union json::pointer::token::u m_data
json::value * m_parent
Definition json.h:112
token()
Definition json.cc:79
~token()
Definition json.cc:100
enum kind m_kind
Definition json.h:118
kind
Definition json.h:90
@ object_member
Definition json.h:92
@ array_index
Definition json.h:93
@ root_value
Definition json.h:91
token(token &&other)=delete
token & operator=(const token &other)=delete
token(const token &other)=delete
Definition json.h:127
property(const char *key_prefix, const char *key)
Definition json.h:132
label_text m_key
Definition json.h:136
property(const char *key)
Definition json.h:128
Definition hash-map-traits.h:33
#define DEBUG_FUNCTION
Definition system.h:1191
Definition json.h:114
char * u_member
Definition json.h:115
size_t u_index
Definition json.h:116