GCC Middle and Back End API Reference
json.h
Go to the documentation of this file.
1/* JSON trees
2 Copyright (C) 2017-2024 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
76/* Base class of JSON value. */
77
78class value
79{
80 public:
81 virtual ~value () {}
82 virtual enum kind get_kind () const = 0;
83 virtual void print (pretty_printer *pp, bool formatted) const = 0;
84
85 void dump (FILE *, bool formatted) const;
86 void DEBUG_FUNCTION dump () const;
87};
88
89/* Subclass of value for objects: a collection of key/value pairs
90 preserving the ordering in which keys were inserted.
91
92 Preserving the order eliminates non-determinism in the output,
93 making it easier for the user to compare repeated invocations. */
94
95class object : public value
96{
97 public:
98 ~object ();
99
100 enum kind get_kind () const final override { return JSON_OBJECT; }
101 void print (pretty_printer *pp, bool formatted) const final override;
102
103 bool is_empty () const { return m_map.is_empty (); }
104
105 void set (const char *key, value *v);
106
107 /* Set the property KEY of this object, requiring V
108 to be of a specific json::value subclass.
109
110 This can be used to enforce type-checking, making it easier
111 to comply with a schema, e.g.
112 obj->set<some_subclass> ("property_name", value)
113 leading to a compile-time error if VALUE is not of the
114 appropriate subclass. */
115 template <typename JsonType>
116 void set (const char *key, std::unique_ptr<JsonType> v)
117 {
118 set (key, v.release ());
119 }
120
121 value *get (const char *key) const;
122
123 void set_string (const char *key, const char *utf8_value);
124 void set_integer (const char *key, long v);
125 void set_float (const char *key, double v);
126
127 /* Set to literal true/false. */
128 void set_bool (const char *key, bool v);
129
130 private:
131 typedef hash_map <char *, value *,
134
135 /* Keep track of order in which keys were inserted. */
136 auto_vec <const char *> m_keys;
137};
138
139/* Subclass of value for arrays. */
140
141class array : public value
142{
143 public:
144 ~array ();
145
146 enum kind get_kind () const final override { return JSON_ARRAY; }
147 void print (pretty_printer *pp, bool formatted) const final override;
148
149 void append (value *v);
150 void append_string (const char *utf8_value);
151
152 /* Append V to this array, requiring V
153 to be a specific json::value subclass.
154
155 This can be used to enforce type-checking, making it easier
156 to comply with a schema, e.g.
157 arr->append<some_subclass> (value)
158 leading to a compile-time error if VALUE is not of the
159 appropriate subclass. */
160 template <typename JsonType>
161 void append (std::unique_ptr<JsonType> v)
162 {
163 append (v.release ());
164 }
165
166 size_t size () const { return m_elements.length (); }
167 value *operator[] (size_t i) const { return m_elements[i]; }
168
169 value **begin () { return m_elements.begin (); }
170 value **end () { return m_elements.end (); }
171 const value * const *begin () const { return m_elements.begin (); }
172 const value * const *end () const { return m_elements.end (); }
173 size_t length () const { return m_elements.length (); }
174 value *get (size_t idx) const { return m_elements[idx]; }
175
176 private:
178};
179
180/* Subclass of value for floating-point numbers. */
181
182class float_number : public value
183{
184 public:
186
187 enum kind get_kind () const final override { return JSON_FLOAT; }
188 void print (pretty_printer *pp, bool formatted) const final override;
189
190 double get () const { return m_value; }
191
192 private:
193 double m_value;
194};
195
196/* Subclass of value for integer-valued numbers. */
197
198class integer_number : public value
199{
200 public:
202
203 enum kind get_kind () const final override { return JSON_INTEGER; }
204 void print (pretty_printer *pp, bool formatted) const final override;
205
206 long get () const { return m_value; }
207
208 private:
210};
211
212
213/* Subclass of value for strings. */
214
215class string : public value
216{
217 public:
218 explicit string (const char *utf8);
219 string (const char *utf8, size_t len);
221
222 enum kind get_kind () const final override { return JSON_STRING; }
223 void print (pretty_printer *pp, bool formatted) const final override;
224
225 const char *get_string () const { return m_utf8; }
226 size_t get_length () const { return m_len; }
227
228 private:
229 char *m_utf8;
230 size_t m_len;
231};
232
233/* Subclass of value for the three JSON literals "true", "false",
234 and "null". */
235
236class literal : public value
237{
238 public:
240
241 /* Construct literal for a boolean value. */
243
244 enum kind get_kind () const final override { return m_kind; }
245 void print (pretty_printer *pp, bool formatted) const final override;
246
247 private:
249};
250
251} // namespace json
252
253template <>
254template <>
255inline bool
257{
258 return true;
259}
260
261template <>
262template <>
263inline bool
265{
266 return true;
267}
268
269template <>
270template <>
271inline bool
273{
274 return jv->get_kind () == json::JSON_OBJECT;
275}
276
277template <>
278template <>
279inline bool
281{
282 return jv->get_kind () == json::JSON_OBJECT;
283}
284
285template <>
286template <>
287inline bool
289{
290 return jv->get_kind () == json::JSON_ARRAY;
291}
292
293template <>
294template <>
295inline bool
297{
298 return jv->get_kind () == json::JSON_ARRAY;
299}
300
301template <>
302template <>
303inline bool
305{
306 return jv->get_kind () == json::JSON_FLOAT;
307}
308
309template <>
310template <>
311inline bool
313{
314 return jv->get_kind () == json::JSON_FLOAT;
315}
316
317template <>
318template <>
319inline bool
321{
322 return jv->get_kind () == json::JSON_INTEGER;
323}
324
325template <>
326template <>
327inline bool
329{
330 return jv->get_kind () == json::JSON_INTEGER;
331}
332
333template <>
334template <>
335inline bool
337{
338 return jv->get_kind () == json::JSON_STRING;
339}
340
341template <>
342template <>
343inline bool
345{
346 return jv->get_kind () == json::JSON_STRING;
347}
348
349#if CHECKING_P
350
351namespace selftest {
352
353class location;
354
355extern void assert_print_eq (const location &loc,
356 const json::value &jv,
357 bool formatted,
358 const char *expected_json);
359
360} // namespace selftest
361
362#endif /* #if CHECKING_P */
363
364#endif /* GCC_JSON_H */
Definition vec.h:1656
Definition hash-map.h:40
bool is_empty() const
Definition hash-map.h:252
Definition json.h:142
value ** end()
Definition json.h:170
enum kind get_kind() const final override
Definition json.h:146
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:254
auto_vec< value * > m_elements
Definition json.h:177
void append_string(const char *utf8_value)
Definition json.cc:291
const value *const * end() const
Definition json.h:172
~array()
Definition json.cc:243
size_t size() const
Definition json.h:166
value ** begin()
Definition json.h:169
value * operator[](size_t i) const
Definition json.h:167
size_t length() const
Definition json.h:173
value * get(size_t idx) const
Definition json.h:174
const value *const * begin() const
Definition json.h:171
void append(value *v)
Definition json.cc:284
void append(std::unique_ptr< JsonType > v)
Definition json.h:161
Definition json.h:183
enum kind get_kind() const final override
Definition json.h:187
float_number(double value)
Definition json.h:185
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:302
double get() const
Definition json.h:190
double m_value
Definition json.h:193
Definition json.h:199
long m_value
Definition json.h:209
enum kind get_kind() const final override
Definition json.h:203
integer_number(long value)
Definition json.h:201
long get() const
Definition json.h:206
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:315
Definition json.h:237
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:357
literal(bool value)
Definition json.h:242
enum kind m_kind
Definition json.h:248
literal(enum kind kind)
Definition json.h:239
enum kind get_kind() const final override
Definition json.h:244
Definition json.h:96
void set(const char *key, value *v)
Definition json.cc:163
void set_string(const char *key, const char *utf8_value)
Definition json.cc:206
void set_float(const char *key, double v)
Definition json.cc:224
enum kind get_kind() const final override
Definition json.h:100
auto_vec< const char * > m_keys
Definition json.h:136
hash_map< char *, value *, simple_hashmap_traits< nofree_string_hash, value * > > map_t
Definition json.h:132
void set_bool(const char *key, bool v)
Definition json.cc:233
map_t m_map
Definition json.h:133
void set_integer(const char *key, long v)
Definition json.cc:215
value * get(const char *key) const
Definition json.cc:191
void set(const char *key, std::unique_ptr< JsonType > v)
Definition json.h:116
bool is_empty() const
Definition json.h:103
~object()
Definition json.cc:109
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:121
Definition json.h:216
string(const char *utf8)
Definition json.cc:328
enum kind get_kind() const final override
Definition json.h:222
~string()
Definition json.h:220
const char * get_string() const
Definition json.h:225
size_t m_len
Definition json.h:230
void print(pretty_printer *pp, bool formatted) const final override
Definition json.cc:346
char * m_utf8
Definition json.h:229
size_t get_length() const
Definition json.h:226
Definition json.h:79
virtual enum kind get_kind() const =0
virtual void print(pretty_printer *pp, bool formatted) const =0
void DEBUG_FUNCTION dump() const
Definition json.cc:98
virtual ~value()
Definition json.h:81
Definition pretty-print.h:241
void final(rtx_insn *first, FILE *file, int optimize_p)
Definition final.cc:2002
free(str)
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 hash-map-traits.h:33
#define DEBUG_FUNCTION
Definition system.h:1236