svf-lib 1.0.1512 → 1.0.1513

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1333 @@
1
+ //===- SVFFileSystem.h -- SVF IR Reader and Writer ------------------------===//
2
+ //
3
+ // SVF - Static Value-Flow Analysis Framework
4
+ // SVF: Static Value-Flow Analysis
5
+ //
6
+ // Copyright (C) <2013-2023> <Yulei Sui>
7
+ //
8
+
9
+ // This program is free software: you can redistribute it and/or modify
10
+ // it under the terms of the GNU Affero General Public License as published by
11
+ // the Free Software Foundation, either version 3 of the License, or
12
+ // (at your option) any later version.
13
+
14
+ // This program is distributed in the hope that it will be useful,
15
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ // GNU Affero General Public License for more details.
18
+
19
+ // You should have received a copy of the GNU Affero General Public License
20
+ // along with this program. If not, see <http://www.gnu.org/licenses/>.
21
+ //
22
+ //===----------------------------------------------------------------------===//
23
+
24
+ #ifndef INCLUDE_SVFFILESYSTEM_H_
25
+ #define INCLUDE_SVFFILESYSTEM_H_
26
+
27
+ #include "Graphs/GenericGraph.h"
28
+ #include "Util/SVFUtil.h"
29
+ #include "Util/cJSON.h"
30
+ #include <type_traits>
31
+
32
+ #define ABORT_MSG(reason) \
33
+ do \
34
+ { \
35
+ SVFUtil::errs() << __FILE__ << ':' << __LINE__ << ": " << reason \
36
+ << '\n'; \
37
+ abort(); \
38
+ } while (0)
39
+ #define ABORT_IFNOT(condition, reason) \
40
+ do \
41
+ { \
42
+ if (!(condition)) \
43
+ ABORT_MSG(reason); \
44
+ } while (0)
45
+
46
+ #define SVFIR_DEBUG 1 /* Turn this on if you're debugging SVFWriter */
47
+ #if SVFIR_DEBUG
48
+ # define ENSURE_NOT_VISITED(graph) \
49
+ do \
50
+ { \
51
+ static std::set<decltype(graph)> visited; \
52
+ bool inserted = visited.insert(graph).second; \
53
+ ABORT_IFNOT(inserted, #graph << " already visited!"); \
54
+ } while (0)
55
+ #else
56
+ # define ENSURE_NOT_VISITED(graph) \
57
+ do \
58
+ { \
59
+ } while (0)
60
+ #endif
61
+ #define FIELD_NAME_ITEM(field) #field, (field)
62
+
63
+ #define JSON_FIELD_OR(json, field, default) ((json) ? (json)->field : default)
64
+ #define JSON_KEY(json) JSON_FIELD_OR(json, string, "NULL")
65
+ #define JSON_CHILD(json) JSON_FIELD_OR(json, child, nullptr)
66
+
67
+ #define JSON_WRITE_FIELD(root, objptr, field) \
68
+ jsonAddJsonableToObject(root, #field, (objptr)->field)
69
+
70
+ #define JSON_READ_OBJ_WITH_NAME(json, obj, name) \
71
+ do \
72
+ { \
73
+ ABORT_IFNOT(jsonKeyEquals(json, name), \
74
+ "Expect name '" << name << "', got " << JSON_KEY(json)); \
75
+ SVFIRReader::readJson(json, obj); \
76
+ } while (0)
77
+
78
+ #define JSON_READ_OBJ_WITH_NAME_FWD(json, obj, name) \
79
+ do \
80
+ { \
81
+ JSON_READ_OBJ_WITH_NAME(json, obj, name); \
82
+ json = (json)->next; \
83
+ } while (0)
84
+
85
+ #define JSON_READ_OBJ(json, obj) JSON_READ_OBJ_WITH_NAME(json, obj, #obj)
86
+ #define JSON_READ_OBJ_FWD(json, obj) \
87
+ JSON_READ_OBJ_WITH_NAME_FWD(json, obj, #obj)
88
+ #define JSON_DEF_READ_FWD(json, type, obj, ...) \
89
+ type obj __VA_ARGS__; \
90
+ JSON_READ_OBJ_FWD(json, obj)
91
+ #define JSON_READ_FIELD_FWD(json, objptr, field) \
92
+ JSON_READ_OBJ_WITH_NAME_FWD(json, (objptr)->field, #field)
93
+ #define CHECK_JSON_KEY_EQUALS(obj, key) \
94
+ ABORT_IFNOT(jsonKeyEquals(obj, key), \
95
+ "Expect json key: " << key << ", but get " << JSON_KEY(obj));
96
+ #define CHECK_JSON_KEY(obj) CHECK_JSON_KEY_EQUALS(obj, #obj)
97
+
98
+ namespace SVF
99
+ {
100
+ /// @brief Forward declarations.
101
+ ///@{
102
+ class NodeIDAllocator;
103
+ // Classes created upon SVFMoudle construction
104
+ class SVFType;
105
+ class SVFPointerType;
106
+ class SVFIntegerType;
107
+ class SVFFunctionType;
108
+ class SVFStructType;
109
+ class SVFArrayType;
110
+ class SVFOtherType;
111
+
112
+ class StInfo; // Every SVFType is linked to a StInfo. It also references SVFType
113
+
114
+ class SVFValue;
115
+ class SVFFunction;
116
+ class SVFBasicBlock;
117
+ class SVFInstruction;
118
+ class SVFCallInst;
119
+ class SVFVirtualCallInst;
120
+ class SVFConstant;
121
+ class SVFGlobalValue;
122
+ class SVFArgument;
123
+ class SVFConstantData;
124
+ class SVFConstantInt;
125
+ class SVFConstantFP;
126
+ class SVFConstantNullPtr;
127
+ class SVFBlackHoleValue;
128
+ class SVFOtherValue;
129
+ class SVFMetadataAsValue;
130
+
131
+ class SVFLoopAndDomInfo; // Part of SVFFunction
132
+
133
+ // Classes created upon buildSymbolTableInfo
134
+ class MemObj;
135
+
136
+ // Classes created upon ICFG construction
137
+ class ICFGNode;
138
+ class GlobalICFGNode;
139
+ class IntraICFGNode;
140
+ class InterICFGNode;
141
+ class FunEntryICFGNode;
142
+ class FunExitICFGNode;
143
+ class CallICFGNode;
144
+ class RetICFGNode;
145
+
146
+ class ICFGEdge;
147
+ class IntraCFGEdge;
148
+ class CallCFGEdge;
149
+ class RetCFGEdge;
150
+
151
+ class SVFIR;
152
+ class SVFIRWriter;
153
+ class SVFLoop;
154
+ class ICFG;
155
+ class IRGraph;
156
+ class CHGraph;
157
+ class CommonCHGraph;
158
+ class SymbolTableInfo;
159
+
160
+ class SVFModule;
161
+
162
+ class LocationSet;
163
+ class ObjTypeInfo; // Need SVFType
164
+
165
+ class SVFVar;
166
+ class ValVar;
167
+ class ObjVar;
168
+ class GepValVar;
169
+ class GepObjVar;
170
+ class FIObjVar;
171
+ class RetPN;
172
+ class VarArgPN;
173
+ class DummyValVar;
174
+ class DummyObjVar;
175
+
176
+ class SVFStmt;
177
+ class AssignStmt;
178
+ class AddrStmt;
179
+ class CopyStmt;
180
+ class StoreStmt;
181
+ class LoadStmt;
182
+ class GepStmt;
183
+ class CallPE;
184
+ class RetPE;
185
+ class MultiOpndStmt;
186
+ class PhiStmt;
187
+ class SelectStmt;
188
+ class CmpStmt;
189
+ class BinaryOPStmt;
190
+ class UnaryOPStmt;
191
+ class BranchStmt;
192
+ class TDForkPE;
193
+ class TDJoinPE;
194
+
195
+ class CHNode;
196
+ class CHEdge;
197
+ class CHGraph;
198
+ // End of forward declarations
199
+ ///@}
200
+
201
+ bool jsonIsBool(const cJSON* item);
202
+ bool jsonIsBool(const cJSON* item, bool& flag);
203
+ bool jsonIsNumber(const cJSON* item);
204
+ bool jsonIsString(const cJSON* item);
205
+ bool jsonIsNullId(const cJSON* item);
206
+ bool jsonIsArray(const cJSON* item);
207
+ bool jsonIsMap(const cJSON* item);
208
+ bool jsonIsObject(const cJSON* item);
209
+ bool jsonKeyEquals(const cJSON* item, const char* key);
210
+ std::pair<const cJSON*, const cJSON*> jsonUnpackPair(const cJSON* item);
211
+ double jsonGetNumber(const cJSON* item);
212
+ cJSON* jsonCreateNullId();
213
+ cJSON* jsonCreateObject();
214
+ cJSON* jsonCreateArray();
215
+ cJSON* jsonCreateString(const char* str);
216
+ cJSON* jsonCreateIndex(size_t index);
217
+ cJSON* jsonCreateBool(bool flag);
218
+ cJSON* jsonCreateNumber(double num);
219
+ bool jsonAddPairToMap(cJSON* obj, cJSON* key, cJSON* value);
220
+ bool jsonAddItemToObject(cJSON* obj, const char* name, cJSON* item);
221
+ bool jsonAddItemToArray(cJSON* array, cJSON* item);
222
+ /// @brief Helper function to write a number to a JSON object.
223
+ bool jsonAddNumberToObject(cJSON* obj, const char* name, double number);
224
+ bool jsonAddStringToObject(cJSON* obj, const char* name, const char* str);
225
+ bool jsonAddStringToObject(cJSON* obj, const char* name, const std::string& s);
226
+ #define jsonForEach(field, array) \
227
+ for (const cJSON* field = JSON_CHILD(array); field; field = field->next)
228
+
229
+ /// @brief Bookkeeping class to keep track of the IDs of objects that doesn't
230
+ /// have any ID. E.g., SVFValue, XXXEdge.
231
+ /// @tparam T
232
+ template <typename T> class WriterPtrPool
233
+ {
234
+ private:
235
+ Map<const T*, size_t> ptrToId;
236
+ std::vector<const T*> ptrPool;
237
+
238
+ public:
239
+ inline size_t getID(const T* ptr)
240
+ {
241
+ if (!ptr)
242
+ return 0;
243
+
244
+ typename decltype(ptrToId)::iterator it;
245
+ bool inserted;
246
+ std::tie(it, inserted) = ptrToId.emplace(ptr, 1 + ptrPool.size());
247
+ if (inserted)
248
+ ptrPool.push_back(ptr);
249
+ return it->second;
250
+ }
251
+
252
+ inline void saveID(const T* ptr)
253
+ {
254
+ getID(ptr);
255
+ }
256
+
257
+ inline const T* getPtr(size_t id) const
258
+ {
259
+ assert(id <= ptrPool.size() && "Invalid ID");
260
+ return id ? ptrPool[id - 1] : nullptr;
261
+ }
262
+
263
+ inline const std::vector<const T*>& getPool() const
264
+ {
265
+ return ptrPool;
266
+ }
267
+
268
+ inline size_t size() const
269
+ {
270
+ return ptrPool.size();
271
+ }
272
+
273
+ inline void reserve(size_t size)
274
+ {
275
+ ptrPool.reserve(size);
276
+ }
277
+
278
+ inline auto begin() const
279
+ {
280
+ return ptrPool.cbegin();
281
+ }
282
+
283
+ inline auto end() const
284
+ {
285
+ return ptrPool.cend();
286
+ }
287
+ };
288
+
289
+ template <typename NodeTy, typename EdgeTy> class GenericGraphWriter
290
+ {
291
+ friend class SVFIRWriter;
292
+
293
+ private:
294
+ using NodeType = NodeTy;
295
+ using EdgeType = EdgeTy;
296
+ using GraphType = GenericGraph<NodeType, EdgeType>;
297
+
298
+ // const GraphType* graph;
299
+ WriterPtrPool<EdgeType> edgePool;
300
+
301
+ public:
302
+ GenericGraphWriter(const GraphType* graph)
303
+ {
304
+ assert(graph && "Graph pointer should never be null");
305
+ edgePool.reserve(graph->getTotalEdgeNum());
306
+
307
+ for (const auto& pair : graph->IDToNodeMap)
308
+ {
309
+ const NodeType* node = pair.second;
310
+
311
+ for (const EdgeType* edge : node->getOutEdges())
312
+ {
313
+ edgePool.saveID(edge);
314
+ }
315
+ }
316
+ }
317
+
318
+ inline size_t getEdgeID(const EdgeType* edge)
319
+ {
320
+ return edgePool.getID(edge);
321
+ }
322
+ };
323
+
324
+ using GenericICFGWriter = GenericGraphWriter<ICFGNode, ICFGEdge>;
325
+
326
+ class ICFGWriter : public GenericICFGWriter
327
+ {
328
+ friend class SVFIRWriter;
329
+
330
+ private:
331
+ WriterPtrPool<SVFLoop> svfLoopPool;
332
+
333
+ public:
334
+ ICFGWriter(const ICFG* icfg);
335
+
336
+ inline size_t getSvfLoopID(const SVFLoop* loop)
337
+ {
338
+ return svfLoopPool.getID(loop);
339
+ }
340
+ };
341
+
342
+ using IRGraphWriter = GenericGraphWriter<SVFVar, SVFStmt>;
343
+ using CHGraphWriter = GenericGraphWriter<CHNode, CHEdge>;
344
+
345
+ class SVFModuleWriter
346
+ {
347
+ friend class SVFIRWriter;
348
+
349
+ private:
350
+ WriterPtrPool<SVFType> svfTypePool;
351
+ WriterPtrPool<StInfo> stInfoPool;
352
+ WriterPtrPool<SVFValue> svfValuePool;
353
+
354
+ public:
355
+ SVFModuleWriter(const SVFModule* svfModule);
356
+
357
+ inline size_t getSVFValueID(const SVFValue* value)
358
+ {
359
+ return svfValuePool.getID(value);
360
+ }
361
+ inline const SVFValue* getSVFValuePtr(size_t id) const
362
+ {
363
+ return svfValuePool.getPtr(id);
364
+ }
365
+ inline size_t getSVFTypeID(const SVFType* type)
366
+ {
367
+ return svfTypePool.getID(type);
368
+ }
369
+ inline size_t getStInfoID(const StInfo* stInfo)
370
+ {
371
+ return stInfoPool.getID(stInfo);
372
+ }
373
+ inline size_t sizeSVFValuePool() const
374
+ {
375
+ return svfValuePool.size();
376
+ }
377
+ };
378
+
379
+ class SVFIRWriter
380
+ {
381
+ private:
382
+ const SVFIR* svfIR;
383
+
384
+ SVFModuleWriter svfModuleWriter;
385
+ ICFGWriter icfgWriter;
386
+ CHGraphWriter chgWriter;
387
+ IRGraphWriter irGraphWriter;
388
+
389
+ OrderedMap<size_t, std::string> numToStrMap;
390
+
391
+ public:
392
+ using autoJSON = std::unique_ptr<cJSON, decltype(&cJSON_Delete)>;
393
+ using autoCStr = std::unique_ptr<char, decltype(&cJSON_free)>;
394
+
395
+ /// @brief Constructor.
396
+ SVFIRWriter(const SVFIR* svfir);
397
+
398
+ static void writeJsonToOstream(const SVFIR* svfir, std::ostream& os);
399
+ static void writeJsonToPath(const SVFIR* svfir, const std::string& path);
400
+
401
+ private:
402
+ /// @brief Main logic to dump a SVFIR to a JSON object.
403
+ autoJSON generateJson();
404
+ autoCStr generateJsonString();
405
+
406
+ const char* numToStr(size_t n);
407
+
408
+ cJSON* toJson(const NodeIDAllocator* nodeIDAllocator);
409
+ cJSON* toJson(const SymbolTableInfo* symTable);
410
+ cJSON* toJson(const SVFModule* module);
411
+ cJSON* toJson(const SVFType* type);
412
+ cJSON* toJson(const SVFValue* value);
413
+ cJSON* toJson(const IRGraph* graph); // IRGraph Graph
414
+ cJSON* toJson(const SVFVar* var); // IRGraph Node
415
+ cJSON* toJson(const SVFStmt* stmt); // IRGraph Edge
416
+ cJSON* toJson(const ICFG* icfg); // ICFG Graph
417
+ cJSON* toJson(const ICFGNode* node); // ICFG Node
418
+ cJSON* toJson(const ICFGEdge* edge); // ICFG Edge
419
+ cJSON* toJson(const CommonCHGraph* graph); // CHGraph Graph
420
+ cJSON* toJson(const CHGraph* graph); // CHGraph Graph
421
+ cJSON* toJson(const CHNode* node); // CHGraph Node
422
+ cJSON* toJson(const CHEdge* edge); // CHGraph Edge
423
+
424
+ cJSON* toJson(const CallSite& cs);
425
+ cJSON* toJson(const LocationSet& ls);
426
+ cJSON* toJson(const SVFLoop* loop);
427
+ cJSON* toJson(const MemObj* memObj);
428
+ cJSON* toJson(const ObjTypeInfo* objTypeInfo); // Only owned by MemObj
429
+ cJSON* toJson(const SVFLoopAndDomInfo* ldInfo); // Only owned by SVFFunction
430
+ cJSON* toJson(const StInfo* stInfo);
431
+
432
+ static cJSON* toJson(bool flag);
433
+ static cJSON* toJson(unsigned number);
434
+ static cJSON* toJson(int number);
435
+ static cJSON* toJson(float number);
436
+ static cJSON* toJson(const std::string& str);
437
+ cJSON* toJson(unsigned long number);
438
+ cJSON* toJson(long long number);
439
+ cJSON* toJson(unsigned long long number);
440
+
441
+ /// \brief Parameter types of these functions are all pointers.
442
+ /// When they are used as arguments of toJson(), they will be
443
+ /// dumped as an index. `contentToJson()` will dump the actual content.
444
+ ///@{
445
+ cJSON* virtToJson(const SVFType* type);
446
+ cJSON* virtToJson(const SVFValue* value);
447
+ cJSON* virtToJson(const SVFVar* var);
448
+ cJSON* virtToJson(const SVFStmt* stmt);
449
+ cJSON* virtToJson(const ICFGNode* node);
450
+ cJSON* virtToJson(const ICFGEdge* edge);
451
+ cJSON* virtToJson(const CHNode* node);
452
+ cJSON* virtToJson(const CHEdge* edge);
453
+
454
+ // Classes inherited from SVFVar
455
+ cJSON* contentToJson(const SVFVar* var);
456
+ cJSON* contentToJson(const ValVar* var);
457
+ cJSON* contentToJson(const ObjVar* var);
458
+ cJSON* contentToJson(const GepValVar* var);
459
+ cJSON* contentToJson(const GepObjVar* var);
460
+ cJSON* contentToJson(const FIObjVar* var);
461
+ cJSON* contentToJson(const RetPN* var);
462
+ cJSON* contentToJson(const VarArgPN* var);
463
+ cJSON* contentToJson(const DummyValVar* var);
464
+ cJSON* contentToJson(const DummyObjVar* var);
465
+
466
+ // Classes inherited from SVFStmt
467
+ cJSON* contentToJson(const SVFStmt* edge);
468
+ cJSON* contentToJson(const AssignStmt* edge);
469
+ cJSON* contentToJson(const AddrStmt* edge);
470
+ cJSON* contentToJson(const CopyStmt* edge);
471
+ cJSON* contentToJson(const StoreStmt* edge);
472
+ cJSON* contentToJson(const LoadStmt* edge);
473
+ cJSON* contentToJson(const GepStmt* edge);
474
+ cJSON* contentToJson(const CallPE* edge);
475
+ cJSON* contentToJson(const RetPE* edge);
476
+ cJSON* contentToJson(const MultiOpndStmt* edge);
477
+ cJSON* contentToJson(const PhiStmt* edge);
478
+ cJSON* contentToJson(const SelectStmt* edge);
479
+ cJSON* contentToJson(const CmpStmt* edge);
480
+ cJSON* contentToJson(const BinaryOPStmt* edge);
481
+ cJSON* contentToJson(const UnaryOPStmt* edge);
482
+ cJSON* contentToJson(const BranchStmt* edge);
483
+ cJSON* contentToJson(const TDForkPE* edge);
484
+ cJSON* contentToJson(const TDJoinPE* edge);
485
+
486
+ // Classes inherited from ICFGNode
487
+ cJSON* contentToJson(const ICFGNode* node);
488
+ cJSON* contentToJson(const GlobalICFGNode* node);
489
+ cJSON* contentToJson(const IntraICFGNode* node);
490
+ cJSON* contentToJson(const InterICFGNode* node);
491
+ cJSON* contentToJson(const FunEntryICFGNode* node);
492
+ cJSON* contentToJson(const FunExitICFGNode* node);
493
+ cJSON* contentToJson(const CallICFGNode* node);
494
+ cJSON* contentToJson(const RetICFGNode* node);
495
+
496
+ // Classes inherited from ICFGEdge
497
+ cJSON* contentToJson(const ICFGEdge* edge);
498
+ cJSON* contentToJson(const IntraCFGEdge* edge);
499
+ cJSON* contentToJson(const CallCFGEdge* edge);
500
+ cJSON* contentToJson(const RetCFGEdge* edge);
501
+
502
+ // CHNode & CHEdge
503
+ cJSON* contentToJson(const CHNode* node);
504
+ cJSON* contentToJson(const CHEdge* edge);
505
+
506
+ cJSON* contentToJson(const SVFType* type);
507
+ cJSON* contentToJson(const SVFPointerType* type);
508
+ cJSON* contentToJson(const SVFIntegerType* type);
509
+ cJSON* contentToJson(const SVFFunctionType* type);
510
+ cJSON* contentToJson(const SVFStructType* type);
511
+ cJSON* contentToJson(const SVFArrayType* type);
512
+ cJSON* contentToJson(const SVFOtherType* type);
513
+
514
+ cJSON* contentToJson(const SVFValue* value);
515
+ cJSON* contentToJson(const SVFFunction* value);
516
+ cJSON* contentToJson(const SVFBasicBlock* value);
517
+ cJSON* contentToJson(const SVFInstruction* value);
518
+ cJSON* contentToJson(const SVFCallInst* value);
519
+ cJSON* contentToJson(const SVFVirtualCallInst* value);
520
+ cJSON* contentToJson(const SVFConstant* value);
521
+ cJSON* contentToJson(const SVFGlobalValue* value);
522
+ cJSON* contentToJson(const SVFArgument* value);
523
+ cJSON* contentToJson(const SVFConstantData* value);
524
+ cJSON* contentToJson(const SVFConstantInt* value);
525
+ cJSON* contentToJson(const SVFConstantFP* value);
526
+ cJSON* contentToJson(const SVFConstantNullPtr* value);
527
+ cJSON* contentToJson(const SVFBlackHoleValue* value);
528
+ cJSON* contentToJson(const SVFOtherValue* value);
529
+ cJSON* contentToJson(const SVFMetadataAsValue* value);
530
+
531
+ // Other classes
532
+ cJSON* contentToJson(const SVFLoop* loop);
533
+ cJSON* contentToJson(const MemObj* memObj); // Owned by SymbolTable->objMap
534
+ cJSON* contentToJson(const StInfo* stInfo);
535
+ ///@}
536
+
537
+ template <typename NodeTy, typename EdgeTy>
538
+ cJSON* genericNodeToJson(const GenericNode<NodeTy, EdgeTy>* node)
539
+ {
540
+ cJSON* root = jsonCreateObject();
541
+ JSON_WRITE_FIELD(root, node, id);
542
+ JSON_WRITE_FIELD(root, node, nodeKind);
543
+ JSON_WRITE_FIELD(root, node, InEdges);
544
+ JSON_WRITE_FIELD(root, node, OutEdges);
545
+ return root;
546
+ }
547
+
548
+ template <typename NodeTy>
549
+ cJSON* genericEdgeToJson(const GenericEdge<NodeTy>* edge)
550
+ {
551
+ cJSON* root = jsonCreateObject();
552
+ JSON_WRITE_FIELD(root, edge, edgeFlag);
553
+ JSON_WRITE_FIELD(root, edge, src);
554
+ JSON_WRITE_FIELD(root, edge, dst);
555
+ return root;
556
+ }
557
+
558
+ template <typename NodeTy, typename EdgeTy>
559
+ cJSON* genericGraphToJson(const GenericGraph<NodeTy, EdgeTy>* graph,
560
+ const std::vector<const EdgeTy*>& edgePool)
561
+ {
562
+ cJSON* root = jsonCreateObject();
563
+
564
+ cJSON* allNode = jsonCreateArray();
565
+ for (const auto& pair : graph->IDToNodeMap)
566
+ {
567
+ NodeTy* node = pair.second;
568
+ cJSON* jsonNode = virtToJson(node);
569
+ jsonAddItemToArray(allNode, jsonNode);
570
+ }
571
+
572
+ cJSON* allEdge = jsonCreateArray();
573
+ for (const EdgeTy* edge : edgePool)
574
+ {
575
+ cJSON* edgeJson = virtToJson(edge);
576
+ jsonAddItemToArray(allEdge, edgeJson);
577
+ }
578
+
579
+ JSON_WRITE_FIELD(root, graph, nodeNum);
580
+ jsonAddItemToObject(root, FIELD_NAME_ITEM(allNode));
581
+ JSON_WRITE_FIELD(root, graph, edgeNum);
582
+ jsonAddItemToObject(root, FIELD_NAME_ITEM(allEdge));
583
+
584
+ return root;
585
+ }
586
+
587
+ /** The following 2 functions are intended to convert SparseBitVectors
588
+ * to JSON. But they're buggy. Commentting them out would enable the
589
+ * toJson(T) where is_iterable_v<T> is true. But that implementation is less
590
+ * space-efficient if the bitvector contains many elements.
591
+ * It is observed that upon construction, SVF IR bitvectors contain at most
592
+ * 1 element. In that case, we can just use the toJson(T) for iterable T
593
+ * without much space overhead.
594
+
595
+ template <unsigned ElementSize>
596
+ cJSON* toJson(const SparseBitVectorElement<ElementSize>& element)
597
+ {
598
+ cJSON* array = jsonCreateArray();
599
+ for (const auto v : element.Bits)
600
+ {
601
+ jsonAddItemToArray(array, toJson(v));
602
+ }
603
+ return array;
604
+ }
605
+
606
+ template <unsigned ElementSize>
607
+ cJSON* toJson(const SparseBitVector<ElementSize>& bv)
608
+ {
609
+ return toJson(bv.Elements);
610
+ }
611
+ */
612
+
613
+ template <typename T, typename U> cJSON* toJson(const std::pair<T, U>& pair)
614
+ {
615
+ cJSON* obj = jsonCreateArray();
616
+ jsonAddItemToArray(obj, toJson(pair.first));
617
+ jsonAddItemToArray(obj, toJson(pair.second));
618
+ return obj;
619
+ }
620
+
621
+ template <typename T,
622
+ typename = std::enable_if_t<SVFUtil::is_iterable_v<T>>>
623
+ cJSON* toJson(const T& container)
624
+ {
625
+ cJSON* array = jsonCreateArray();
626
+ for (const auto& item : container)
627
+ {
628
+ cJSON* itemObj = toJson(item);
629
+ jsonAddItemToArray(array, itemObj);
630
+ }
631
+ return array;
632
+ }
633
+
634
+ template <typename T>
635
+ bool jsonAddJsonableToObject(cJSON* obj, const char* name, const T& item)
636
+ {
637
+ cJSON* itemObj = toJson(item);
638
+ return jsonAddItemToObject(obj, name, itemObj);
639
+ }
640
+
641
+ template <typename T>
642
+ bool jsonAddContentToObject(cJSON* obj, const char* name, const T& item)
643
+ {
644
+ cJSON* itemObj = contentToJson(item);
645
+ return jsonAddItemToObject(obj, name, itemObj);
646
+ }
647
+ };
648
+
649
+ /*
650
+ * Reader Part
651
+ */
652
+
653
+ /// @brief Type trait to get base type.
654
+ /// Helper struct to detect inheritance from Node/Edge
655
+ ///@}
656
+ template <typename T, typename = void> struct KindBaseHelper
657
+ {
658
+ };
659
+ #define KIND_BASE(B, KindGetter) \
660
+ template <typename T> \
661
+ struct KindBaseHelper<T, std::enable_if_t<std::is_base_of<B, T>::value>> \
662
+ { \
663
+ using type = B; \
664
+ static inline s64_t getKind(T* p) \
665
+ { \
666
+ return {p->KindGetter()}; \
667
+ } \
668
+ }
669
+ KIND_BASE(SVFType, getKind);
670
+ KIND_BASE(SVFValue, getKind);
671
+ KIND_BASE(SVFVar, getNodeKind);
672
+ KIND_BASE(SVFStmt, getEdgeKind);
673
+ KIND_BASE(ICFGNode, getNodeKind);
674
+ KIND_BASE(ICFGEdge, getEdgeKind);
675
+ KIND_BASE(CHNode, getNodeKind);
676
+ KIND_BASE(CHEdge, getEdgeKind);
677
+ #undef KIND_BASE
678
+
679
+ template <typename T> using KindBaseT = typename KindBaseHelper<T>::type;
680
+ ///@}
681
+
682
+ /// @brief Keeps a map from IDs to T objects, such as XXNode.
683
+ /// @tparam T: The type of the objects.
684
+ template <typename T> class ReaderIDToObjMap
685
+ {
686
+ private:
687
+ using IDToPairMapTy = OrderedMap<unsigned, std::pair<const cJSON*, T*>>;
688
+ IDToPairMapTy idMap;
689
+
690
+ public:
691
+ template <typename IdObjCreator>
692
+ /// idObjcreator : (const cJSON*) -> (id, T*) with id set
693
+ void createObjs(const cJSON* idObjArrayJson, IdObjCreator idObjCreator)
694
+ {
695
+ assert(idMap.empty() &&
696
+ "idToObjMap should be empty when creating objects");
697
+ ABORT_IFNOT(jsonIsArray(idObjArrayJson), "expects an array");
698
+
699
+ jsonForEach(objJson, idObjArrayJson)
700
+ {
701
+ ABORT_IFNOT(jsonIsObject(objJson), "expects an object");
702
+ const cJSON* objFieldJson = objJson->child;
703
+ // creator is allowed to change objFieldJson
704
+ auto idObj = idObjCreator(objFieldJson);
705
+ auto pair = std::pair<const cJSON*, T*>(objFieldJson, idObj.second);
706
+ bool inserted = idMap.emplace(idObj.first, pair).second;
707
+ ABORT_IFNOT(inserted, "ID " << idObj.first << " duplicated in "
708
+ << idObjArrayJson->string);
709
+ }
710
+ }
711
+
712
+ T* getPtr(unsigned id) const
713
+ {
714
+ auto it = idMap.find(id);
715
+ ABORT_IFNOT(it != idMap.end(), "ID " << id << " not found");
716
+ return it->second.second;
717
+ }
718
+
719
+ template <typename FillFunc> void fillObjs(FillFunc fillFunc)
720
+ {
721
+ for (auto& pair : idMap)
722
+ {
723
+ const cJSON* objFieldJson = pair.second.first;
724
+ T* obj = pair.second.second;
725
+ fillFunc(objFieldJson, obj);
726
+
727
+ ABORT_IFNOT(!objFieldJson, "json should be consumed by filler, but "
728
+ << objFieldJson->string << " left");
729
+ }
730
+ }
731
+
732
+ inline size_t size() const
733
+ {
734
+ return idMap.size();
735
+ }
736
+
737
+ template <typename Map> void saveToIDToObjMap(Map& idToObjMap) const
738
+ {
739
+ for (auto& pair : idMap)
740
+ {
741
+ unsigned id = pair.first;
742
+ T* obj = pair.second.second;
743
+ assert(obj && "obj should not be null");
744
+ idToObjMap.insert(std::make_pair(id, obj));
745
+ }
746
+ }
747
+ };
748
+
749
+ /// @brief Reverse of WriterPtrPool where T is object type without ID field.
750
+ /// @tparam T
751
+ template <typename T> class ReaderPtrPool
752
+ {
753
+ private:
754
+ std::vector<const cJSON*> jsonArray;
755
+ std::vector<T*> ptrPool;
756
+
757
+ public:
758
+ inline void reserve(size_t size)
759
+ {
760
+ jsonArray.reserve(size);
761
+ ptrPool.reserve(size);
762
+ }
763
+
764
+ /// @brief
765
+ /// @tparam Creator
766
+ /// @param objArrayJson
767
+ /// @param creator
768
+ template <typename Creator>
769
+ void createObjs(const cJSON* objArrayJson, Creator creator)
770
+ {
771
+ assert(jsonArray.empty() &&
772
+ "jsonArray should be empty when creating objects");
773
+ ABORT_IFNOT(jsonIsArray(objArrayJson), "expects an array");
774
+
775
+ jsonForEach(objJson, objArrayJson)
776
+ {
777
+ ABORT_IFNOT(jsonIsObject(objJson), "expects objects in array");
778
+ const cJSON* objFieldJson = objJson->child;
779
+ T* obj = creator(objFieldJson);
780
+ jsonArray.push_back(objFieldJson);
781
+ ptrPool.push_back(obj);
782
+ }
783
+ }
784
+
785
+ T* getPtr(size_t id) const
786
+ {
787
+ ABORT_IFNOT(id <= ptrPool.size(),
788
+ "Invalid ID " << id << ". Max ID = " << ptrPool.size());
789
+ return id ? ptrPool[id - 1] : nullptr;
790
+ }
791
+
792
+ template <typename FillFunc> void fillObjs(FillFunc fillFunc)
793
+ {
794
+ assert(jsonArray.size() == ptrPool.size() &&
795
+ "jsonArray and ptrPool should have same size");
796
+ for (size_t i = 0; i < jsonArray.size(); ++i)
797
+ {
798
+ const cJSON*& objFieldJson = jsonArray[i];
799
+ fillFunc(objFieldJson, ptrPool[i]);
800
+ ABORT_IFNOT(!objFieldJson, "json should be consumed by filler, but "
801
+ << objFieldJson->string << " left");
802
+ }
803
+ jsonArray.clear();
804
+ jsonArray.shrink_to_fit();
805
+ }
806
+
807
+ inline size_t size() const
808
+ {
809
+ return ptrPool.size();
810
+ }
811
+
812
+ template <typename Set> void saveToSet(Set& set) const
813
+ {
814
+ for (T* obj : ptrPool)
815
+ {
816
+ set.insert(obj);
817
+ }
818
+ }
819
+ };
820
+
821
+ template <typename NodeTy, typename EdgeTy> class GenericGraphReader
822
+ {
823
+ private:
824
+ ReaderIDToObjMap<NodeTy> idToNodeMap;
825
+ ReaderPtrPool<EdgeTy> edgePool;
826
+
827
+ protected:
828
+ const cJSON* graphFieldJson = nullptr;
829
+
830
+ public:
831
+ template <typename NodeCreator, typename EdgeCreator>
832
+ void createObjs(const cJSON* graphJson, NodeCreator nodeCreator,
833
+ EdgeCreator edgeCreator)
834
+ {
835
+ // Read nodeNum
836
+ const cJSON* nodeNum = graphJson->child;
837
+ CHECK_JSON_KEY(nodeNum);
838
+ u32_t numOfNodes = jsonGetNumber(nodeNum);
839
+ (void)numOfNodes;
840
+
841
+ // Read allNode
842
+ const cJSON* allNode = nodeNum->next;
843
+ CHECK_JSON_KEY(allNode);
844
+ idToNodeMap.createObjs(allNode, nodeCreator);
845
+ // TODO: ABORT_IFNOT(idToNodeMap.size() == numOfNodes, "nodeNum mismatch");
846
+
847
+ // Read edgeNum
848
+ const cJSON* edgeNum = allNode->next;
849
+ CHECK_JSON_KEY(edgeNum);
850
+ u32_t numOfEdges = jsonGetNumber(edgeNum);
851
+ (void)numOfEdges;
852
+
853
+ // Read allEdge
854
+ const cJSON* allEdge = edgeNum->next;
855
+ CHECK_JSON_KEY(allEdge);
856
+ edgePool.createObjs(allEdge, edgeCreator);
857
+ // TODO: ABORT_IFNOT(edgePool.size() == numOfEdges, "edgeNum mismatch");
858
+
859
+ // Rest fields
860
+ assert(!graphFieldJson && "graphFieldJson should be empty");
861
+ graphFieldJson = allEdge->next;
862
+ }
863
+
864
+ inline NodeTy* getNodePtr(unsigned id) const
865
+ {
866
+ return idToNodeMap.getPtr(id);
867
+ }
868
+
869
+ inline EdgeTy* getEdgePtr(unsigned id) const
870
+ {
871
+ return edgePool.getPtr(id);
872
+ }
873
+
874
+ template <typename NodeFiller, typename EdgeFiller>
875
+ void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller)
876
+ {
877
+ // GenericNode<> contains field `InEdges` and `OutEdges`, which are
878
+ // ordered set of edges with comparator `GenericEdge::equalGEdge()`,
879
+ // which need operands `src` and `dst` to be non-null to get IDs, so we
880
+ // need to fill nodes first.
881
+ edgePool.fillObjs(edgeFiller);
882
+ idToNodeMap.fillObjs(nodeFiller);
883
+ }
884
+
885
+ void saveToGenericGraph(GenericGraph<NodeTy, EdgeTy>* graph) const
886
+ {
887
+ graph->edgeNum = edgePool.size();
888
+ graph->nodeNum = idToNodeMap.size();
889
+ idToNodeMap.saveToIDToObjMap(graph->IDToNodeMap);
890
+ }
891
+
892
+ const cJSON* getFieldJson() const
893
+ {
894
+ return graphFieldJson;
895
+ }
896
+ };
897
+
898
+ class SymbolTableInfoReader
899
+ {
900
+ friend class SVFIRReader;
901
+
902
+ private:
903
+ const cJSON* symTabFieldJson = nullptr;
904
+ ReaderIDToObjMap<MemObj> memObjMap;
905
+
906
+ public:
907
+ inline MemObj* getMemObjPtr(unsigned id) const
908
+ {
909
+ return memObjMap.getPtr(id);
910
+ }
911
+
912
+ template <typename MemObjCreator>
913
+ void createObjs(const cJSON* symTabJson, MemObjCreator memObjCreator)
914
+ {
915
+ assert(!symTabFieldJson && "symTabFieldJson should be empty");
916
+ ABORT_IFNOT(jsonIsObject(symTabJson), "symTableJson is not an object?");
917
+
918
+ const cJSON* const allMemObj = symTabJson->child;
919
+ CHECK_JSON_KEY(allMemObj);
920
+ memObjMap.createObjs(allMemObj, memObjCreator);
921
+
922
+ symTabFieldJson = allMemObj->next;
923
+ }
924
+
925
+ inline const cJSON* getFieldJson() const
926
+ {
927
+ return symTabFieldJson;
928
+ }
929
+ };
930
+
931
+ using GenericICFGReader = GenericGraphReader<ICFGNode, ICFGEdge>;
932
+ using CHGraphReader = GenericGraphReader<CHNode, CHEdge>;
933
+ using IRGraphReader = GenericGraphReader<SVFVar, SVFStmt>;
934
+
935
+ class ICFGReader : public GenericICFGReader
936
+ {
937
+ // friend class SVFIRReader;
938
+
939
+ private:
940
+ ReaderPtrPool<SVFLoop> svfLoopPool;
941
+
942
+ public:
943
+ template <typename NodeCreator, typename EdgeCreator, typename SVFLoopCreator>
944
+ void createObjs(const cJSON* icfgJson, NodeCreator nodeCreator,
945
+ EdgeCreator edgeCreator, SVFLoopCreator svfLoopCreator)
946
+ {
947
+ GenericICFGReader::createObjs(icfgJson, nodeCreator, edgeCreator);
948
+
949
+ const cJSON* const allSvfLoop = graphFieldJson;
950
+ CHECK_JSON_KEY(allSvfLoop);
951
+ svfLoopPool.createObjs(graphFieldJson, svfLoopCreator);
952
+ graphFieldJson = allSvfLoop->next;
953
+ }
954
+
955
+ inline SVFLoop* getSVFLoopPtr(size_t id) const
956
+ {
957
+ return svfLoopPool.getPtr(id);
958
+ }
959
+
960
+ template <typename NodeFiller, typename EdgeFiller, typename LoopFiller>
961
+ void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller,
962
+ LoopFiller loopFiller)
963
+ {
964
+ GenericICFGReader::fillObjs(nodeFiller, edgeFiller);
965
+ svfLoopPool.fillObjs(loopFiller);
966
+ }
967
+ };
968
+
969
+ class SVFModuleReader
970
+ {
971
+ friend class SVFIRReader;
972
+
973
+ private:
974
+ const cJSON* svfModuleFieldJson = nullptr;
975
+ ReaderPtrPool<SVFType> svfTypePool;
976
+ ReaderPtrPool<StInfo> stInfoPool;
977
+ ReaderPtrPool<SVFValue> svfValuePool;
978
+
979
+ public:
980
+ template <typename SVFTypeCreator, typename SVFTypeFiller,
981
+ typename SVFValueCreator, typename SVFValueFiller,
982
+ typename StInfoCreator>
983
+ void createObjs(const cJSON* svfModuleJson, SVFTypeCreator typeCreator,
984
+ SVFTypeFiller typeFiller, SVFValueCreator valueCreator,
985
+ SVFValueFiller valueFiller, StInfoCreator stInfoCreator)
986
+ {
987
+ assert(!svfModuleFieldJson && "SVFModule Already created?");
988
+ ABORT_IFNOT(jsonIsObject(svfModuleJson),
989
+ "svfModuleJson not an JSON object?");
990
+
991
+ const cJSON* const allSVFType = svfModuleJson->child;
992
+ CHECK_JSON_KEY(allSVFType);
993
+ svfTypePool.createObjs(allSVFType, typeCreator);
994
+
995
+ const cJSON* const allStInfo = allSVFType->next;
996
+ CHECK_JSON_KEY(allStInfo);
997
+ stInfoPool.createObjs(allStInfo, stInfoCreator); // Only need SVFType*
998
+
999
+ svfTypePool.fillObjs(typeFiller); // Only need SVFType* & StInfo*
1000
+
1001
+ const cJSON* const allSVFValue = allStInfo->next;
1002
+ CHECK_JSON_KEY(allSVFValue);
1003
+ svfValuePool.createObjs(allSVFValue, valueCreator);
1004
+ svfValuePool.fillObjs(valueFiller); // Need SVFType* & SVFValue*
1005
+
1006
+ svfModuleFieldJson = allSVFValue->next;
1007
+ }
1008
+
1009
+ inline SVFValue* getSVFValuePtr(size_t id) const
1010
+ {
1011
+ return svfValuePool.getPtr(id);
1012
+ }
1013
+ inline SVFType* getSVFTypePtr(size_t id) const
1014
+ {
1015
+ return svfTypePool.getPtr(id);
1016
+ }
1017
+ inline StInfo* getStInfoPtr(size_t id) const
1018
+ {
1019
+ return stInfoPool.getPtr(id);
1020
+ }
1021
+
1022
+ const cJSON* getFieldJson() const
1023
+ {
1024
+ return svfModuleFieldJson;
1025
+ }
1026
+ };
1027
+
1028
+ /* SVFIRReader
1029
+ * Read SVFIR from JSON
1030
+ */
1031
+
1032
+ class SVFIRReader
1033
+ {
1034
+ private:
1035
+ SVFModuleReader svfModuleReader;
1036
+ SymbolTableInfoReader symTableReader;
1037
+ ICFGReader icfgReader;
1038
+ CHGraphReader chGraphReader;
1039
+ IRGraphReader irGraphReader;
1040
+
1041
+ public:
1042
+ static SVFIR* read(const std::string& path);
1043
+
1044
+ static void readJson(const cJSON* obj, bool& flag);
1045
+ static void readJson(const cJSON* obj, unsigned& val);
1046
+ static void readJson(const cJSON* obj, int& val);
1047
+ static void readJson(const cJSON* obj, float& val);
1048
+ static void readJson(const cJSON* obj, unsigned long& val);
1049
+ static void readJson(const cJSON* obj, long long& val);
1050
+ static void readJson(const cJSON* obj, unsigned long long& val);
1051
+ static void readJson(const cJSON* obj, std::string& str);
1052
+
1053
+ // Helper functions
1054
+ static inline s64_t applyEdgeMask(u64_t edgeFlag)
1055
+ {
1056
+ return edgeFlag & GenericEdge<void>::EdgeKindMask;
1057
+ }
1058
+ template <typename T>
1059
+ static inline void setEdgeFlag(GenericEdge<T>* edge,
1060
+ typename GenericEdge<T>::GEdgeFlag edgeFlag)
1061
+ {
1062
+ edge->edgeFlag = edgeFlag;
1063
+ }
1064
+
1065
+ private:
1066
+ using GNodeK = GenericNode<int, GenericEdge<void>>::GNodeK;
1067
+ using GEdgeFlag = GenericEdge<void>::GEdgeFlag;
1068
+ using GEdgeKind = GenericEdge<void>::GEdgeKind;
1069
+ static ICFGNode* createICFGNode(NodeID id, GNodeK type);
1070
+ static ICFGEdge* createICFGEdge(GEdgeKind kind);
1071
+ static CHNode* createCHNode(NodeID id, GNodeK kind);
1072
+ static CHEdge* createCHEdge(GEdgeKind kind);
1073
+ static SVFVar* createPAGNode(NodeID id, GNodeK kind);
1074
+ static SVFStmt* createPAGEdge(GEdgeKind kind);
1075
+
1076
+ template <typename EdgeCreator>
1077
+ static inline auto createEdgeWithFlag(GEdgeFlag flag, EdgeCreator creator)
1078
+ {
1079
+ auto kind = SVFIRReader::applyEdgeMask(flag);
1080
+ auto edge = creator(kind);
1081
+ setEdgeFlag(edge, flag);
1082
+ return edge;
1083
+ }
1084
+
1085
+ SVFIR* read(const cJSON* root);
1086
+ const cJSON* createObjs(const cJSON* root);
1087
+
1088
+ void readJson(const cJSON* obj, NodeIDAllocator* idAllocator);
1089
+ void readJson(SymbolTableInfo* symTabInfo);
1090
+ void readJson(IRGraph* graph); // IRGraph Graph
1091
+ void readJson(ICFG* icfg); // ICFG Graph
1092
+ void readJson(CHGraph* graph); // CHGraph Graph
1093
+ void readJson(SVFModule* module);
1094
+
1095
+ void readJson(const cJSON* obj, SVFType*& type);
1096
+ void readJson(const cJSON* obj, StInfo*& stInfo);
1097
+ void readJson(const cJSON* obj, SVFValue*& value);
1098
+
1099
+ void readJson(const cJSON* obj, SVFVar*& var); // IRGraph Node
1100
+ void readJson(const cJSON* obj, SVFStmt*& stmt); // IRGraph Edge
1101
+ void readJson(const cJSON* obj, ICFGNode*& node); // ICFG Node
1102
+ void readJson(const cJSON* obj, ICFGEdge*& edge); // ICFG Edge
1103
+ void readJson(const cJSON* obj, CHNode*& node); // CHGraph Node
1104
+ void readJson(const cJSON* obj, CHEdge*& edge); // CHGraph Edge
1105
+ void readJson(const cJSON* obj, CallSite& cs); // CHGraph's csToClassMap
1106
+
1107
+ void readJson(const cJSON* obj, LocationSet& ls);
1108
+ void readJson(const cJSON* obj, SVFLoop*& loop);
1109
+ void readJson(const cJSON* obj, MemObj*& memObj);
1110
+ void readJson(const cJSON* obj,
1111
+ ObjTypeInfo*& objTypeInfo); // Only owned by MemObj
1112
+ void readJson(const cJSON* obj,
1113
+ SVFLoopAndDomInfo*& ldInfo); // Only owned by SVFFunction
1114
+
1115
+ template <unsigned ElementSize>
1116
+ inline void readJson(const cJSON* obj, SparseBitVector<ElementSize>& bv)
1117
+ {
1118
+ ABORT_IFNOT(jsonIsArray(obj), "SparseBitVector should be an array");
1119
+ jsonForEach(nObj, obj)
1120
+ {
1121
+ unsigned n;
1122
+ readJson(nObj, n);
1123
+ bv.set(n);
1124
+ }
1125
+ }
1126
+
1127
+ /* See comment of toJson(SparseBitVectorElement) for reason of commenting
1128
+ it out.
1129
+ template <unsigned ElementSize>
1130
+ inline void readJson(const cJSON* obj,
1131
+ SparseBitVectorElement<ElementSize>& element)
1132
+ {
1133
+ readJson(obj, element.Bits);
1134
+ }
1135
+ */
1136
+
1137
+ /// @brief Read a pointer of some child class of
1138
+ /// SVFType/SVFValue/SVFVar/SVFStmt/ICFGNode/ICFGEdge/CHNode/CHEdge
1139
+ template <typename T>
1140
+ inline SVFUtil::void_t<KindBaseT<T>> readJson(const cJSON* obj, T*& ptr)
1141
+ {
1142
+ // TODO: Can be optimized?
1143
+ KindBaseT<T>* basePtr = ptr;
1144
+ readJson(obj, basePtr);
1145
+ if (!basePtr)
1146
+ return; // ptr is nullptr when read
1147
+ ptr = SVFUtil::dyn_cast<T>(basePtr);
1148
+ ABORT_IFNOT(ptr, "Cast: " << obj->string << " shoudn't have kind "
1149
+ << KindBaseHelper<T>::getKind(ptr));
1150
+ }
1151
+
1152
+ /// Read a const pointer
1153
+ template <typename T> inline void readJson(const cJSON* obj, const T*& cptr)
1154
+ {
1155
+ assert(!cptr && "const pointer should be NULL");
1156
+ T* ptr{};
1157
+ readJson(obj, ptr);
1158
+ cptr = ptr;
1159
+ }
1160
+
1161
+ template <typename T1, typename T2>
1162
+ void readJson(const cJSON* obj, std::pair<T1, T2>& pair)
1163
+ {
1164
+ auto jpair = jsonUnpackPair(obj);
1165
+ readJson(jpair.first, pair.first);
1166
+ readJson(jpair.second, pair.second);
1167
+ }
1168
+
1169
+ template <typename T, size_t N>
1170
+ void readJson(const cJSON* obj, T (&array)[N])
1171
+ {
1172
+ static_assert(N > 0, "array size should be greater than 0");
1173
+ ABORT_IFNOT(jsonIsArray(obj), "array expects an array");
1174
+ size_t i = 0;
1175
+ jsonForEach(elemJson, obj)
1176
+ {
1177
+ readJson(elemJson, array[i]);
1178
+ if (++i >= N)
1179
+ break;
1180
+ }
1181
+ ABORT_IFNOT(i == N, "expect array of size " << N);
1182
+ }
1183
+
1184
+ template <typename C>
1185
+ std::enable_if_t<SVFUtil::is_sequence_container_v<C>> readJson(
1186
+ const cJSON* obj, C& container)
1187
+ {
1188
+ using T = typename C::value_type;
1189
+ assert(container.empty() && "container should be empty");
1190
+ ABORT_IFNOT(jsonIsArray(obj), "vector expects an array");
1191
+ jsonForEach(elemJson, obj)
1192
+ {
1193
+ container.push_back(T{});
1194
+ readJson(elemJson, container.back());
1195
+ }
1196
+ }
1197
+
1198
+ template <typename C>
1199
+ std::enable_if_t<SVFUtil::is_map_v<C>> readJson(const cJSON* obj, C& map)
1200
+ {
1201
+ assert(map.empty() && "map should be empty");
1202
+ ABORT_IFNOT(jsonIsMap(obj), "expects an map (represted by array)");
1203
+ jsonForEach(elemJson, obj)
1204
+ {
1205
+ auto jpair = jsonUnpackPair(elemJson);
1206
+ typename C::key_type key{};
1207
+ readJson(jpair.first, key);
1208
+ auto it = map.emplace(std::move(key), typename C::mapped_type{});
1209
+ ABORT_IFNOT(it.second, "Duplicated map key");
1210
+ readJson(jpair.second, it.first->second);
1211
+ }
1212
+ }
1213
+
1214
+ template <typename C>
1215
+ std::enable_if_t<SVFUtil::is_set_v<C>> readJson(const cJSON* obj, C& set)
1216
+ {
1217
+ using T = typename C::value_type;
1218
+ assert(set.empty() && "set should be empty");
1219
+ ABORT_IFNOT(jsonIsArray(obj), "expects an array");
1220
+ jsonForEach(elemJson, obj)
1221
+ {
1222
+ T elem{};
1223
+ readJson(elemJson, elem);
1224
+ auto inserted = set.insert(std::move(elem)).second;
1225
+ ABORT_IFNOT(inserted, "Duplicated set element");
1226
+ }
1227
+ }
1228
+
1229
+ // IGRaph
1230
+ void virtFill(const cJSON*& fieldJson, SVFVar* var);
1231
+ void fill(const cJSON*& fieldJson, SVFVar* var);
1232
+ void fill(const cJSON*& fieldJson, ValVar* var);
1233
+ void fill(const cJSON*& fieldJson, ObjVar* var);
1234
+ void fill(const cJSON*& fieldJson, GepValVar* var);
1235
+ void fill(const cJSON*& fieldJson, GepObjVar* var);
1236
+ void fill(const cJSON*& fieldJson, FIObjVar* var);
1237
+ void fill(const cJSON*& fieldJson, RetPN* var);
1238
+ void fill(const cJSON*& fieldJson, VarArgPN* var);
1239
+ void fill(const cJSON*& fieldJson, DummyValVar* var);
1240
+ void fill(const cJSON*& fieldJson, DummyObjVar* var);
1241
+
1242
+ void virtFill(const cJSON*& fieldJson, SVFStmt* stmt);
1243
+ void fill(const cJSON*& fieldJson, SVFStmt* stmt);
1244
+ void fill(const cJSON*& fieldJson, AssignStmt* stmt);
1245
+ void fill(const cJSON*& fieldJson, AddrStmt* stmt);
1246
+ void fill(const cJSON*& fieldJson, CopyStmt* stmt);
1247
+ void fill(const cJSON*& fieldJson, StoreStmt* stmt);
1248
+ void fill(const cJSON*& fieldJson, LoadStmt* stmt);
1249
+ void fill(const cJSON*& fieldJson, GepStmt* stmt);
1250
+ void fill(const cJSON*& fieldJson, CallPE* stmt);
1251
+ void fill(const cJSON*& fieldJson, RetPE* stmt);
1252
+ void fill(const cJSON*& fieldJson, MultiOpndStmt* stmt);
1253
+ void fill(const cJSON*& fieldJson, PhiStmt* stmt);
1254
+ void fill(const cJSON*& fieldJson, SelectStmt* stmt);
1255
+ void fill(const cJSON*& fieldJson, CmpStmt* stmt);
1256
+ void fill(const cJSON*& fieldJson, BinaryOPStmt* stmt);
1257
+ void fill(const cJSON*& fieldJson, UnaryOPStmt* stmt);
1258
+ void fill(const cJSON*& fieldJson, BranchStmt* stmt);
1259
+ void fill(const cJSON*& fieldJson, TDForkPE* stmt);
1260
+ void fill(const cJSON*& fieldJson, TDJoinPE* stmt);
1261
+
1262
+ void fill(const cJSON*& fieldJson, MemObj* memObj);
1263
+ void fill(const cJSON*& fieldJson, StInfo* stInfo);
1264
+ // ICFG
1265
+ void virtFill(const cJSON*& fieldJson, ICFGNode* node);
1266
+ void fill(const cJSON*& fieldJson, ICFGNode* node);
1267
+ void fill(const cJSON*& fieldJson, GlobalICFGNode* node);
1268
+ void fill(const cJSON*& fieldJson, IntraICFGNode* node);
1269
+ void fill(const cJSON*& fieldJson, InterICFGNode* node);
1270
+ void fill(const cJSON*& fieldJson, FunEntryICFGNode* node);
1271
+ void fill(const cJSON*& fieldJson, FunExitICFGNode* node);
1272
+ void fill(const cJSON*& fieldJson, CallICFGNode* node);
1273
+ void fill(const cJSON*& fieldJson, RetICFGNode* node);
1274
+
1275
+ void virtFill(const cJSON*& fieldJson, ICFGEdge* node);
1276
+ void fill(const cJSON*& fieldJson, ICFGEdge* edge);
1277
+ void fill(const cJSON*& fieldJson, IntraCFGEdge* edge);
1278
+ void fill(const cJSON*& fieldJson, CallCFGEdge* edge);
1279
+ void fill(const cJSON*& fieldJson, RetCFGEdge* edge);
1280
+
1281
+ void fill(const cJSON*& fieldJson, SVFLoop* loop);
1282
+ // CHGraph
1283
+ void virtFill(const cJSON*& fieldJson, CHNode* node);
1284
+ void virtFill(const cJSON*& fieldJson, CHEdge* edge);
1285
+
1286
+ // SVFModule
1287
+ void virtFill(const cJSON*& fieldJson, SVFValue* value);
1288
+ void fill(const cJSON*& fieldJson, SVFValue* value);
1289
+ void fill(const cJSON*& fieldJson, SVFFunction* value);
1290
+ void fill(const cJSON*& fieldJson, SVFBasicBlock* value);
1291
+ void fill(const cJSON*& fieldJson, SVFInstruction* value);
1292
+ void fill(const cJSON*& fieldJson, SVFCallInst* value);
1293
+ void fill(const cJSON*& fieldJson, SVFVirtualCallInst* value);
1294
+ void fill(const cJSON*& fieldJson, SVFConstant* value);
1295
+ void fill(const cJSON*& fieldJson, SVFGlobalValue* value);
1296
+ void fill(const cJSON*& fieldJson, SVFArgument* value);
1297
+ void fill(const cJSON*& fieldJson, SVFConstantData* value);
1298
+ void fill(const cJSON*& fieldJson, SVFConstantInt* value);
1299
+ void fill(const cJSON*& fieldJson, SVFConstantFP* value);
1300
+ void fill(const cJSON*& fieldJson, SVFConstantNullPtr* value);
1301
+ void fill(const cJSON*& fieldJson, SVFBlackHoleValue* value);
1302
+ void fill(const cJSON*& fieldJson, SVFOtherValue* value);
1303
+ void fill(const cJSON*& fieldJson, SVFMetadataAsValue* value);
1304
+
1305
+ void virtFill(const cJSON*& fieldJson, SVFType* type);
1306
+ void fill(const cJSON*& fieldJson, SVFType* type);
1307
+ void fill(const cJSON*& fieldJson, SVFPointerType* type);
1308
+ void fill(const cJSON*& fieldJson, SVFIntegerType* type);
1309
+ void fill(const cJSON*& fieldJson, SVFFunctionType* type);
1310
+ void fill(const cJSON*& fieldJson, SVFStructType* type);
1311
+ void fill(const cJSON*& fieldJson, SVFArrayType* type);
1312
+ void fill(const cJSON*& fieldJson, SVFOtherType* type);
1313
+
1314
+ template <typename NodeTy, typename EdgeTy>
1315
+ void fill(const cJSON*& fieldJson, GenericNode<NodeTy, EdgeTy>* node)
1316
+ {
1317
+ // id and nodeKind have already been read.
1318
+ JSON_READ_FIELD_FWD(fieldJson, node, InEdges);
1319
+ JSON_READ_FIELD_FWD(fieldJson, node, OutEdges);
1320
+ }
1321
+
1322
+ template <typename NodeTy>
1323
+ void fill(const cJSON*& fieldJson, GenericEdge<NodeTy>* edge)
1324
+ {
1325
+ // edgeFlag has already been read.
1326
+ JSON_READ_FIELD_FWD(fieldJson, edge, src);
1327
+ JSON_READ_FIELD_FWD(fieldJson, edge, dst);
1328
+ }
1329
+ };
1330
+
1331
+ } // namespace SVF
1332
+
1333
+ #endif // !INCLUDE_SVFFILESYSTEM_H_