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
128 void dump (FILE *, bool formatted) const;
129 void DEBUG_FUNCTION dump () const;
130
131 virtual object *dyn_cast_object () { return nullptr; }
132
133 static int compare (const json::value &val_a, const json::value &val_b);
134
136
138};
139
140/* Subclass of value for objects: a collection of key/value pairs
141 preserving the ordering in which keys were inserted.
142
143 Preserving the order eliminates non-determinism in the output,
144 making it easier for the user to compare repeated invocations. */
145
146class object : public value
147{
148 public:
149 ~object ();
150
151 enum kind get_kind () const final override { return JSON_OBJECT; }
152 void print (pretty_printer *pp, bool formatted) const final override;
153
154 object *dyn_cast_object () final override { return this; }
155
156 bool is_empty () const { return m_map.is_empty (); }
157
158 void set (const char *key, value *v);
159
160 /* Set the property KEY of this object, requiring V
161 to be of a specific json::value subclass.
162
163 This can be used to enforce type-checking, making it easier
164 to comply with a schema, e.g.
165 obj->set<some_subclass> ("property_name", value)
166 leading to a compile-time error if VALUE is not of the
167 appropriate subclass. */
168 template <typename JsonType>
169 void set (const char *key, std::unique_ptr<JsonType> v)
170 {
171 set (key, v.release ());
172 }
173
174 value *get (const char *key) const;
175
176 void set_string (const char *key, const char *utf8_value);
177 void set_integer (const char *key, long v);
178 void set_float (const char *key, double v);
179
180 /* Set to literal true/false. */
181 void set_bool (const char *key, bool v);
182
183 static int compare (const json::object &obj_a, const json::object &obj_b);
184
185 private:
186 typedef hash_map <char *, value *,
189
190 /* Keep track of order in which keys were inserted. */
191 auto_vec <const char *> m_keys;
192};
193
194/* Subclass of value for arrays. */
195
196class array : public value
197{
198 public:
199 ~array ();
200
201 enum kind get_kind () const final override { return JSON_ARRAY; }
202 void print (pretty_printer *pp, bool formatted) const final override;
203
204 void append (value *v);
205 void append_string (const char *utf8_value);
206
207 /* Append V to this array, requiring V
208 to be a specific json::value subclass.
209
210 This can be used to enforce type-checking, making it easier
211 to comply with a schema, e.g.
212 arr->append<some_subclass> (value)
213 leading to a compile-time error if VALUE is not of the
214 appropriate subclass. */
215 template <typename JsonType>
216 void append (std::unique_ptr<JsonType> v)
217 {
218 append (v.release ());
219 }
220
221 size_t size () const { return m_elements.length (); }
222 value *operator[] (size_t i) const { return m_elements[i]; }
223
224 value **begin () { return m_elements.begin (); }
225 value **end () { return m_elements.end (); }
226 const value * const *begin () const { return m_elements.begin (); }
227 const value * const *end () const { return m_elements.end (); }
228 size_t length () const { return m_elements.length (); }
229 value *get (size_t idx) const { return m_elements[idx]; }
230
231 private:
233};
234
235/* Subclass of value for floating-point numbers. */
236
237class float_number : public value
238{
239 public:
241
242 enum kind get_kind () const final override { return JSON_FLOAT; }
243 void print (pretty_printer *pp, bool formatted) const final override;
244
245 double get () const { return m_value; }
246
247 private:
248 double m_value;
249};
250
251/* Subclass of value for integer-valued numbers. */
252
253class integer_number : public value
254{
255 public:
257
258 enum kind get_kind () const final override { return JSON_INTEGER; }
259 void print (pretty_printer *pp, bool formatted) const final override;
260
261 long get () const { return m_value; }
262
263 private:
265};
266
267
268/* Subclass of value for strings. */
269
270class string : public value
271{
272 public:
273 explicit string (const char *utf8);
274 string (const char *utf8, size_t len);
276
277 enum kind get_kind () const final override { return JSON_STRING; }
278 void print (pretty_printer *pp, bool formatted) const final override;
279
280 const char *get_string () const { return m_utf8; }
281 size_t get_length () const { return m_len; }
282
283 private:
284 char *m_utf8;
285 size_t m_len;
286};
287
288/* Subclass of value for the three JSON literals "true", "false",
289 and "null". */
290
291class literal : public value
292{
293 public:
295
296 /* Construct literal for a boolean value. */
298
299 enum kind get_kind () const final override { return m_kind; }
300 void print (pretty_printer *pp, bool formatted) const final override;
301
302 private:
304};
305
306} // namespace json
307
308template <>
309template <>
310inline bool
312{
313 return true;
314}
315
316template <>
317template <>
318inline bool
320{
321 return true;
322}
323
324template <>
325template <>
326inline bool
328{
329 return jv->get_kind () == json::JSON_OBJECT;
330}
331
332template <>
333template <>
334inline bool
336{
337 return jv->get_kind () == json::JSON_OBJECT;
338}
339
340template <>
341template <>
342inline bool
344{
345 return jv->get_kind () == json::JSON_ARRAY;
346}
347
348template <>
349template <>
350inline bool
352{
353 return jv->get_kind () == json::JSON_ARRAY;
354}
355
356template <>
357template <>
358inline bool
360{
361 return jv->get_kind () == json::JSON_FLOAT;
362}
363
364template <>
365template <>
366inline bool
368{
369 return jv->get_kind () == json::JSON_FLOAT;
370}
371
372template <>
373template <>
374inline bool
376{
377 return jv->get_kind () == json::JSON_INTEGER;
378}
379
380template <>
381template <>
382inline bool
384{
385 return jv->get_kind () == json::JSON_INTEGER;
386}
387
388template <>
389template <>
390inline bool
392{
393 return jv->get_kind () == json::JSON_STRING;
394}
395
396template <>
397template <>
398inline bool
400{
401 return jv->get_kind () == json::JSON_STRING;
402}
403
404#if CHECKING_P
405
406namespace selftest {
407
408class location;
409
410extern void assert_print_eq (const location &loc,
411 const json::value &jv,
412 bool formatted,
413 const char *expected_json);
414
415} // namespace selftest
416
417#endif /* #if CHECKING_P */
418
419#endif /* GCC_JSON_H */
Definition vec.h:1667
Definition hash-map.h:40
Definition json.h:197
value ** end()
Definition json.h:225
enum kind get_kind() const final override
Definition json.h:201
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:419
auto_vec< value * > m_elements
Definition json.h:232
void append_string(const char *utf8_value)
Definition json.cc:457
const value *const * end() const
Definition json.h:227
~array()
Definition json.cc:408
size_t size() const
Definition json.h:221
value ** begin()
Definition json.h:224
value * operator[](size_t i) const
Definition json.h:222
size_t length() const
Definition json.h:228
value * get(size_t idx) const
Definition json.h:229
const value *const * begin() const
Definition json.h:226
void append(value *v)
Definition json.cc:449
void append(std::unique_ptr< JsonType > v)
Definition json.h:216
Definition json.h:238
enum kind get_kind() const final override
Definition json.h:242
float_number(double value)
Definition json.h:240
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:468
double get() const
Definition json.h:245
double m_value
Definition json.h:248
Definition json.h:254
long m_value
Definition json.h:264
enum kind get_kind() const final override
Definition json.h:258
integer_number(long value)
Definition json.h:256
long get() const
Definition json.h:261
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:481
Definition json.h:292
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:523
literal(bool value)
Definition json.h:297
enum kind m_kind
Definition json.h:303
literal(enum kind kind)
Definition json.h:294
enum kind get_kind() const final override
Definition json.h:299
Definition json.h:147
hash_map< char *, value *, simple_hashmap_traits< nofree_string_hash, value * > > map_t
Definition json.h:187
void set(const char *key, value *v)
Definition json.cc:296
void set_string(const char *key, const char *utf8_value)
Definition json.cc:341
void set_float(const char *key, double v)
Definition json.cc:359
enum kind get_kind() const final override
Definition json.h:151
auto_vec< const char * > m_keys
Definition json.h:191
void set_bool(const char *key, bool v)
Definition json.cc:368
map_t m_map
Definition json.h:188
object * dyn_cast_object() final override
Definition json.h:154
void set_integer(const char *key, long v)
Definition json.cc:350
value * get(const char *key) const
Definition json.cc:326
void set(const char *key, std::unique_ptr< JsonType > v)
Definition json.h:169
static int compare(const json::object &obj_a, const json::object &obj_b)
Definition json.cc:376
bool is_empty() const
Definition json.h:156
~object()
Definition json.cc:242
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:254
Definition json.h:271
string(const char *utf8)
Definition json.cc:494
enum kind get_kind() const final override
Definition json.h:277
~string()
Definition json.h:275
const char * get_string() const
Definition json.h:280
size_t m_len
Definition json.h:285
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:512
char * m_utf8
Definition json.h:284
size_t get_length() const
Definition json.h:281
Definition json.h:122
virtual enum kind get_kind() const =0
virtual object * dyn_cast_object()
Definition json.h:131
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:135
pointer::token m_pointer_token
Definition json.h:137
virtual ~value()
Definition json.h:124
Definition pretty-print.h:241
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2008
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(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