svf-tools 1.0.693 → 1.0.695

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