svf-tools 1.0.678 → 1.0.680

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,624 @@
1
+ #ifndef INCLUDE_SVFIRRW_H_
2
+ #define INCLUDE_SVFIRRW_H_
3
+
4
+ #include "Util/SVFUtil.h"
5
+ #include "Util/cJSON.h"
6
+ #include "Graphs/GenericGraph.h"
7
+ #include <type_traits>
8
+
9
+ #if 1
10
+ # define ENSURE_NOT_VISITED(graph) \
11
+ do \
12
+ { \
13
+ static std::set<decltype(graph)> visited; \
14
+ bool inserted = visited.insert(graph).second; \
15
+ ABORT_IFNOT(!inserted, #graph " already visited!"); \
16
+ } while (0)
17
+ #else
18
+ # define ENSURE_NOT_VISITED(graph) \
19
+ do \
20
+ { \
21
+ } while (0)
22
+ #endif
23
+
24
+ #define ABORT_IFNOT(condition, reason) \
25
+ do \
26
+ { \
27
+ if (!(condition)) \
28
+ { \
29
+ SVFUtil::errs() \
30
+ << __FILE__ << ':' << __LINE__ << ": " << reason << '\n'; \
31
+ abort(); \
32
+ } \
33
+ } while (0)
34
+
35
+ #define JSON_WRITE_FIELD(root, objptr, field) \
36
+ jsonAddJsonableToObject(root, #field, (objptr)->field)
37
+
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
+ ///@}
54
+
55
+ namespace SVF
56
+ {
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;
70
+ class SVFType;
71
+ class SVFPointerType;
72
+ class SVFIntegerType;
73
+ class SVFFunctionType;
74
+ class SVFStructType;
75
+ class SVFArrayType;
76
+ class SVFOtherType;
77
+
78
+ class SVFLoopAndDomInfo;
79
+ class SVFValue;
80
+ class SVFFunction;
81
+ class SVFBasicBlock;
82
+ class SVFInstruction;
83
+ class SVFCallInst;
84
+ class SVFVirtualCallInst;
85
+ class SVFConstant;
86
+ class SVFGlobalValue;
87
+ class SVFArgument;
88
+ class SVFConstantData;
89
+ class SVFConstantInt;
90
+ class SVFConstantFP;
91
+ class SVFConstantNullPtr;
92
+ class SVFBlackHoleValue;
93
+ class SVFOtherValue;
94
+ class SVFMetadataAsValue;
95
+
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;
106
+
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;
125
+
126
+ class ICFGNode;
127
+ class GlobalICFGNode;
128
+ class IntraICFGNode;
129
+ class InterICFGNode;
130
+ class FunEntryICFGNode;
131
+ class FunExitICFGNode;
132
+ class CallICFGNode;
133
+ class RetICFGNode;
134
+
135
+ class ICFGEdge;
136
+ class IntraCFGEdge;
137
+ class CallCFGEdge;
138
+ class RetCFGEdge;
139
+
140
+
141
+ class SVFModule;
142
+
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
+ 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;
171
+
172
+ class SVFVar;
173
+ class ValVar;
174
+ class ObjVar;
175
+ class GepValVar;
176
+ class GepObjVar;
177
+ class FIObjVar;
178
+ class RetPN;
179
+ class VarArgPN;
180
+ class DummyValVar;
181
+ class DummyObjVar;
182
+
183
+ class SVFStmt;
184
+ class AssignStmt;
185
+ class AddrStmt;
186
+ class CopyStmt;
187
+ class StoreStmt;
188
+ class LoadStmt;
189
+ class GepStmt;
190
+ class CallPE;
191
+ class RetPE;
192
+ class MultiOpndStmt;
193
+ class PhiStmt;
194
+ class SelectStmt;
195
+ class CmpStmt;
196
+ class BinaryOPStmt;
197
+ class UnaryOPStmt;
198
+ class BranchStmt;
199
+ class TDForkPE;
200
+ class TDJoinPE;
201
+
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
+ class CHNode;
217
+ class CHEdge;
218
+ class CHGraph;
219
+
220
+ cJSON* jsonCreateNullId();
221
+ bool jsonIsNullId(const cJSON* item);
222
+ cJSON* jsonCreateObject();
223
+ cJSON* jsonCreateArray();
224
+ cJSON* jsonCreateMap();
225
+ cJSON* jsonCreateString(const char* str);
226
+ cJSON* jsonCreateIndex(size_t index);
227
+ cJSON* jsonCreateNumber(double num);
228
+ bool jsonAddPairToMap(cJSON* obj, cJSON* key, cJSON* value);
229
+ bool jsonAddItemToObject(cJSON* obj, const char* name, cJSON* item);
230
+ bool jsonAddItemToArray(cJSON* array, cJSON* item);
231
+ /// @brief Helper function to write a number to a JSON object.
232
+ bool jsonAddNumberToObject(cJSON* obj, const char* name, double number);
233
+ 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
238
+ {
239
+ private:
240
+ Map<const T*, size_t> ptrToId;
241
+ std::vector<const T*> ptrPool;
242
+
243
+ public:
244
+ inline size_t getID(const T* ptr)
245
+ {
246
+ if (ptr == nullptr)
247
+ return 0;
248
+ auto it_inserted = ptrToId.emplace(ptr, 1 + ptrPool.size());
249
+ if (it_inserted.second)
250
+ ptrPool.push_back(ptr);
251
+ return it_inserted.first->second;
252
+ }
253
+
254
+ inline void saveID(const T* ptr)
255
+ {
256
+ getID(ptr);
257
+ }
258
+
259
+ inline const T* getPtr(size_t id) const
260
+ {
261
+ assert(id >= 0 && id <= ptrPool.size() && "Invalid ID.");
262
+ return id ? ptrPool[id - 1] : nullptr;
263
+ }
264
+
265
+ inline const std::vector<const T*>& getPool() const
266
+ {
267
+ return ptrPool;
268
+ }
269
+
270
+ size_t size() const
271
+ {
272
+ return ptrPool.size();
273
+ }
274
+ };
275
+
276
+ template <typename NodeTy, typename EdgeTy> class GenericGraphWriter
277
+ {
278
+ friend class SVFIRWriter;
279
+
280
+ private:
281
+ using NodeType = NodeTy;
282
+ using EdgeType = EdgeTy;
283
+ using GraphType = GenericGraph<NodeType, EdgeType>;
284
+
285
+ const GraphType* graph;
286
+ OrderedMap<const NodeType*, NodeID> nodeToID;
287
+ PtrPool<EdgeType> edgePool;
288
+
289
+ public:
290
+ GenericGraphWriter(const GraphType* g) : graph(g)
291
+ {
292
+ assert(g && "Graph pointer should never be null");
293
+
294
+ for (const auto& entry : graph->IDToNodeMap)
295
+ {
296
+ const NodeID id = entry.first;
297
+ const NodeType* node = entry.second;
298
+
299
+ nodeToID.emplace(node, id);
300
+ for (const EdgeType* edge : node->getOutEdges())
301
+ {
302
+ edgePool.saveID(edge);
303
+ }
304
+ }
305
+ }
306
+
307
+ inline size_t getEdgeID(const EdgeType* edge)
308
+ {
309
+ return edgePool.getID(edge);
310
+ }
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
+ };
319
+
320
+ using GenericICFGWriter = GenericGraphWriter<ICFGNode, ICFGEdge>;
321
+
322
+ class ICFGWriter : public GenericICFGWriter
323
+ {
324
+ friend class SVFIRWriter;
325
+
326
+ private:
327
+ PtrPool<SVFLoop> svfLoopPool;
328
+
329
+ public:
330
+ ICFGWriter(const ICFG* icfg);
331
+
332
+ inline size_t getSvfLoopID(const SVFLoop* loop)
333
+ {
334
+ return svfLoopPool.getID(loop);
335
+ }
336
+ };
337
+
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
+ using IRGraphWriter = GenericGraphWriter<SVFVar, SVFStmt>;
351
+ using CHGraphWriter = GenericGraphWriter<CHNode, CHEdge>;
352
+
353
+ class SVFModuleWriter
354
+ {
355
+ friend class SVFIRWriter;
356
+
357
+ PtrPool<SVFType> svfTypePool;
358
+ PtrPool<SVFValue> svfValuePool;
359
+
360
+ size_t getSvfTypeID(const SVFType* type);
361
+ size_t getSvfValueID(const SVFValue* value);
362
+ };
363
+
364
+ class SVFIRWriter
365
+ {
366
+ private:
367
+ const SVFIR* svfIR;
368
+
369
+ SVFModuleWriter svfModuleWriter;
370
+ IRGraphWriter irGraphWriter;
371
+ ICFGWriter icfgWriter;
372
+ CHGraphWriter chgWriter;
373
+ SymbolTableInfoWriter symbolTableInfoWriter;
374
+
375
+ OrderedMap<size_t, std::string> numToStrMap;
376
+
377
+ public:
378
+ using autoJSON = std::unique_ptr<cJSON, decltype(&cJSON_Delete)>;
379
+ using autoCStr = std::unique_ptr<char, decltype(&cJSON_free)>;
380
+
381
+ SVFIRWriter(const SVFIR* svfir);
382
+
383
+ static void writeJsonToOstream(const SVFIR* svfir, std::ostream& os);
384
+ static void writeJsonToPath(const SVFIR* svfir, const std::string& path);
385
+
386
+ private:
387
+ /// @brief Main logic to dump a SVFIR to a JSON object.
388
+ autoJSON generateJson();
389
+ autoCStr generateJsonString();
390
+
391
+ const char* numToStr(size_t n);
392
+
393
+ cJSON* toJson(const SVFModule* module);
394
+ cJSON* toJson(const SVFType* type);
395
+ 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
402
+ 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
406
+
407
+ cJSON* toJson(const CallSite& cs);
408
+ cJSON* toJson(const LocationSet& ls);
409
+ cJSON* toJson(const SVFLoop* loop);
410
+ cJSON* toJson(const MemObj* memObj);
411
+ cJSON* toJson(const ObjTypeInfo* objTypeInfo); // Ensures ownership
412
+ cJSON* toJson(const SVFLoopAndDomInfo* ldInfo); // Only owned by SVFFunction
413
+ cJSON* toJson(const StInfo* type); // Ensure Only owned by SVFType
414
+
415
+ static cJSON* toJson(unsigned number);
416
+ static cJSON* toJson(int number);
417
+ static cJSON* toJson(float number);
418
+ cJSON* toJson(unsigned long number);
419
+ cJSON* toJson(long long number);
420
+ cJSON* toJson(unsigned long long number);
421
+
422
+ /// \brief Parameter types of these functions are all pointers.
423
+ /// When they are used as arguments of toJson(), they will be
424
+ /// dumped as an index. `contentToJson()` will dump the actual content.
425
+ ///@{
426
+ cJSON* virtToJson(const SVFType* type);
427
+ cJSON* virtToJson(const SVFValue* value);
428
+ cJSON* virtToJson(const SVFVar* var);
429
+ cJSON* virtToJson(const SVFStmt* stmt);
430
+ cJSON* virtToJson(const ICFGNode* node);
431
+ cJSON* virtToJson(const ICFGEdge* edge);
432
+ cJSON* virtToJson(const CHNode* node);
433
+ cJSON* virtToJson(const CHEdge* edge);
434
+
435
+ // Classes inherited from SVFVar
436
+ cJSON* contentToJson(const SVFVar* var);
437
+ cJSON* contentToJson(const ValVar* var);
438
+ cJSON* contentToJson(const ObjVar* var);
439
+ cJSON* contentToJson(const GepValVar* var);
440
+ cJSON* contentToJson(const GepObjVar* var);
441
+ cJSON* contentToJson(const FIObjVar* var);
442
+ cJSON* contentToJson(const RetPN* var);
443
+ cJSON* contentToJson(const VarArgPN* var);
444
+ cJSON* contentToJson(const DummyValVar* var);
445
+ cJSON* contentToJson(const DummyObjVar* var);
446
+
447
+ // Classes inherited from SVFStmt
448
+ cJSON* contentToJson(const SVFStmt* edge);
449
+ cJSON* contentToJson(const AssignStmt* edge);
450
+ cJSON* contentToJson(const AddrStmt* edge);
451
+ cJSON* contentToJson(const CopyStmt* edge);
452
+ cJSON* contentToJson(const StoreStmt* edge);
453
+ cJSON* contentToJson(const LoadStmt* edge);
454
+ cJSON* contentToJson(const GepStmt* edge);
455
+ cJSON* contentToJson(const CallPE* edge);
456
+ cJSON* contentToJson(const RetPE* edge);
457
+ cJSON* contentToJson(const MultiOpndStmt* edge);
458
+ cJSON* contentToJson(const PhiStmt* edge);
459
+ cJSON* contentToJson(const SelectStmt* edge);
460
+ cJSON* contentToJson(const CmpStmt* edge);
461
+ cJSON* contentToJson(const BinaryOPStmt* edge);
462
+ cJSON* contentToJson(const UnaryOPStmt* edge);
463
+ cJSON* contentToJson(const BranchStmt* edge);
464
+ cJSON* contentToJson(const TDForkPE* edge);
465
+ cJSON* contentToJson(const TDJoinPE* edge);
466
+
467
+ // Classes inherited from ICFGNode
468
+ cJSON* contentToJson(const ICFGNode* node);
469
+ cJSON* contentToJson(const GlobalICFGNode* node);
470
+ cJSON* contentToJson(const IntraICFGNode* node);
471
+ cJSON* contentToJson(const InterICFGNode* node);
472
+ cJSON* contentToJson(const FunEntryICFGNode* node);
473
+ cJSON* contentToJson(const FunExitICFGNode* node);
474
+ cJSON* contentToJson(const CallICFGNode* node);
475
+ cJSON* contentToJson(const RetICFGNode* node);
476
+
477
+ // Classes inherited from ICFGEdge
478
+ cJSON* contentToJson(const ICFGEdge* edge);
479
+ cJSON* contentToJson(const IntraCFGEdge* edge);
480
+ cJSON* contentToJson(const CallCFGEdge* edge);
481
+ cJSON* contentToJson(const RetCFGEdge* edge);
482
+
483
+ // CHNode & CHEdge
484
+ cJSON* contentToJson(const CHNode* node);
485
+ cJSON* contentToJson(const CHEdge* edge);
486
+
487
+ cJSON* contentToJson(const SVFType* type);
488
+ cJSON* contentToJson(const SVFPointerType* type);
489
+ cJSON* contentToJson(const SVFIntegerType* type);
490
+ cJSON* contentToJson(const SVFFunctionType* type);
491
+ cJSON* contentToJson(const SVFStructType* type);
492
+ cJSON* contentToJson(const SVFArrayType* type);
493
+ cJSON* contentToJson(const SVFOtherType* type);
494
+
495
+ cJSON* contentToJson(const SVFValue* value);
496
+ cJSON* contentToJson(const SVFFunction* value);
497
+ cJSON* contentToJson(const SVFBasicBlock* value);
498
+ cJSON* contentToJson(const SVFInstruction* value);
499
+ cJSON* contentToJson(const SVFCallInst* value);
500
+ cJSON* contentToJson(const SVFVirtualCallInst* value);
501
+ cJSON* contentToJson(const SVFConstant* value);
502
+ cJSON* contentToJson(const SVFGlobalValue* value);
503
+ cJSON* contentToJson(const SVFArgument* value);
504
+ cJSON* contentToJson(const SVFConstantData* value);
505
+ cJSON* contentToJson(const SVFConstantInt* value);
506
+ cJSON* contentToJson(const SVFConstantFP* value);
507
+ cJSON* contentToJson(const SVFConstantNullPtr* value);
508
+ cJSON* contentToJson(const SVFBlackHoleValue* value);
509
+ cJSON* contentToJson(const SVFOtherValue* value);
510
+ cJSON* contentToJson(const SVFMetadataAsValue* value);
511
+
512
+ // Other classes
513
+ cJSON* contentToJson(const SVFLoop* loop);
514
+ cJSON* contentToJson(const SymbolTableInfo* symTable);
515
+ cJSON* contentToJson(const MemObj* memObj); // Owned by SymbolTable->objMap
516
+ ///@}
517
+
518
+ template <typename NodeTy, typename EdgeTy>
519
+ cJSON* genericNodeToJson(const GenericNode<NodeTy, EdgeTy>* node)
520
+ {
521
+ cJSON* root = jsonCreateObject();
522
+ JSON_WRITE_FIELD(root, node, id);
523
+ JSON_WRITE_FIELD(root, node, nodeKind);
524
+ JSON_WRITE_FIELD(root, node, InEdges);
525
+ JSON_WRITE_FIELD(root, node, OutEdges);
526
+ return root;
527
+ }
528
+
529
+ template <typename NodeTy>
530
+ cJSON* genericEdgeToJson(const GenericEdge<NodeTy>* edge)
531
+ {
532
+ cJSON* root = jsonCreateObject();
533
+ JSON_WRITE_FIELD(root, edge, src);
534
+ JSON_WRITE_FIELD(root, edge, dst);
535
+ JSON_WRITE_FIELD(root, edge, edgeFlag);
536
+ return root;
537
+ }
538
+
539
+ template <typename NodeTy, typename EdgeTy>
540
+ cJSON* genericGraphToJson(const GenericGraph<NodeTy, EdgeTy>* graph,
541
+ const std::vector<const EdgeTy*>& edgePool)
542
+ {
543
+ cJSON* root = jsonCreateObject();
544
+
545
+ JSON_WRITE_FIELD(root, graph, edgeNum);
546
+ JSON_WRITE_FIELD(root, graph, nodeNum);
547
+
548
+ cJSON* map = jsonCreateMap();
549
+ for (const auto& pair : graph->IDToNodeMap)
550
+ {
551
+ NodeID id = pair.first;
552
+ NodeTy* node = pair.second;
553
+
554
+ cJSON* jsonID = jsonCreateIndex(id);
555
+ cJSON* jsonNode = virtToJson(node);
556
+ jsonAddPairToMap(map, jsonID, jsonNode);
557
+ }
558
+
559
+ cJSON* edgesJson = jsonCreateArray();
560
+ for (const EdgeTy* edge : edgePool)
561
+ {
562
+ cJSON* edgeJson = virtToJson(edge);
563
+ jsonAddItemToArray(edgesJson, edgeJson);
564
+ }
565
+ jsonAddItemToObject(root, "edges", edgesJson);
566
+
567
+ return root;
568
+ }
569
+
570
+ template <unsigned ElementSize>
571
+ cJSON* toJson(const SparseBitVectorElement<ElementSize> &element)
572
+ {
573
+ cJSON* array = jsonCreateArray();
574
+ for (const auto v : element.Bits)
575
+ {
576
+ jsonAddItemToArray(array, toJson(v));
577
+ }
578
+ return array;
579
+ }
580
+
581
+ template <unsigned ElementSize>
582
+ cJSON* toJson(const SparseBitVector<ElementSize>& bv)
583
+ {
584
+ return toJson(bv.Elements);
585
+ }
586
+
587
+ template <typename T, typename U> cJSON* toJson(const std::pair<T, U>& pair)
588
+ {
589
+ cJSON* obj = jsonCreateArray();
590
+ jsonAddItemToArray(obj, toJson(pair.first));
591
+ jsonAddItemToArray(obj, toJson(pair.second));
592
+ return obj;
593
+ }
594
+
595
+ template <typename T, typename = std::enable_if_t<is_iterable_v<T>>>
596
+ cJSON* toJson(const T& container)
597
+ {
598
+ cJSON* array = jsonCreateArray();
599
+ for (const auto& item : container)
600
+ {
601
+ cJSON* itemObj = toJson(item);
602
+ jsonAddItemToArray(array, itemObj);
603
+ }
604
+ return array;
605
+ }
606
+
607
+ template <typename T>
608
+ bool jsonAddJsonableToObject(cJSON* obj, const char* name, const T& item)
609
+ {
610
+ cJSON* itemObj = toJson(item);
611
+ return jsonAddItemToObject(obj, name, itemObj);
612
+ }
613
+
614
+ template <typename T>
615
+ bool jsonAddContentToObject(cJSON* obj, const char* name, const T& item)
616
+ {
617
+ cJSON* itemObj = contentToJson(item);
618
+ return jsonAddItemToObject(obj, name, itemObj);
619
+ }
620
+ };
621
+
622
+ } // namespace SVF
623
+
624
+ #endif // !INCLUDE_SVFIRRW_H_
@@ -42,6 +42,7 @@ class SVFModule
42
42
  {
43
43
  friend class SVFModuleWrite;
44
44
  friend class SVFModuleRead;
45
+ friend class SVFIRWriter;
45
46
 
46
47
  public:
47
48
  typedef std::vector<const SVFFunction*> FunctionSetType;
@@ -76,18 +76,15 @@ class SVFModuleWrite
76
76
  {
77
77
  private:
78
78
  const SVFModule* module; ///< Borrowed pointer to the SVFModule.
79
- const char* jsonStr; ///< Json string of the SVFModule. It gets freed by
80
- /// `cJSON_free()` in destructor.
79
+ const char* jsonStr; ///< Json string of the SVFModule. It gets freed by `cJSON_free()` in destructor.
81
80
 
82
81
  std::unordered_map<const SVFType*, TypeIndex> typeToIndex;
83
- std::vector<const SVFType*>
84
- typePool; ///< A pool of all SVFTypes in the SVFModule
82
+ std::vector<const SVFType*> typePool; ///< A pool of all SVFTypes in the SVFModule
85
83
  TypeIndex getTypeIndex(const SVFType* type);
86
84
  const char* getStrTypeIndex(const SVFType* type);
87
85
 
88
86
  std::unordered_map<const SVFValue*, ValueIndex> valueToIndex;
89
- std::vector<const SVFValue*>
90
- valuePool; ///< A pool of all SVFValues in the SVFModule
87
+ std::vector<const SVFValue*> valuePool; ///< A pool of all SVFValues in the SVFModule
91
88
  ValueIndex getValueIndex(const SVFValue* value);
92
89
  const char* getStrValueIndex(const SVFValue* value);
93
90