@@ -57,19 +57,22 @@ class JSONLoader {
5757 std::unordered_map<int , IR::Node *> &node_refs;
5858 std::unique_ptr<JsonData> json_root;
5959 const JsonData *json = nullptr ;
60+ JsonData::LocationInfo *locinfo = nullptr ;
61+ bool (*errfn)(const JSONLoader &, std::string_view msg) = nullptr ;
6062
61- JSONLoader (const JsonData *json, std::unordered_map<int , IR::Node *> &refs)
62- : node_refs(refs), json(json) {}
63+ JSONLoader (const JsonData *json, std::unordered_map<int , IR::Node *> &refs,
64+ JsonData::LocationInfo *locinfo)
65+ : node_refs(refs), json(json), locinfo(locinfo) {}
6366
6467 public:
65- explicit JSONLoader (std::istream &in)
66- : node_refs(*(new std::unordered_map<int , IR::Node *>())) {
68+ explicit JSONLoader (std::istream &in, JsonData::LocationInfo *li = nullptr )
69+ : node_refs(*(new std::unordered_map<int , IR::Node *>())), locinfo(li) {
6770 in >> json_root;
6871 json = json_root.get ();
6972 }
7073
7174 JSONLoader (const JSONLoader &unpacker, std::string_view field)
72- : node_refs(unpacker.node_refs), json(nullptr ) {
75+ : node_refs(unpacker.node_refs), json(nullptr ), locinfo(unpacker.locinfo) {
7376 if (!unpacker) return ;
7477 if (auto *obj = unpacker.json ->to <JsonObject>()) {
7578 if (auto it = obj->find (field); it != obj->end ()) {
@@ -88,23 +91,35 @@ class JSONLoader {
8891 return json->as <T>();
8992 }
9093
94+ std::string locdesc (const JsonData &d) const {
95+ if (!locinfo) return " " ;
96+ return locinfo->desc (d);
97+ }
98+ std::string locdesc () const {
99+ if (!json) return " " ;
100+ return locdesc (*json);
101+ }
102+ bool error (std::string_view msg) const {
103+ if ((!errfn || errfn (*this , msg)) && JsonData::strict) throw JsonData::error (msg, json);
104+ return false ;
105+ }
106+
91107 private:
92- const IR::Node *get_node () {
108+ const IR::Node *get_node (NodeFactoryFn factory = nullptr ) {
93109 if (!json || !json->is <JsonObject>()) return nullptr ; // invalid json exception?
94110 int id;
95- auto success = load (" Node_ID" , id);
96- if (!success) {
97- return nullptr ;
98- }
111+ auto success = load (" Node_ID" , id) || error (" missing field Node_ID" );
112+ if (!success) return nullptr ;
99113 if (id >= 0 ) {
100114 if (node_refs.find (id) == node_refs.end ()) {
101- cstring type;
102- auto success = load (" Node_Type" , type);
103- if (!success) {
104- return nullptr ;
115+ if (!factory) {
116+ cstring type;
117+ auto success = load (" Node_Type" , type) || error (" missing field Node_Type" );
118+ if (!success) return nullptr ;
119+ factory = get (IR::unpacker_table, type);
105120 }
106- if (auto fn = get (IR::unpacker_table, type) ) {
107- node_refs[id] = fn (*this );
121+ if (factory ) {
122+ node_refs[id] = factory (*this );
108123 // Creating JsonObject from source_info read from jsonFile
109124 // and setting SourceInfo for each node
110125 // when "--fromJSON" flag is used
@@ -150,29 +165,32 @@ class JSONLoader {
150165
151166 template <typename T>
152167 void unpack_json (IR::Vector<T> &v) {
153- v = * IR::Vector<T>::fromJSON (* this );
168+ v = get_node ( NodeFactoryFn (& IR::Vector<T>::fromJSON))-> as <IR::Vector<T>>( );
154169 }
155170 template <typename T>
156171 void unpack_json (const IR::Vector<T> *&v) {
157- v = IR::Vector<T>::fromJSON (* this );
172+ v = get_node ( NodeFactoryFn (& IR::Vector<T>::fromJSON))-> checkedTo <IR::Vector<T>>( );
158173 }
159174 template <typename T>
160175 void unpack_json (IR::IndexedVector<T> &v) {
161- v = * IR::IndexedVector<T>::fromJSON (* this );
176+ v = get_node ( NodeFactoryFn (& IR::IndexedVector<T>::fromJSON))-> as <IR::IndexedVector<T>>( );
162177 }
163178 template <typename T>
164179 void unpack_json (const IR::IndexedVector<T> *&v) {
165- v = IR::IndexedVector<T>::fromJSON (*this );
180+ v = get_node (NodeFactoryFn (&IR::IndexedVector<T>::fromJSON))
181+ ->checkedTo <IR::IndexedVector<T>>();
166182 }
167183 template <class T , template <class K , class V , class COMP , class ALLOC > class MAP , class COMP ,
168184 class ALLOC >
169185 void unpack_json (IR::NameMap<T, MAP, COMP, ALLOC> &m) {
170- m = *IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON (*this );
186+ m = get_node (NodeFactoryFn (&IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON))
187+ ->as <IR::NameMap<T, MAP, COMP, ALLOC>>();
171188 }
172189 template <class T , template <class K , class V , class COMP , class ALLOC > class MAP , class COMP ,
173190 class ALLOC >
174191 void unpack_json (const IR::NameMap<T, MAP, COMP, ALLOC> *&m) {
175- m = IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON (*this );
192+ m = get_node (NodeFactoryFn (&IR::NameMap<T, MAP, COMP, ALLOC>::fromJSON))
193+ ->checkedTo <IR::NameMap<T, MAP, COMP, ALLOC>>();
176194 }
177195
178196 template <typename K, typename V>
@@ -250,20 +268,20 @@ class JSONLoader {
250268
251269 template <typename T, typename U>
252270 void unpack_json (std::pair<T, U> &v) {
253- load (" first" , v.first );
254- load (" second" , v.second );
271+ load (" first" , v.first ) || error ( " missing field first " ) ;
272+ load (" second" , v.second ) || error ( " missing field second " ) ;
255273 }
256274
257275 template <typename T>
258276 void unpack_json (std::optional<T> &v) {
259277 bool isValid = false ;
260- load (" valid" , isValid);
278+ load (" valid" , isValid) || error ( " missing field valid " ) ;
261279 if (!isValid) {
262280 v = std::nullopt ;
263281 return ;
264282 }
265283 T value;
266- auto success = load (" value" , value);
284+ auto success = load (" value" , value) || error ( " missing field value " ) ;
267285 if (!success) {
268286 v = std::nullopt ;
269287 return ;
@@ -282,15 +300,15 @@ class JSONLoader {
282300 Variant &variant) {
283301 if (N == target) {
284302 variant.template emplace <N>();
285- load (" value" , std::get<N>(variant));
303+ load (" value" , std::get<N>(variant)) || error ( " missing field value " ) ;
286304 } else
287305 unpack_variant<N + 1 >(target, variant);
288306 }
289307
290308 template <class ... Types>
291309 void unpack_json (std::variant<Types...> &v) {
292310 int index = -1 ;
293- load (" variant_index" , index);
311+ load (" variant_index" , index) || error ( " missing field variant_index " ) ;
294312 unpack_variant<0 >(index, v);
295313 }
296314
@@ -346,21 +364,21 @@ class JSONLoader {
346364 }
347365
348366 template <typename T>
349- std::enable_if_t <has_fromJSON<T>::value && !std::is_base_of_v<IR::Node , T> &&
367+ std::enable_if_t <has_fromJSON<T>::value && !std::is_base_of_v<IR::INode , T> &&
350368 std::is_pointer_v<decltype (T::fromJSON(std::declval<JSONLoader &>()))>>
351369 unpack_json (T *&v) {
352370 v = T::fromJSON (*this );
353371 }
354372
355373 template <typename T>
356- std::enable_if_t <has_fromJSON<T>::value && !std::is_base_of_v<IR::Node , T> &&
374+ std::enable_if_t <has_fromJSON<T>::value && !std::is_base_of_v<IR::INode , T> &&
357375 std::is_pointer_v<decltype (T::fromJSON(std::declval<JSONLoader &>()))>>
358376 unpack_json (T &v) {
359377 v = *(T::fromJSON (*this ));
360378 }
361379
362380 template <typename T>
363- std::enable_if_t <has_fromJSON<T>::value && !std::is_base_of<IR::Node , T>::value &&
381+ std::enable_if_t <has_fromJSON<T>::value && !std::is_base_of<IR::INode , T>::value &&
364382 !std::is_pointer_v<decltype (T::fromJSON(std::declval<JSONLoader &>()))>>
365383 unpack_json (T &v) {
366384 v = T::fromJSON (*this );
@@ -387,12 +405,12 @@ class JSONLoader {
387405 public:
388406 template <typename T>
389407 void load (const JsonData &json, T &v) {
390- JSONLoader (&json, node_refs).unpack_json (v);
408+ JSONLoader (&json, node_refs, locinfo ).unpack_json (v);
391409 }
392410
393411 template <typename T>
394412 void load (const std::unique_ptr<JsonData> &json, T &v) {
395- JSONLoader (json.get (), node_refs).unpack_json (v);
413+ JSONLoader (json.get (), node_refs, locinfo ).unpack_json (v);
396414 }
397415
398416 template <typename T>
@@ -424,15 +442,15 @@ class JSONLoader {
424442
425443template <class T >
426444IR::Vector<T>::Vector(JSONLoader &json) : VectorBase(json) {
427- json.load (" vec" , vec);
445+ json.load (" vec" , vec) || json. error ( " missing field vec " ) ;
428446}
429447template <class T >
430448IR::Vector<T> *IR::Vector<T>::fromJSON(JSONLoader &json) {
431449 return new Vector<T>(json);
432450}
433451template <class T >
434452IR::IndexedVector<T>::IndexedVector(JSONLoader &json) : Vector<T>(json) {
435- json.load (" declarations" , declarations);
453+ json.load (" declarations" , declarations) || json. error ( " missing field declarations " ) ;
436454}
437455template <class T >
438456IR::IndexedVector<T> *IR::IndexedVector<T>::fromJSON(JSONLoader &json) {
@@ -442,7 +460,7 @@ template <class T, template <class K, class V, class COMP, class ALLOC> class MA
442460 class COMP /* = std::less<cstring>*/ ,
443461 class ALLOC /* = std::allocator<std::pair<cstring, const T*>>*/ >
444462IR::NameMap<T, MAP, COMP, ALLOC>::NameMap(JSONLoader &json) : Node(json) {
445- json.load (" symbols" , symbols);
463+ json.load (" symbols" , symbols) || json. error ( " missing field symbols " ) ;
446464}
447465template <class T , template <class K , class V , class COMP , class ALLOC > class MAP /* = std::map */ ,
448466 class COMP /* = std::less<cstring>*/ ,
0 commit comments