Static Value-Flow Analysis
SVFFileSystem.cpp
Go to the documentation of this file.
1 #include "SVFIR/SVFFileSystem.h"
2 #include "Graphs/CHG.h"
3 #include "SVFIR/SVFIR.h"
4 #include "Util/CommandLine.h"
5 #include <sys/fcntl.h>
6 #include <sys/mman.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10 
12  "human-readable", "Whether to output human-readable JSON", true);
13 
14 namespace SVF
15 {
16 
17 SVFType* createSVFType(SVFType::GNodeK kind, bool isSingleValTy)
18 {
19  switch (kind)
20  {
21  default:
22  ABORT_MSG(kind << " is an impossible SVFTyKind in create()");
23  case SVFType::SVFTy:
24  ABORT_MSG("Creation of RAW SVFType isn't allowed");
26  ABORT_IFNOT(isSingleValTy, "Pointer type must be single-valued");
27  return new SVFPointerType();
29  ABORT_IFNOT(isSingleValTy, "Integer type must be single-valued");
30  return new SVFIntegerType();
32  ABORT_IFNOT(!isSingleValTy, "Function type must be multi-valued");
33  return new SVFFunctionType(nullptr);
35  ABORT_IFNOT(!isSingleValTy, "Struct type must be multi-valued");
36  return new SVFStructType();
38  ABORT_IFNOT(!isSingleValTy, "Array type must be multi-valued");
39  return new SVFArrayType();
41  return new SVFOtherType(isSingleValTy);
42  }
43 }
44 
46  std::string&& name)
47 {
48  auto creator = [=]() -> SVFValue*
49  {
50  switch (kind)
51  {
52  default:
53  ABORT_MSG(kind << " is an impossible SVFValueKind in create()");
54  case SVFValue::SVFVal:
55  ABORT_MSG("Creation of RAW SVFValue isn't allowed");
56  case SVFValue::SVFFunc:
57  return new SVFFunction(type, {}, {}, {}, {}, {}, {});
58  case SVFValue::SVFBB:
59  return new SVFBasicBlock(type, {});
60  case SVFValue::SVFInst:
61  return new SVFInstruction(type, {}, {}, {});
62  case SVFValue::SVFCall:
63  return new SVFCallInst(type, {}, {}, {});
64  case SVFValue::SVFVCall:
65  return new SVFVirtualCallInst(type, {}, {}, {});
66  case SVFValue::SVFGlob:
67  return new SVFGlobalValue(type);
68  case SVFValue::SVFArg:
69  return new SVFArgument(type, {}, {}, {});
70  case SVFValue::SVFConst:
71  return new SVFConstant(type);
73  return new SVFConstantData(type);
75  return new SVFConstantInt(type, {}, {});
77  return new SVFConstantFP(type, {});
79  return new SVFConstantNullPtr(type);
81  return new SVFBlackHoleValue(type);
83  return new SVFMetadataAsValue(type);
84  case SVFValue::SVFOther:
85  return new SVFOtherValue(type);
86  }
87  };
88  auto val = creator();
89  val->setName(std::move(name));
90  return val;
91 }
92 
93 template <typename SmallNumberType>
94 static inline void readSmallNumber(const cJSON* obj, SmallNumberType& val)
95 {
96  val = static_cast<SmallNumberType>(jsonGetNumber(obj));
97 }
98 
99 template <typename BigNumberType, typename CStrToVal>
100 static inline void readBigNumber(const cJSON* obj, BigNumberType& val, CStrToVal conv)
101 {
103  "Expect (number) string JSON for " << JSON_KEY(obj));
104  val = conv(obj->valuestring);
105 }
106 
108 {
109  return jsonCreateBool(flag);
110 }
111 
113 {
114  // OK, double precision enough
115  return jsonCreateNumber(number);
116 }
117 
119 {
120  // OK, double precision enough
121  return jsonCreateNumber(number);
122 }
123 
125 {
126  return jsonCreateString(str.c_str());
127 }
128 
130 {
131  return jsonCreateNumber(number);
132 }
133 
135 {
136  // unsigned long is subset of unsigned long long
137  return toJson(static_cast<unsigned long long>(number));
138 }
139 
141 {
142  return toJson(static_cast<unsigned long long>(number));
143 }
144 
145 cJSON* SVFIRWriter::toJson(unsigned long long number)
146 {
148 }
149 
151 {
152  auto kind = type->getKind();
153 
154  switch (kind)
155  {
156  default:
157  assert(false && "Impossible SVFType kind");
158 
159 #define CASE(Kind) \
160  case SVFType::Kind: \
161  return contentToJson(static_cast<const Kind##pe*>(type))
162 
163  CASE(SVFTy);
164  CASE(SVFPointerTy);
165  CASE(SVFIntegerTy);
166  CASE(SVFFunctionTy);
167  CASE(SVFStructTy);
168  CASE(SVFArrayTy);
169  CASE(SVFOtherTy);
170 #undef CASE
171  }
172 }
173 
175 {
176  auto kind = value->getKind();
177 
178  switch (kind)
179  {
180  default:
181  assert(false && "Impossible SVFValue kind");
182 
183 #define CASE(ValueKind, type) \
184  case SVFValue::ValueKind: \
185  return contentToJson(static_cast<const type*>(value))
186 
187  CASE(SVFVal, SVFValue);
188  CASE(SVFFunc, SVFFunction);
189  CASE(SVFBB, SVFBasicBlock);
190  CASE(SVFInst, SVFInstruction);
191  CASE(SVFCall, SVFCallInst);
192  CASE(SVFVCall, SVFVirtualCallInst);
193  CASE(SVFGlob, SVFGlobalValue);
194  CASE(SVFArg, SVFArgument);
195  CASE(SVFConst, SVFConstant);
196  CASE(SVFConstData, SVFConstantData);
197  CASE(SVFConstInt, SVFConstantInt);
198  CASE(SVFConstFP, SVFConstantFP);
199  CASE(SVFNullPtr, SVFConstantNullPtr);
200  CASE(SVFBlackHole, SVFBlackHoleValue);
201  CASE(SVFMetaAsValue, SVFMetadataAsValue);
202  CASE(SVFOther, SVFOtherValue);
203 #undef CASE
204  }
205 }
206 
208 {
209  switch (var->getNodeKind())
210  {
211  default:
212  assert(false && "Unknown SVFVar kind");
213 
214 #define CASE(VarKind, VarType) \
215  case SVFVar::VarKind: \
216  return contentToJson(static_cast<const VarType*>(var))
217 
218  CASE(ValNode, ValVar);
219  CASE(ObjNode, ObjVar);
220  CASE(RetNode, RetPN);
221  CASE(VarargNode, VarArgPN);
222  CASE(GepValNode, GepValVar);
223  CASE(GepObjNode, GepObjVar);
224  CASE(FIObjNode, FIObjVar);
225  CASE(DummyValNode, DummyValVar);
226  CASE(DummyObjNode, DummyObjVar);
227 #undef CASE
228  }
229 }
230 
232 {
233  switch (stmt->getEdgeKind())
234  {
235  default:
236  assert(false && "Unknown SVFStmt kind");
237 
238 #define CASE(EdgeKind, EdgeType) \
239  case SVFStmt::EdgeKind: \
240  return contentToJson(static_cast<const EdgeType*>(stmt))
241 
242  CASE(Addr, AddrStmt);
243  CASE(Copy, CopyStmt);
244  CASE(Store, StoreStmt);
245  CASE(Load, LoadStmt);
246  CASE(Call, CallPE);
247  CASE(Ret, RetPE);
248  CASE(Gep, GepStmt);
249  CASE(Phi, PhiStmt);
250  CASE(Select, SelectStmt);
251  CASE(Cmp, CmpStmt);
252  CASE(BinaryOp, BinaryOPStmt);
253  CASE(UnaryOp, UnaryOPStmt);
254  CASE(Branch, BranchStmt);
255  CASE(ThreadFork, TDForkPE);
256  CASE(ThreadJoin, TDJoinPE);
257 #undef CASE
258  }
259 }
260 
262 {
263  switch (node->getNodeKind())
264  {
265  default:
266  assert(false && "Unknown ICFGNode kind");
267 
268 #define CASE(NodeKind, NodeType) \
269  case ICFGNode::NodeKind: \
270  return contentToJson(static_cast<const NodeType*>(node))
271 
272  CASE(IntraBlock, IntraICFGNode);
273  CASE(FunEntryBlock, FunEntryICFGNode);
274  CASE(FunExitBlock, FunExitICFGNode);
275  CASE(FunCallBlock, CallICFGNode);
276  CASE(FunRetBlock, RetICFGNode);
277  CASE(GlobalBlock, GlobalICFGNode);
278 #undef CASE
279  }
280 }
281 
283 {
284  switch (edge->getEdgeKind())
285  {
286  default:
287  assert(false && "Unknown ICFGEdge kind");
288  case ICFGEdge::IntraCF:
289  return contentToJson(static_cast<const IntraCFGEdge*>(edge));
290  case ICFGEdge::CallCF:
291  return contentToJson(static_cast<const CallCFGEdge*>(edge));
292  case ICFGEdge::RetCF:
293  return contentToJson(static_cast<const RetCFGEdge*>(edge));
294  }
295 }
296 
298 {
299  return contentToJson(node);
300 }
301 
303 {
304  return contentToJson(edge);
305 }
306 
308 {
309  cJSON* root = genericNodeToJson(var);
310  JSON_WRITE_FIELD(root, var, value);
311  JSON_WRITE_FIELD(root, var, InEdgeKindToSetMap);
312  JSON_WRITE_FIELD(root, var, OutEdgeKindToSetMap);
313  JSON_WRITE_FIELD(root, var, isPtr);
314  return root;
315 }
316 
318 {
319  return contentToJson(static_cast<const SVFVar*>(var));
320 }
321 
323 {
324  cJSON* root = contentToJson(static_cast<const SVFVar*>(var));
325  JSON_WRITE_FIELD(root, var, mem);
326  return root;
327 }
328 
330 {
331  cJSON* root = contentToJson(static_cast<const ValVar*>(var));
332  JSON_WRITE_FIELD(root, var, ap);
333  JSON_WRITE_FIELD(root, var, gepValType);
334  return root;
335 }
336 
338 {
339  cJSON* root = contentToJson(static_cast<const ObjVar*>(var));
340  JSON_WRITE_FIELD(root, var, apOffset);
341  JSON_WRITE_FIELD(root, var, base);
342  return root;
343 }
344 
346 {
347  return contentToJson(static_cast<const ObjVar*>(var));
348 }
349 
351 {
352  return contentToJson(static_cast<const ValVar*>(var));
353 }
354 
356 {
357  return contentToJson(static_cast<const ValVar*>(var));
358 }
359 
361 {
362  return contentToJson(static_cast<const ValVar*>(var));
363 }
364 
366 {
367  return contentToJson(static_cast<const ObjVar*>(var));
368 }
369 
371 {
372  cJSON* root = genericNodeToJson(node);
373  JSON_WRITE_FIELD(root, node, fun);
374  JSON_WRITE_FIELD(root, node, bb);
375  // TODO: Ensure this?
376  assert(node->VFGNodes.empty() && "VFGNodes list not empty?");
377  JSON_WRITE_FIELD(root, node, pagEdges);
378  return root;
379 }
380 
382 {
383  return contentToJson(static_cast<const ICFGNode*>(node));
384 }
385 
387 {
388  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
389  JSON_WRITE_FIELD(root, node, isRet);
390  return root;
391 }
392 
394 {
395  return contentToJson(static_cast<const ICFGNode*>(node));
396 }
397 
399 {
400  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
401  JSON_WRITE_FIELD(root, node, FPNodes);
402  return root;
403 }
404 
406 {
407  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
408  JSON_WRITE_FIELD(root, node, formalRet);
409  return root;
410 }
411 
413 {
414  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
415  JSON_WRITE_FIELD(root, node, ret);
416  JSON_WRITE_FIELD(root, node, APNodes);
417  return root;
418 }
419 
421 {
422  cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
423  JSON_WRITE_FIELD(root, node, actualRet);
424  JSON_WRITE_FIELD(root, node, callBlockNode);
425  return root;
426 }
427 
429 {
430  return genericEdgeToJson(edge);
431 }
432 
434 {
435  cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
436  JSON_WRITE_FIELD(root, edge, conditionVar);
437  JSON_WRITE_FIELD(root, edge, branchCondVal);
438  return root;
439 }
440 
442 {
443  cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
444  JSON_WRITE_FIELD(root, edge, callPEs);
445  return root;
446 }
447 
449 {
450  cJSON* root = contentToJson(static_cast<const ICFGEdge*>(edge));
451  JSON_WRITE_FIELD(root, edge, retPE);
452  return root;
453 }
454 
456 {
457  cJSON* root = genericNodeToJson(node);
458  JSON_WRITE_FIELD(root, node, vtable);
459  JSON_WRITE_FIELD(root, node, className);
460  JSON_WRITE_FIELD(root, node, flags);
461  JSON_WRITE_FIELD(root, node, virtualFunctionVectors);
462  return root;
463 }
464 
466 {
467  cJSON* root = genericEdgeToJson(edge);
468  JSON_WRITE_FIELD(root, edge, edgeType);
469  return root;
470 }
471 
473 {
474  cJSON* root = jsonCreateObject();
475  JSON_WRITE_FIELD(root, type, kind);
476  JSON_WRITE_FIELD(root, type, isSingleValTy);
477  JSON_WRITE_FIELD(root, type, typeinfo);
478  return root;
479 }
480 
482 {
483  cJSON* root = contentToJson(static_cast<const SVFType*>(type));
484  return root;
485 }
486 
488 {
489  cJSON* root = contentToJson(static_cast<const SVFType*>(type));
490  JSON_WRITE_FIELD(root, type, signAndWidth);
491  return root;
492 }
493 
495 {
496  cJSON* root = contentToJson(static_cast<const SVFType*>(type));
497  JSON_WRITE_FIELD(root, type, retTy);
498  return root;
499 }
500 
502 {
503  cJSON* root = contentToJson(static_cast<const SVFType*>(type));
504  JSON_WRITE_FIELD(root, type, name);
505  return root;
506 }
507 
509 {
510  cJSON* root = contentToJson(static_cast<const SVFType*>(type));
511  JSON_WRITE_FIELD(root, type, numOfElement);
512  JSON_WRITE_FIELD(root, type, typeOfElement);
513  return root;
514 }
515 
517 {
518  cJSON* root = contentToJson(static_cast<const SVFType*>(type));
519  JSON_WRITE_FIELD(root, type, repr);
520  return root;
521 }
522 
524 {
525  cJSON* root = jsonCreateObject();
526  JSON_WRITE_FIELD(root, value, kind);
527  JSON_WRITE_FIELD(root, value, type);
528  JSON_WRITE_FIELD(root, value, name);
529  JSON_WRITE_FIELD(root, value, ptrInUncalledFun);
530  JSON_WRITE_FIELD(root, value, constDataOrAggData);
531  JSON_WRITE_FIELD(root, value, sourceLoc);
532  return root;
533 }
534 
536 {
537  cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
538 #define F(f) JSON_WRITE_FIELD(root, value, f);
539  F(isDecl);
540  F(intrinsic);
541  F(addrTaken);
542  F(isUncalled);
543  F(isNotRet);
544  F(varArg);
545  F(funcType);
546  F(loopAndDom);
547  F(realDefFun);
548  F(allBBs);
549  F(allArgs);
550 #undef F
551  return root;
552 }
553 
555 {
556  cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
557  JSON_WRITE_FIELD(root, value, succBBs);
558  JSON_WRITE_FIELD(root, value, predBBs);
559  JSON_WRITE_FIELD(root, value, fun);
560  return root;
561 }
562 
564 {
565  cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
566  JSON_WRITE_FIELD(root, value, bb);
567  JSON_WRITE_FIELD(root, value, terminator);
568  JSON_WRITE_FIELD(root, value, ret);
569  return root;
570 }
571 
573 {
574  cJSON* root = contentToJson(static_cast<const SVFInstruction*>(value));
575  JSON_WRITE_FIELD(root, value, args);
576  JSON_WRITE_FIELD(root, value, varArg);
577  JSON_WRITE_FIELD(root, value, calledVal);
578  return root;
579 }
580 
582 {
583  cJSON* root = contentToJson(static_cast<const SVFCallInst*>(value));
584  JSON_WRITE_FIELD(root, value, vCallVtblPtr);
585  JSON_WRITE_FIELD(root, value, virtualFunIdx);
586  JSON_WRITE_FIELD(root, value, funNameOfVcall);
587  return root;
588 }
589 
591 {
592  return contentToJson(static_cast<const SVFValue*>(value));
593 }
594 
596 {
597  cJSON* root = contentToJson(static_cast<const SVFConstant*>(value));
598  JSON_WRITE_FIELD(root, value, realDefGlobal);
599  return root;
600 }
601 
603 {
604  cJSON* root = contentToJson(static_cast<const SVFValue*>(value));
605  JSON_WRITE_FIELD(root, value, fun);
606  JSON_WRITE_FIELD(root, value, argNo);
607  JSON_WRITE_FIELD(root, value, uncalled);
608  return root;
609 }
610 
612 {
613  return contentToJson(static_cast<const SVFConstant*>(value));
614 }
615 
617 {
618  cJSON* root = contentToJson(static_cast<const SVFConstantData*>(value));
619  JSON_WRITE_FIELD(root, value, zval);
620  JSON_WRITE_FIELD(root, value, sval);
621  return root;
622 }
623 
625 {
626  cJSON* root = contentToJson(static_cast<const SVFConstantData*>(value));
627  JSON_WRITE_FIELD(root, value, dval);
628  return root;
629 }
630 
632 {
633  return contentToJson(static_cast<const SVFConstantData*>(value));
634 }
635 
637 {
638  return contentToJson(static_cast<const SVFConstantData*>(value));
639 }
640 
642 {
643  return contentToJson(static_cast<const SVFValue*>(value));
644 }
645 
647 {
648  return contentToJson(static_cast<const SVFOtherValue*>(value));
649 }
650 
652 {
653  cJSON* root = genericEdgeToJson(edge);
654  JSON_WRITE_FIELD(root, edge, value);
655  JSON_WRITE_FIELD(root, edge, basicBlock);
656  JSON_WRITE_FIELD(root, edge, icfgNode);
657  JSON_WRITE_FIELD(root, edge, edgeId);
658  return root;
659 }
660 
662 {
663  cJSON* root = jsonCreateObject();
664 #define F(field) JSON_WRITE_FIELD(root, loop, field)
665  F(entryICFGEdges);
666  F(backICFGEdges);
667  F(inICFGEdges);
668  F(outICFGEdges);
669  F(icfgNodes);
670  F(loopBound);
671 #undef F
672  return root;
673 }
674 
676 {
677  return contentToJson(static_cast<const SVFStmt*>(edge));
678 }
679 
681 {
682  return contentToJson(static_cast<const AssignStmt*>(edge));
683 }
684 
686 {
687  cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
688  JSON_WRITE_FIELD(root, edge, copyKind);
689  return root;
690 }
691 
693 {
694  return contentToJson(static_cast<const AssignStmt*>(edge));
695 }
696 
698 {
699  return contentToJson(static_cast<const AssignStmt*>(edge));
700 }
701 
703 {
704  cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
705  JSON_WRITE_FIELD(root, edge, ap);
706  JSON_WRITE_FIELD(root, edge, variantField);
707  return root;
708 }
709 
711 {
712  cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
713  JSON_WRITE_FIELD(root, edge, call);
714  JSON_WRITE_FIELD(root, edge, entry);
715  return root;
716 }
717 
719 {
720  cJSON* root = contentToJson(static_cast<const AssignStmt*>(edge));
721  JSON_WRITE_FIELD(root, edge, call);
722  JSON_WRITE_FIELD(root, edge, exit);
723  return root;
724 }
725 
727 {
728  cJSON* root = contentToJson(static_cast<const SVFStmt*>(edge));
729  JSON_WRITE_FIELD(root, edge, opVars);
730  return root;
731 }
732 
734 {
735  cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
736  JSON_WRITE_FIELD(root, edge, opICFGNodes);
737  return root;
738 }
739 
741 {
742  cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
743  JSON_WRITE_FIELD(root, edge, condition);
744  return root;
745 }
746 
748 {
749  cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
750  JSON_WRITE_FIELD(root, edge, predicate);
751  return root;
752 }
753 
755 {
756  cJSON* root = contentToJson(static_cast<const MultiOpndStmt*>(edge));
757  JSON_WRITE_FIELD(root, edge, opcode);
758  return root;
759 }
760 
762 {
763  cJSON* root = contentToJson(static_cast<const SVFStmt*>(edge));
764  JSON_WRITE_FIELD(root, edge, opcode);
765  return root;
766 }
767 
769 {
770  cJSON* root = contentToJson(static_cast<const SVFStmt*>(edge));
771  JSON_WRITE_FIELD(root, edge, successors);
772  JSON_WRITE_FIELD(root, edge, cond);
773  JSON_WRITE_FIELD(root, edge, brInst);
774  return root;
775 }
776 
778 {
779  return contentToJson(static_cast<const CallPE*>(edge));
780 }
781 
783 {
784  return contentToJson(static_cast<const RetPE*>(edge));
785 }
786 
787 bool jsonAddNumberToObject(cJSON* obj, const char* name, double number)
788 {
789  cJSON* node = cJSON_CreateNumber(number);
790  return jsonAddItemToObject(obj, name, node);
791 }
792 
793 bool jsonAddStringToObject(cJSON* obj, const char* name, const char* str)
794 {
795  cJSON* node = cJSON_CreateStringReference(str);
796  return jsonAddItemToObject(obj, name, node);
797 }
798 
799 bool jsonAddStringToObject(cJSON* obj, const char* name, const std::string& s)
800 {
801  return jsonAddStringToObject(obj, name, s.c_str());
802 }
803 
804 bool jsonIsBool(const cJSON* item)
805 {
806  return humanReadableOption()
807  ? cJSON_IsBool(item)
808  : cJSON_IsNumber(item) &&
809  (item->valuedouble == 0 || item->valuedouble == 1);
810 }
811 
812 bool jsonIsBool(const cJSON* item, bool& flag)
813 {
814  if (humanReadableOption())
815  {
816  if (!cJSON_IsBool(item))
817  return false;
818  flag = cJSON_IsTrue(item);
819  return true;
820  }
821  else
822  {
823  if (!cJSON_IsNumber(item))
824  return false;
825  flag = item->valuedouble == 1;
826  return true;
827  }
828 }
829 
830 bool jsonIsNumber(const cJSON* item)
831 {
832  return cJSON_IsNumber(item);
833 }
834 
835 bool jsonIsString(const cJSON* item)
836 {
837  return cJSON_IsString(item);
838 }
839 
840 bool jsonIsNullId(const cJSON* item)
841 {
842  // TODO: optimize
843  return cJSON_IsNull(item);
844 }
845 
846 bool jsonIsArray(const cJSON* item)
847 {
848  return cJSON_IsArray(item);
849 }
850 
851 bool jsonIsMap(const cJSON* item)
852 {
853  return cJSON_IsArray(item);
854 }
855 
856 bool jsonIsObject(const cJSON* item)
857 {
858  return humanReadableOption() ? cJSON_IsObject(item) : cJSON_IsArray(item);
859 }
860 
861 bool jsonKeyEquals(const cJSON* item, const char* key)
862 {
863  return item && !(humanReadableOption() && std::strcmp(item->string, key));
864 }
865 
866 std::pair<const cJSON*,const cJSON*> jsonUnpackPair(const cJSON* item)
867 {
868  ABORT_IFNOT(jsonIsArray(item), "Expected array as pair");
869  cJSON* child1 = item->child;
870  ABORT_IFNOT(child1, "Missing first child of pair");
871  cJSON* child2 = child1->next;
872  ABORT_IFNOT(child2, "Missing first child of pair");
873  ABORT_IFNOT(!child2->next, "Pair has more than two children");
874  return {child1, child2};
875 }
876 
877 double jsonGetNumber(const cJSON* item)
878 {
879  ABORT_IFNOT(jsonIsNumber(item), "Expected number for " << JSON_KEY(item));
880  return item->valuedouble;
881 }
882 
884 {
885  // TODO: optimize
886  return cJSON_CreateNull();
887 }
888 
890 {
891  return humanReadableOption() ? cJSON_CreateObject() : cJSON_CreateArray();
892 }
893 
895 {
896  return cJSON_CreateArray();
897 }
898 
900 {
901  // Don't use cJSON_CreateObject() here, because it only allows string keys.
902  return cJSON_CreateArray();
903 }
904 
905 cJSON* jsonCreateString(const char* str)
906 {
907  return cJSON_CreateStringReference(str);
908 }
909 
911 {
912  constexpr size_t maxPreciseIntInDouble = (1ull << 53);
913  (void)maxPreciseIntInDouble; // silence unused warning
914  assert(index <= maxPreciseIntInDouble);
915  return cJSON_CreateNumber(index);
916 }
917 
919 {
920  bool hr = humanReadableOption();
921  return hr ? cJSON_CreateBool(flag) : cJSON_CreateNumber(flag);
922 }
923 
925 {
926  return cJSON_CreateNumber(num);
927 }
928 
929 bool jsonAddPairToMap(cJSON* mapObj, cJSON* key, cJSON* value)
930 {
931  cJSON* pair = cJSON_CreateArray();
932  jsonAddItemToArray(pair, key);
933  jsonAddItemToArray(pair, value);
934  jsonAddItemToArray(mapObj, pair);
935  return pair;
936 }
937 
938 bool jsonAddItemToObject(cJSON* obj, const char* name, cJSON* item)
939 {
940  return humanReadableOption() ? cJSON_AddItemToObject(obj, name, item)
941  : cJSON_AddItemToArray(obj, item);
942 }
943 
945 {
946  return cJSON_AddItemToArray(array, item);
947 }
948 
950 {
951  for (const auto& pair : icfg->getIcfgNodeToSVFLoopVec())
952  {
953  for (const SVFLoop* loop : pair.second)
954  {
955  svfLoopPool.saveID(loop);
956  }
957  }
958 }
959 
961 {
962  // TODO: SVFType & StInfo are managed by SymbolTableInfo. Refactor it?
963  auto symTab = SymbolTableInfo::SymbolInfo();
964 
965  const auto& svfTypes = symTab->getSVFTypes();
966  svfTypePool.reserve(svfTypes.size());
967  for (const SVFType* type : svfTypes)
968  {
969  svfTypePool.saveID(type);
970  }
971 
972  const auto& stInfos = symTab->getStInfos();
973  stInfoPool.reserve(stInfos.size());
974  for (const StInfo* stInfo : stInfos)
975  {
976  stInfoPool.saveID(stInfo);
977  }
978 
979  svfValuePool.reserve(svfModule->getFunctionSet().size() +
980  svfModule->getConstantSet().size() +
981  svfModule->getOtherValueSet().size());
982 }
983 
985  : svfIR(svfir), svfModuleWriter(svfir->svfModule), icfgWriter(svfir->icfg),
986  chgWriter(SVFUtil::dyn_cast<CHGraph>(svfir->chgraph)),
987  irGraphWriter(svfir)
988 {
989 }
990 
991 void SVFIRWriter::writeJsonToOstream(const SVFIR* svfir, std::ostream& os)
992 {
993  SVFIRWriter writer(svfir);
994  os << writer.generateJsonString().get() << '\n';
995 }
996 
997 void SVFIRWriter::writeJsonToPath(const SVFIR* svfir, const std::string& path)
998 {
999  std::ofstream jsonFile(path);
1000  if (jsonFile.is_open())
1001  {
1002  writeJsonToOstream(svfir, jsonFile);
1003  jsonFile.close();
1004  }
1005  else
1006  {
1007  SVFUtil::errs() << "Failed to open file '" << path
1008  << "' to write SVFIR's JSON\n";
1009  }
1010 }
1011 
1012 const char* SVFIRWriter::numToStr(size_t n)
1013 {
1014  auto it = numToStrMap.find(n);
1015  if (it != numToStrMap.end() && !(numToStrMap.key_comp()(n, it->first)))
1016  {
1017  return it->second.c_str();
1018  }
1019  return numToStrMap.emplace_hint(it, n, std::to_string(n))->second.c_str();
1020 }
1021 
1023 {
1024  autoJSON object = generateJson();
1025  char* str = humanReadableOption() ? cJSON_Print(object.get())
1026  : cJSON_PrintUnformatted(object.get());
1027  return {str, cJSON_free};
1028 }
1029 
1031 {
1032  const IRGraph* const irGraph = svfIR;
1033  NodeIDAllocator* nodeIDAllocator = NodeIDAllocator::allocator;
1034  assert(nodeIDAllocator && "NodeIDAllocator is not initialized?");
1035 
1036  cJSON* root = jsonCreateObject();
1037 #define F(field) JSON_WRITE_FIELD(root, svfIR, field)
1038  F(svfModule);
1039  F(symInfo);
1040  F(icfg);
1041  F(chgraph);
1042  jsonAddJsonableToObject(root, FIELD_NAME_ITEM(irGraph));
1043  F(icfgNode2SVFStmtsMap);
1044  F(icfgNode2PTASVFStmtsMap);
1045  F(GepValObjMap);
1046  F(typeLocSetsMap);
1047  F(GepObjVarMap);
1048  F(memToFieldsMap);
1049  F(globSVFStmtSet);
1050  F(phiNodeMap);
1051  F(funArgsListMap);
1052  F(callSiteArgsListMap);
1053  F(callSiteRetMap);
1054  F(funRetMap);
1055  F(indCallSiteToFunPtrMap);
1056  F(funPtrToCallSitesMap);
1057  F(candidatePointers);
1058  F(callSiteSet);
1059  jsonAddJsonableToObject(root, FIELD_NAME_ITEM(nodeIDAllocator));
1060 #undef F
1061 
1062  return {root, cJSON_Delete};
1063 }
1064 
1066 {
1068 }
1069 
1071 {
1073 }
1074 
1076 {
1077  ENSURE_NOT_VISITED(graph);
1078 
1080 #define F(field) JSON_WRITE_FIELD(root, graph, field)
1081  F(KindToSVFStmtSetMap);
1082  F(KindToPTASVFStmtSetMap);
1083  F(fromFile);
1084  F(nodeNumAfterPAGBuild);
1085  F(totalPTAPAGEdge);
1086  F(valueToEdgeMap);
1087 #undef F
1088  return root;
1089 }
1090 
1092 {
1093  return var ? jsonCreateIndex(var->getId()) : jsonCreateNullId();
1094 }
1095 
1097 {
1098  return jsonCreateIndex(irGraphWriter.getEdgeID(stmt));
1099 }
1100 
1102 {
1103  cJSON* allSvfLoop = jsonCreateArray(); // all indices seen in constructor
1104  for (const SVFLoop* svfLoop : icfgWriter.svfLoopPool)
1105  {
1106  cJSON* svfLoopObj = contentToJson(svfLoop);
1107  jsonAddItemToArray(allSvfLoop, svfLoopObj);
1108  }
1109 
1110 #define F(field) JSON_WRITE_FIELD(root, icfg, field)
1112  jsonAddItemToObject(root, FIELD_NAME_ITEM(allSvfLoop)); // Meta field
1113  F(totalICFGNode);
1114  F(FunToFunEntryNodeMap);
1115  F(FunToFunExitNodeMap);
1116  F(globalBlockNode);
1117  F(icfgNodeToSVFLoopVec);
1118 #undef F
1119  return root;
1120 }
1121 
1123 {
1124  assert(node && "ICFGNode is null!");
1125  return jsonCreateIndex(node->getId());
1126 }
1127 
1129 {
1130  assert(edge && "ICFGNode is null!");
1131  return jsonCreateIndex(icfgWriter.getEdgeID(edge));
1132 }
1133 
1135 {
1136  auto chg = SVFUtil::dyn_cast<CHGraph>(graph);
1137  assert(chg && "Unsupported CHGraph type!");
1138  return toJson(chg);
1139 }
1140 
1142 {
1144 #define F(field) JSON_WRITE_FIELD(root, graph, field)
1145  // TODO: Ensure svfMod is the same as the SVFIR's?
1146  F(classNum);
1147  F(vfID);
1148  // F(buildingCHGTime); No need
1149  F(classNameToNodeMap);
1150  F(classNameToDescendantsMap);
1151  F(classNameToAncestorsMap);
1152  F(classNameToInstAndDescsMap);
1153  F(templateNameToInstancesMap);
1154  F(callNodeToClassesMap);
1155  F(virtualFunctionToIDMap);
1156  F(callNodeToCHAVtblsMap);
1157  F(callNodeToCHAVFnsMap);
1158 #undef F
1159  return root;
1160 }
1161 
1163 {
1164  return jsonCreateIndex(node->getId());
1165 }
1166 
1168 {
1169  return jsonCreateIndex(chgWriter.getEdgeID(edge));
1170 }
1171 
1173 {
1174  return jsonCreateIndex(icfgWriter.getSvfLoopID(loop));
1175 }
1176 
1178 {
1179  cJSON* root = jsonCreateObject();
1180  JSON_WRITE_FIELD(root, memObj, symId);
1181  JSON_WRITE_FIELD(root, memObj, typeInfo);
1182  JSON_WRITE_FIELD(root, memObj, refVal);
1183  return root;
1184 }
1185 
1187 {
1188  cJSON* root = jsonCreateObject();
1189 #define F(field) JSON_WRITE_FIELD(root, stInfo, field)
1190  F(stride);
1191  F(numOfFlattenElements);
1192  F(numOfFlattenFields);
1193  F(fldIdxVec);
1194  F(elemIdxVec);
1195  F(fldIdx2TypeMap);
1196  F(finfo);
1197  F(flattenElementTypes);
1198 #undef F
1199  return root;
1200 }
1201 
1203 {
1204  ENSURE_NOT_VISITED(objTypeInfo);
1205 
1206  cJSON* root = jsonCreateObject();
1207  JSON_WRITE_FIELD(root, objTypeInfo, type);
1208  JSON_WRITE_FIELD(root, objTypeInfo, flags);
1209  JSON_WRITE_FIELD(root, objTypeInfo, maxOffsetLimit);
1210  JSON_WRITE_FIELD(root, objTypeInfo, elemNum);
1211  return root;
1212 }
1213 
1215 {
1216  return jsonCreateIndex(memObj->getId());
1217 }
1218 
1220 {
1221  ENSURE_NOT_VISITED(ldInfo);
1222 
1223  cJSON* root = jsonCreateObject();
1224  JSON_WRITE_FIELD(root, ldInfo, reachableBBs);
1225  JSON_WRITE_FIELD(root, ldInfo, dtBBsMap);
1226  JSON_WRITE_FIELD(root, ldInfo, pdtBBsMap);
1227  JSON_WRITE_FIELD(root, ldInfo, dfBBsMap);
1228  JSON_WRITE_FIELD(root, ldInfo, bb2LoopMap);
1229  JSON_WRITE_FIELD(root, ldInfo, bb2PdomLevel);
1230  JSON_WRITE_FIELD(root, ldInfo, bb2PIdom);
1231  return root;
1232 }
1233 
1235 {
1237 }
1238 
1240 {
1241  cJSON* root = jsonCreateObject();
1242  JSON_WRITE_FIELD(root, &ap, fldIdx);
1243  JSON_WRITE_FIELD(root, &ap, idxOperandPairs);
1244  return root;
1245 }
1246 
1248 {
1249  ENSURE_NOT_VISITED(nodeIDAllocator);
1250 
1251  cJSON* root = jsonCreateObject();
1252  JSON_WRITE_FIELD(root, nodeIDAllocator, strategy);
1253  JSON_WRITE_FIELD(root, nodeIDAllocator, numObjects);
1254  JSON_WRITE_FIELD(root, nodeIDAllocator, numValues);
1255  JSON_WRITE_FIELD(root, nodeIDAllocator, numSymbols);
1256  JSON_WRITE_FIELD(root, nodeIDAllocator, numNodes);
1257  return root;
1258 }
1259 
1261 {
1262  ENSURE_NOT_VISITED(symTable);
1263 
1264  cJSON* root = jsonCreateObject();
1265  cJSON* allMemObj = jsonCreateArray();
1266  for (const auto& pair : symTable->objMap)
1267  {
1268  const MemObj* memObj = pair.second;
1269  cJSON* memObjJson = contentToJson(memObj);
1270  jsonAddItemToArray(allMemObj, memObjJson);
1271  }
1272 
1273 #define F(field) JSON_WRITE_FIELD(root, symTable, field)
1274  jsonAddItemToObject(root, FIELD_NAME_ITEM(allMemObj)); // Actual field
1275 
1276  F(valSymMap);
1277  F(objSymMap);
1278  F(returnSymMap);
1279  F(varargSymMap);
1280  // Field objMap can be represented by allMemObj
1281  // Field mod can be represented by svfIR->svfModule. Delete it?
1282  assert(symTable->mod == svfIR->svfModule && "SVFModule mismatch!");
1283  F(modelConstants);
1284  F(totalSymNum);
1285  F(maxStruct);
1286  F(maxStSize);
1287  // Field svfTypes can be represented by svfModuleWriter.svfTypePool
1288  // Field stInfos can be represented by svfModuleWriter.stInfoPool
1289 #undef F
1290 
1291  return root;
1292 }
1293 
1295 {
1296  cJSON* root = jsonCreateObject();
1297  cJSON* allSVFType = jsonCreateArray();
1298  cJSON* allStInfo = jsonCreateArray();
1299  cJSON* allSVFValue = jsonCreateArray();
1300 
1301  for (const SVFType* svfType : svfModuleWriter.svfTypePool)
1302  {
1303  cJSON* svfTypeObj = virtToJson(svfType);
1304  jsonAddItemToArray(allSVFType, svfTypeObj);
1305  }
1306 
1307  for (const StInfo* stInfo : svfModuleWriter.stInfoPool)
1308  {
1309  cJSON* stInfoObj = contentToJson(stInfo);
1310  jsonAddItemToArray(allStInfo, stInfoObj);
1311  }
1312 
1313 #define F(field) JSON_WRITE_FIELD(root, module, field)
1314  jsonAddItemToObject(root, FIELD_NAME_ITEM(allSVFType)); // Meta field
1315  jsonAddItemToObject(root, FIELD_NAME_ITEM(allStInfo)); // Meta field
1316  jsonAddItemToObject(root, FIELD_NAME_ITEM(allSVFValue)); // Meta field
1317  F(pagReadFromTxt);
1318  F(moduleIdentifier);
1319 
1320  F(FunctionSet);
1321  F(GlobalSet);
1322  F(AliasSet);
1323  F(ConstantSet);
1324  F(OtherValueSet);
1325 #undef F
1326 
1327  for (size_t i = 1; i <= svfModuleWriter.sizeSVFValuePool(); ++i)
1328  {
1330  jsonAddItemToArray(allSVFValue, value);
1331  }
1332 
1333  return root;
1334 }
1335 
1337 {
1338  const cJSON* svfirField = createObjs(root);
1339 
1340  SVFIR* svfIR = SVFIR::getPAG(); // SVFIR constructor sets symInfo
1341  IRGraph* irGraph = svfIR;
1342 
1343  auto svfModule = SVFModule::getSVFModule();
1344  auto icfg = new ICFG();
1345  auto chgraph = new CHGraph(svfModule);
1346  auto symInfo = SymbolTableInfo::SymbolInfo();
1347  symInfo->mod = svfModule;
1348 
1349  svfIR->svfModule = svfModule;
1350  svfIR->icfg = icfg;
1351  svfIR->chgraph = chgraph;
1352 
1353 #define F(field) JSON_READ_FIELD_FWD(svfirField, svfIR, field)
1354  readJson(symInfo);
1355  readJson(irGraph);
1356  readJson(icfg);
1357  readJson(chgraph);
1358  readJson(svfModule);
1359 
1360  F(icfgNode2SVFStmtsMap);
1361  F(icfgNode2PTASVFStmtsMap);
1362  F(GepValObjMap);
1363  F(typeLocSetsMap);
1364  F(GepObjVarMap);
1365  F(memToFieldsMap);
1366  F(globSVFStmtSet);
1367  F(phiNodeMap);
1368  F(funArgsListMap);
1369  F(callSiteArgsListMap);
1370  F(callSiteRetMap);
1371  F(funRetMap);
1372  F(indCallSiteToFunPtrMap);
1373  F(funPtrToCallSitesMap);
1374  F(candidatePointers);
1375  F(callSiteSet);
1376 #undef F
1377  assert(!NodeIDAllocator::allocator && "NodeIDAllocator should be NULL");
1378  auto nodeIDAllocator = NodeIDAllocator::get();
1379  JSON_READ_OBJ_FWD(svfirField, nodeIDAllocator);
1380 
1381  return svfIR;
1382 }
1383 
1385 {
1386 #define READ_CREATE_NODE_FWD(GType) \
1387  [](const cJSON*& nodeJson) { \
1388  JSON_DEF_READ_FWD(nodeJson, NodeID, id); \
1389  JSON_DEF_READ_FWD(nodeJson, GNodeK, nodeKind); \
1390  return std::make_pair(id, create##GType##Node(id, nodeKind)); \
1391  }
1392 #define READ_CREATE_EDGE_FWD(GType) \
1393  [](const cJSON*& edgeJson) { \
1394  JSON_DEF_READ_FWD(edgeJson, GEdgeFlag, edgeFlag); \
1395  auto kind = applyEdgeMask(edgeFlag); \
1396  auto edge = create##GType##Edge(kind); \
1397  setEdgeFlag(edge, edgeFlag); \
1398  return edge; \
1399  }
1400 
1401  ABORT_IFNOT(jsonIsObject(root), "Root should be an object");
1402 
1403  const cJSON* const svfModule = root->child;
1404  CHECK_JSON_KEY(svfModule);
1406  svfModule,
1407  // SVFType Creator
1408  [](const cJSON*& svfTypeFldJson)
1409  {
1410  JSON_DEF_READ_FWD(svfTypeFldJson, SVFType::GNodeK, kind);
1411  JSON_DEF_READ_FWD(svfTypeFldJson, bool, isSingleValTy);
1412  return createSVFType(kind, isSingleValTy);
1413  },
1414  // SVFType Filler
1415  [this](const cJSON*& svfVarFldJson, SVFType* type)
1416  {
1417  virtFill(svfVarFldJson, type);
1418  },
1419  // SVFValue Creator
1420  [this](const cJSON*& svfValueFldJson)
1421  {
1422  JSON_DEF_READ_FWD(svfValueFldJson, SVFValue::GNodeK, kind);
1423  JSON_DEF_READ_FWD(svfValueFldJson, const SVFType*, type, {});
1424  JSON_DEF_READ_FWD(svfValueFldJson, std::string, name);
1425  return createSVFValue(kind, type, std::move(name));
1426  },
1427  // SVFValue Filler
1428  [this](const cJSON*& svfVarFldJson, SVFValue* value)
1429  {
1430  virtFill(svfVarFldJson, value);
1431  },
1432  // StInfo Creator (no filler needed)
1433  [this](const cJSON*& stInfoFldJson)
1434  {
1435  JSON_DEF_READ_FWD(stInfoFldJson, u32_t, stride);
1436  auto si = new StInfo(stride);
1437  fill(stInfoFldJson, si);
1438  ABORT_IFNOT(!stInfoFldJson, "StInfo has extra field");
1439  return si;
1440  });
1441 
1442  const cJSON* const symInfo = svfModule->next;
1443  CHECK_JSON_KEY(symInfo);
1445  symInfo,
1446  // MemObj Creator (no filler needed)
1447  [this](const cJSON*& memObjFldJson)
1448  {
1449  JSON_DEF_READ_FWD(memObjFldJson, SymID, symId);
1450  JSON_DEF_READ_FWD(memObjFldJson, ObjTypeInfo*, typeInfo, {});
1451  JSON_DEF_READ_FWD(memObjFldJson, const SVFValue*, refVal, {});
1452  return std::make_pair(symId, new MemObj(symId, typeInfo, refVal));
1453  });
1454 
1455  const cJSON* const icfg = symInfo->next;
1456  CHECK_JSON_KEY(icfg);
1459  [](auto)
1460  {
1461  return new SVFLoop({}, 0);
1462  });
1463 
1464  const cJSON* const chgraph = icfg->next;
1465  CHECK_JSON_KEY(chgraph);
1467  READ_CREATE_EDGE_FWD(CH));
1468 
1469  const cJSON* const irGraph = chgraph->next;
1470  CHECK_JSON_KEY(irGraph);
1473 
1475  [this](const cJSON*& j, ICFGNode* node)
1476  {
1477  virtFill(j, node);
1478  },
1479  [this](const cJSON*& j, ICFGEdge* edge)
1480  {
1481  virtFill(j, edge);
1482  },
1483  [this](const cJSON*& j, SVFLoop* loop)
1484  {
1485  fill(j, loop);
1486  });
1488  [this](const cJSON*& j, CHNode* node)
1489  {
1490  virtFill(j, node);
1491  },
1492  [this](const cJSON*& j, CHEdge* edge)
1493  {
1494  virtFill(j, edge);
1495  });
1497  [this](const cJSON*& j, SVFVar* var)
1498  {
1499  virtFill(j, var);
1500  },
1501  [this](const cJSON*& j, SVFStmt* stmt)
1502  {
1503  virtFill(j, stmt);
1504  });
1505 
1506  return irGraph->next;
1507 
1508 #undef READ_CREATE_EDGE_FWD
1509 #undef READ_CREATE_NODE_FWD
1510 }
1511 
1512 void SVFIRReader::readJson(const cJSON* obj, bool& flag)
1513 {
1514  ABORT_IFNOT(jsonIsBool(obj, flag), "Expect bool for " << obj->string);
1515 }
1516 
1517 void SVFIRReader::readJson(const cJSON* obj, unsigned& val)
1518 {
1519  readSmallNumber(obj, val);
1520 }
1521 
1522 void SVFIRReader::readJson(const cJSON* obj, int& val)
1523 {
1524  readSmallNumber(obj, val);
1525 }
1526 
1527 void SVFIRReader::readJson(const cJSON* obj, short& val)
1528 {
1529  readSmallNumber(obj, val);
1530 }
1531 
1532 void SVFIRReader::readJson(const cJSON* obj, float& val)
1533 {
1534  readSmallNumber(obj, val);
1535 }
1536 
1537 void SVFIRReader::readJson(const cJSON* obj, unsigned long& val)
1538 {
1539  readBigNumber(obj, val,
1540  [](const char* s)
1541  {
1542  return std::strtoul(s, nullptr, 10);
1543  });
1544 }
1545 
1546 void SVFIRReader::readJson(const cJSON* obj, long long& val)
1547 {
1548  readBigNumber(obj, val,
1549  [](const char* s)
1550  {
1551  return std::strtoll(s, nullptr, 10);
1552  });
1553 }
1554 
1555 void SVFIRReader::readJson(const cJSON* obj, unsigned long long& val)
1556 {
1557  readBigNumber(obj, val,
1558  [](const char* s)
1559  {
1560  return std::strtoull(s, nullptr, 10);
1561  });
1562 }
1563 
1565 {
1566  ABORT_IFNOT(jsonIsString(obj), "Expect string for " << obj->string);
1567  str = obj->valuestring;
1568 }
1569 
1571 {
1572  switch (kind)
1573  {
1574  default:
1575  ABORT_MSG(kind << " is an impossible ICFGNodeKind in create()");
1576 #define CASE(kind, constructor) \
1577  case ICFGNode::kind: \
1578  return new constructor(id);
1579  CASE(IntraBlock, IntraICFGNode);
1580  CASE(FunEntryBlock, FunEntryICFGNode);
1581  CASE(FunExitBlock, FunExitICFGNode);
1582  CASE(FunCallBlock, CallICFGNode);
1583  CASE(FunRetBlock, RetICFGNode);
1584  CASE(GlobalBlock, GlobalICFGNode);
1585 #undef CASE
1586  }
1587 }
1588 
1590 {
1591  constexpr ICFGNode* src = nullptr;
1592  constexpr ICFGNode* dst = nullptr;
1593 
1594  switch (kind)
1595  {
1596  default:
1597  ABORT_MSG(kind << " is an impossible ICFGEdgeKind in create()");
1598  case ICFGEdge::IntraCF:
1599  return new IntraCFGEdge(src, dst);
1600  case ICFGEdge::CallCF:
1601  return new CallCFGEdge(src, dst);
1602  case ICFGEdge::RetCF:
1603  return new RetCFGEdge(src, dst);
1604  }
1605 }
1606 
1608 {
1609  ABORT_IFNOT(kind == 0, "Impossible CHNode kind " << kind);
1610  return new CHNode("", id);
1611 }
1612 
1614 {
1615  ABORT_IFNOT(kind == 0, "Unsupported CHEdge kind " << kind);
1616  return new CHEdge(nullptr, nullptr, {});
1617 }
1618 
1620 {
1621  switch (kind)
1622  {
1623  default:
1624  ABORT_MSG(kind << " is an impossible SVFVarKind in create()");
1625 #define CASE(kind, constructor) \
1626  case SVFVar::kind: \
1627  return new constructor(id);
1628  CASE(ValNode, ValVar);
1629  CASE(RetNode, RetPN);
1630  CASE(ObjNode, ObjVar);
1631  CASE(VarargNode, VarArgPN);
1632  CASE(GepValNode, GepValVar);
1633  CASE(GepObjNode, GepObjVar);
1634  CASE(FIObjNode, FIObjVar);
1635  CASE(DummyValNode, DummyValVar);
1636  CASE(DummyObjNode, DummyObjVar);
1637 #undef CASE
1638  }
1639 }
1640 
1642 {
1643  switch (kind)
1644  {
1645  default:
1646  ABORT_MSG(kind << " is an impossible SVFStmtKind in create()");
1647 #define CASE(kind, constructor) \
1648  case SVFStmt::kind: \
1649  return new constructor;
1650  CASE(Addr, AddrStmt);
1651  CASE(Copy, CopyStmt);
1652  CASE(Store, StoreStmt);
1653  CASE(Load, LoadStmt);
1654  CASE(Call, CallPE);
1655  CASE(Ret, RetPE);
1656  CASE(Gep, GepStmt);
1657  CASE(Phi, PhiStmt);
1658  CASE(Select, SelectStmt);
1659  CASE(Cmp, CmpStmt);
1660  CASE(BinaryOp, BinaryOPStmt);
1661  CASE(UnaryOp, UnaryOPStmt);
1662  CASE(Branch, BranchStmt);
1663  CASE(ThreadFork, TDForkPE);
1664  CASE(ThreadJoin, TDJoinPE);
1665 #undef CASE
1666  }
1667 }
1668 
1669 void SVFIRReader::readJson(const cJSON* obj, NodeIDAllocator* idAllocator)
1670 {
1671  assert(idAllocator && "idAllocator should be nonempty");
1672 
1673  ABORT_IFNOT(jsonIsObject(obj), "Expect object for " << JSON_KEY(obj));
1674  obj = obj->child;
1675 
1676  JSON_DEF_READ_FWD(obj, int, strategy);
1677  static_assert(sizeof(idAllocator->strategy) == sizeof(strategy),
1678  "idAllocator->strategy should be represented by int");
1679  idAllocator->strategy = static_cast<NodeIDAllocator::Strategy>(strategy);
1680  JSON_READ_FIELD_FWD(obj, idAllocator, numObjects);
1681  JSON_READ_FIELD_FWD(obj, idAllocator, numValues);
1682  JSON_READ_FIELD_FWD(obj, idAllocator, numSymbols);
1683  JSON_READ_FIELD_FWD(obj, idAllocator, numNodes);
1684 
1685  ABORT_IFNOT(!obj, "Extra field " << JSON_KEY(obj) << " in NodeIDAllocator");
1686 }
1687 
1689 {
1690  const cJSON* obj = symTableReader.getFieldJson();
1691 #define F(field) JSON_READ_FIELD_FWD(obj, symTabInfo, field)
1692  // `allMemObj` was consumed during create & fill phase.
1693  F(valSymMap);
1694  F(objSymMap);
1695  F(returnSymMap);
1696  F(varargSymMap);
1697  symTableReader.memObjMap.saveToIDToObjMap(symTabInfo->objMap); // objMap
1698  F(modelConstants);
1699  F(totalSymNum);
1700  F(maxStruct);
1701  F(maxStSize);
1702 #undef F
1703  ABORT_IFNOT(!obj, "Extra field " << JSON_KEY(obj) << " in SymbolTableInfo");
1704 }
1705 
1707 {
1708  assert(SymbolTableInfo::symInfo && "SymbolTableInfo should be nonempty");
1709  assert(graph->symInfo == SymbolTableInfo::SymbolInfo() && "symInfo differ");
1710 
1711  auto& valToEdgeMap = graph->valueToEdgeMap;
1712  valToEdgeMap.clear();
1713 
1715  const cJSON* obj = irGraphReader.getFieldJson();
1716 #define F(field) JSON_READ_FIELD_FWD(obj, graph, field)
1717  // base and symInfo have already been read
1718  F(KindToSVFStmtSetMap);
1719  F(KindToPTASVFStmtSetMap);
1720  F(fromFile);
1721  F(nodeNumAfterPAGBuild);
1722  F(totalPTAPAGEdge);
1723  F(valueToEdgeMap);
1724 #undef F
1725 
1726  auto nullit = valToEdgeMap.find(nullptr);
1727  ABORT_IFNOT(nullit != valToEdgeMap.end(), "valueToEdgeMap should has key NULL");
1728  ABORT_IFNOT(nullit->second.empty(), "valueToEdgeMap[NULL] should be empty");
1729 }
1730 
1732 {
1734  const cJSON* obj = icfgReader.getFieldJson();
1735 #define F(field) JSON_READ_FIELD_FWD(obj, icfg, field)
1736  F(totalICFGNode);
1737  F(FunToFunEntryNodeMap);
1738  F(FunToFunExitNodeMap);
1739  F(globalBlockNode);
1740  F(icfgNodeToSVFLoopVec);
1741 #undef F
1742 }
1743 
1745 {
1747  const cJSON* obj = chGraphReader.getFieldJson();
1748 #define F(field) JSON_READ_FIELD_FWD(obj, graph, field)
1749  F(classNum);
1750  F(vfID);
1751  F(classNameToNodeMap);
1752  F(classNameToDescendantsMap);
1753  F(classNameToAncestorsMap);
1754  F(classNameToInstAndDescsMap);
1755  F(templateNameToInstancesMap);
1756  F(callNodeToClassesMap);
1757  F(virtualFunctionToIDMap);
1758  F(callNodeToCHAVtblsMap);
1759  F(callNodeToCHAVFnsMap);
1760 #undef F
1761 }
1762 
1764 {
1765  const cJSON* obj = svfModuleReader.getFieldJson();
1766  auto symInfo = SymbolTableInfo::symInfo;
1767  assert(symInfo && "SymbolTableInfo should be non-NULL");
1768  svfModuleReader.svfTypePool.saveToSet(symInfo->svfTypes);
1769  svfModuleReader.stInfoPool.saveToSet(symInfo->stInfos);
1770 
1771 #define F(field) JSON_READ_FIELD_FWD(obj, module, field)
1772  F(pagReadFromTxt);
1773  F(moduleIdentifier);
1774  F(FunctionSet);
1775  F(GlobalSet);
1776  F(AliasSet);
1777  F(ConstantSet);
1778  F(OtherValueSet);
1779 #undef F
1780 }
1781 
1783 {
1784  assert(!type && "SVFType already read?");
1786 }
1787 
1788 void SVFIRReader::readJson(const cJSON* obj, StInfo*& stInfo)
1789 {
1790  assert(!stInfo && "StInfo already read?");
1792 }
1793 
1794 void SVFIRReader::readJson(const cJSON* obj, SVFValue*& value)
1795 {
1796  assert(!value && "SVFValue already read?");
1798 }
1799 
1800 void SVFIRReader::readJson(const cJSON* obj, SVFVar*& var)
1801 {
1802  assert(!var && "SVFVar already read?");
1803  if (jsonIsNullId(obj))
1804  var = nullptr;
1805  else
1807 }
1808 
1809 void SVFIRReader::readJson(const cJSON* obj, SVFStmt*& stmt)
1810 {
1811  assert(!stmt && "SVFStmt already read?");
1812  stmt = irGraphReader.getEdgePtr(jsonGetNumber(obj));
1813 }
1814 
1815 void SVFIRReader::readJson(const cJSON* obj, ICFGNode*& node)
1816 {
1817  assert(!node && "ICFGNode already read?");
1818  NodeID id = jsonGetNumber(obj);
1819  node = icfgReader.getNodePtr(id);
1820 }
1821 
1822 void SVFIRReader::readJson(const cJSON* obj, ICFGEdge*& edge)
1823 {
1824  assert(!edge && "ICFGEdge already read?");
1825  edge = icfgReader.getEdgePtr(jsonGetNumber(obj));
1826 }
1827 
1828 void SVFIRReader::readJson(const cJSON* obj, CHNode*& node)
1829 {
1830  assert(!node && "CHNode already read?");
1831  node = chGraphReader.getNodePtr(jsonGetNumber(obj));
1832 }
1833 
1834 void SVFIRReader::readJson(const cJSON* obj, CHEdge*& edge)
1835 {
1836  assert(!edge && "CHEdge already read?");
1837  edge = chGraphReader.getEdgePtr(jsonGetNumber(obj));
1838 }
1839 
1841 {
1842  ABORT_IFNOT(jsonIsObject(obj), "Expected obj for AccessPath");
1843  obj = obj->child;
1844  JSON_READ_FIELD_FWD(obj, &ap, fldIdx);
1845  JSON_READ_FIELD_FWD(obj, &ap, idxOperandPairs);
1846  ABORT_IFNOT(!obj, "Extra field " << JSON_KEY(obj) << " in AccessPath");
1847 }
1848 
1849 void SVFIRReader::readJson(const cJSON* obj, SVFLoop*& loop)
1850 {
1851  assert(!loop && "SVFLoop already read?");
1852  unsigned id = jsonGetNumber(obj);
1853  loop = icfgReader.getSVFLoopPtr(id);
1854 }
1855 
1856 void SVFIRReader::readJson(const cJSON* obj, MemObj*& memObj)
1857 {
1858  assert(!memObj && "MemObj already read?");
1859  memObj = symTableReader.getMemObjPtr(jsonGetNumber(obj));
1860 }
1861 
1862 void SVFIRReader::readJson(const cJSON* obj, ObjTypeInfo*& objTypeInfo)
1863 {
1864  assert(!objTypeInfo && "ObjTypeInfo already read?");
1865  ABORT_IFNOT(jsonIsObject(obj), "Expected object for objTypeInfo");
1866  cJSON* field = obj->child;
1867 
1868  JSON_DEF_READ_FWD(field, SVFType*, type, {});
1869  JSON_DEF_READ_FWD(field, u32_t, flags);
1870  JSON_DEF_READ_FWD(field, u32_t, maxOffsetLimit);
1871  JSON_DEF_READ_FWD(field, u32_t, elemNum);
1872 
1873  ABORT_IFNOT(!field, "Extra field in objTypeInfo: " << JSON_KEY(field));
1874  objTypeInfo = new ObjTypeInfo(type, maxOffsetLimit);
1875  objTypeInfo->flags = flags;
1876  objTypeInfo->elemNum = elemNum;
1877 }
1878 
1880 {
1881  assert(!ldInfo && "SVFLoopAndDomInfo already read?");
1882  ABORT_IFNOT(jsonIsObject(obj), "Expected object for SVFLoopAndDomInfo");
1883  cJSON* field = obj->child;
1884 
1885  ldInfo = new SVFLoopAndDomInfo();
1886 
1887  JSON_READ_FIELD_FWD(field, ldInfo, reachableBBs);
1888  JSON_READ_FIELD_FWD(field, ldInfo, dtBBsMap);
1889  JSON_READ_FIELD_FWD(field, ldInfo, pdtBBsMap);
1890  JSON_READ_FIELD_FWD(field, ldInfo, dfBBsMap);
1891  JSON_READ_FIELD_FWD(field, ldInfo, bb2LoopMap);
1892  JSON_READ_FIELD_FWD(field, ldInfo, bb2PdomLevel);
1893  JSON_READ_FIELD_FWD(field, ldInfo, bb2PIdom);
1894 
1895  ABORT_IFNOT(!field,
1896  "Extra field in SVFLoopAndDomInfo: " << JSON_KEY(field));
1897 }
1898 
1899 void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFVar* var)
1900 {
1901  switch (var->getNodeKind())
1902  {
1903  default:
1904  assert(false && "Unknown SVFVar kind");
1905 
1906 #define CASE(VarKind, VarType) \
1907  case SVFVar::VarKind: \
1908  return fill(fieldJson, static_cast<VarType*>(var))
1909 
1910  CASE(ValNode, ValVar);
1911  CASE(ObjNode, ObjVar);
1912  CASE(RetNode, RetPN);
1913  CASE(VarargNode, VarArgPN);
1914  CASE(GepValNode, GepValVar);
1915  CASE(GepObjNode, GepObjVar);
1916  CASE(FIObjNode, FIObjVar);
1917  CASE(DummyValNode, DummyValVar);
1918  CASE(DummyObjNode, DummyObjVar);
1919 #undef CASE
1920  }
1921 }
1922 
1923 void SVFIRReader::fill(const cJSON*& fieldJson, SVFVar* var)
1924 {
1925  fill(fieldJson, static_cast<GenericPAGNodeTy*>(var));
1926  JSON_READ_FIELD_FWD(fieldJson, var, value);
1927  JSON_READ_FIELD_FWD(fieldJson, var, InEdgeKindToSetMap);
1928  JSON_READ_FIELD_FWD(fieldJson, var, OutEdgeKindToSetMap);
1929  JSON_READ_FIELD_FWD(fieldJson, var, isPtr);
1930 }
1931 
1932 void SVFIRReader::fill(const cJSON*& fieldJson, ValVar* var)
1933 {
1934  fill(fieldJson, static_cast<SVFVar*>(var));
1935 }
1936 
1937 void SVFIRReader::fill(const cJSON*& fieldJson, ObjVar* var)
1938 {
1939  fill(fieldJson, static_cast<SVFVar*>(var));
1940  JSON_READ_FIELD_FWD(fieldJson, var, mem);
1941 }
1942 
1943 void SVFIRReader::fill(const cJSON*& fieldJson, GepValVar* var)
1944 {
1945  fill(fieldJson, static_cast<ValVar*>(var));
1946  JSON_READ_FIELD_FWD(fieldJson, var, ap);
1947  JSON_READ_FIELD_FWD(fieldJson, var, gepValType);
1948 }
1949 
1950 void SVFIRReader::fill(const cJSON*& fieldJson, GepObjVar* var)
1951 {
1952  fill(fieldJson, static_cast<ObjVar*>(var));
1953  JSON_READ_FIELD_FWD(fieldJson, var, apOffset);
1954  JSON_READ_FIELD_FWD(fieldJson, var, base);
1955 }
1956 
1957 void SVFIRReader::fill(const cJSON*& fieldJson, FIObjVar* var)
1958 {
1959  fill(fieldJson, static_cast<ObjVar*>(var));
1960 }
1961 
1962 void SVFIRReader::fill(const cJSON*& fieldJson, RetPN* var)
1963 {
1964  fill(fieldJson, static_cast<ValVar*>(var));
1965 }
1966 
1967 void SVFIRReader::fill(const cJSON*& fieldJson, VarArgPN* var)
1968 {
1969  fill(fieldJson, static_cast<ValVar*>(var));
1970 }
1971 
1972 void SVFIRReader::fill(const cJSON*& fieldJson, DummyValVar* var)
1973 {
1974  fill(fieldJson, static_cast<ValVar*>(var));
1975 }
1976 
1977 void SVFIRReader::fill(const cJSON*& fieldJson, DummyObjVar* var)
1978 {
1979  fill(fieldJson, static_cast<ObjVar*>(var));
1980 }
1981 
1982 void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFStmt* stmt)
1983 {
1984  auto kind = stmt->getEdgeKind();
1985 
1986  switch (kind)
1987  {
1988  default:
1989  ABORT_MSG("Unknown SVFStmt kind " << kind);
1990 
1991 #define CASE(EdgeKind, EdgeType) \
1992  case SVFStmt::EdgeKind: \
1993  return fill(fieldJson, static_cast<EdgeType*>(stmt))
1994 
1995  CASE(Addr, AddrStmt);
1996  CASE(Copy, CopyStmt);
1997  CASE(Store, StoreStmt);
1998  CASE(Load, LoadStmt);
1999  CASE(Call, CallPE);
2000  CASE(Ret, RetPE);
2001  CASE(Gep, GepStmt);
2002  CASE(Phi, PhiStmt);
2003  CASE(Select, SelectStmt);
2004  CASE(Cmp, CmpStmt);
2005  CASE(BinaryOp, BinaryOPStmt);
2006  CASE(UnaryOp, UnaryOPStmt);
2007  CASE(Branch, BranchStmt);
2008  CASE(ThreadFork, TDForkPE);
2009  CASE(ThreadJoin, TDJoinPE);
2010 #undef CASE
2011  }
2012 }
2013 
2014 void SVFIRReader::fill(const cJSON*& fieldJson, SVFStmt* stmt)
2015 {
2016  fill(fieldJson, static_cast<GenericPAGEdgeTy*>(stmt));
2017  JSON_READ_FIELD_FWD(fieldJson, stmt, value);
2018  JSON_READ_FIELD_FWD(fieldJson, stmt, basicBlock);
2019  JSON_READ_FIELD_FWD(fieldJson, stmt, icfgNode);
2020  JSON_READ_FIELD_FWD(fieldJson, stmt, edgeId);
2021 }
2022 
2023 void SVFIRReader::fill(const cJSON*& fieldJson, AssignStmt* stmt)
2024 {
2025  fill(fieldJson, static_cast<SVFStmt*>(stmt));
2026 }
2027 
2028 void SVFIRReader::fill(const cJSON*& fieldJson, AddrStmt* stmt)
2029 {
2030  fill(fieldJson, static_cast<AssignStmt*>(stmt));
2031 }
2032 
2033 void SVFIRReader::fill(const cJSON*& fieldJson, CopyStmt* stmt)
2034 {
2035  fill(fieldJson, static_cast<AssignStmt*>(stmt));
2036  JSON_READ_FIELD_FWD(fieldJson, stmt, copyKind);
2037 }
2038 
2039 void SVFIRReader::fill(const cJSON*& fieldJson, StoreStmt* stmt)
2040 {
2041  fill(fieldJson, static_cast<AssignStmt*>(stmt));
2042 }
2043 
2044 void SVFIRReader::fill(const cJSON*& fieldJson, LoadStmt* stmt)
2045 {
2046  fill(fieldJson, static_cast<AssignStmt*>(stmt));
2047 }
2048 
2049 void SVFIRReader::fill(const cJSON*& fieldJson, GepStmt* stmt)
2050 {
2051  fill(fieldJson, static_cast<AssignStmt*>(stmt));
2052  JSON_READ_FIELD_FWD(fieldJson, stmt, ap);
2053  JSON_READ_FIELD_FWD(fieldJson, stmt, variantField);
2054 }
2055 
2056 void SVFIRReader::fill(const cJSON*& fieldJson, CallPE* stmt)
2057 {
2058  fill(fieldJson, static_cast<AssignStmt*>(stmt));
2059  JSON_READ_FIELD_FWD(fieldJson, stmt, call);
2060  JSON_READ_FIELD_FWD(fieldJson, stmt, entry);
2061 }
2062 
2063 void SVFIRReader::fill(const cJSON*& fieldJson, RetPE* stmt)
2064 {
2065  fill(fieldJson, static_cast<AssignStmt*>(stmt));
2066  JSON_READ_FIELD_FWD(fieldJson, stmt, call);
2067  JSON_READ_FIELD_FWD(fieldJson, stmt, exit);
2068 }
2069 
2070 void SVFIRReader::fill(const cJSON*& fieldJson, MultiOpndStmt* stmt)
2071 {
2072  fill(fieldJson, static_cast<SVFStmt*>(stmt));
2073  JSON_READ_FIELD_FWD(fieldJson, stmt, opVars);
2074 }
2075 
2076 void SVFIRReader::fill(const cJSON*& fieldJson, PhiStmt* stmt)
2077 {
2078  fill(fieldJson, static_cast<MultiOpndStmt*>(stmt));
2079  JSON_READ_FIELD_FWD(fieldJson, stmt, opICFGNodes);
2080 }
2081 
2082 void SVFIRReader::fill(const cJSON*& fieldJson, SelectStmt* stmt)
2083 {
2084  fill(fieldJson, static_cast<MultiOpndStmt*>(stmt));
2085  JSON_READ_FIELD_FWD(fieldJson, stmt, condition);
2086 }
2087 
2088 void SVFIRReader::fill(const cJSON*& fieldJson, CmpStmt* stmt)
2089 {
2090  fill(fieldJson, static_cast<MultiOpndStmt*>(stmt));
2091  JSON_READ_FIELD_FWD(fieldJson, stmt, predicate);
2092 }
2093 
2094 void SVFIRReader::fill(const cJSON*& fieldJson, BinaryOPStmt* stmt)
2095 {
2096  fill(fieldJson, static_cast<MultiOpndStmt*>(stmt));
2097  JSON_READ_FIELD_FWD(fieldJson, stmt, opcode);
2098 }
2099 
2100 void SVFIRReader::fill(const cJSON*& fieldJson, UnaryOPStmt* stmt)
2101 {
2102  fill(fieldJson, static_cast<SVFStmt*>(stmt));
2103  JSON_READ_FIELD_FWD(fieldJson, stmt, opcode);
2104 }
2105 
2106 void SVFIRReader::fill(const cJSON*& fieldJson, BranchStmt* stmt)
2107 {
2108  fill(fieldJson, static_cast<SVFStmt*>(stmt));
2109  JSON_READ_FIELD_FWD(fieldJson, stmt, successors);
2110  JSON_READ_FIELD_FWD(fieldJson, stmt, cond);
2111  JSON_READ_FIELD_FWD(fieldJson, stmt, brInst);
2112 }
2113 
2114 void SVFIRReader::fill(const cJSON*& fieldJson, TDForkPE* stmt)
2115 {
2116  fill(fieldJson, static_cast<CallPE*>(stmt));
2117 }
2118 
2119 void SVFIRReader::fill(const cJSON*& fieldJson, TDJoinPE* stmt)
2120 {
2121  fill(fieldJson, static_cast<RetPE*>(stmt));
2122 }
2123 
2124 void SVFIRReader::fill(const cJSON*& fieldJson, MemObj* memObj)
2125 {
2126  // symId has already been read
2127  JSON_READ_FIELD_FWD(fieldJson, memObj, typeInfo);
2128  JSON_READ_FIELD_FWD(fieldJson, memObj, refVal);
2129 }
2130 
2131 void SVFIRReader::fill(const cJSON*& fieldJson, StInfo* stInfo)
2132 {
2133 #define F(field) JSON_READ_FIELD_FWD(fieldJson, stInfo, field)
2134  // stride has already been read upon construction
2135  F(numOfFlattenElements);
2136  F(numOfFlattenFields);
2137  F(fldIdxVec);
2138  F(elemIdxVec);
2139  F(fldIdx2TypeMap);
2140  F(finfo);
2141  F(flattenElementTypes);
2142 #undef F
2143 }
2144 
2145 void SVFIRReader::virtFill(const cJSON*& fieldJson, ICFGNode* node)
2146 {
2147  switch (node->getNodeKind())
2148  {
2149  default:
2150  ABORT_MSG("Unknown ICFGNode kind " << node->getNodeKind());
2151 
2152 #define CASE(NodeKind, NodeType) \
2153  case ICFGNode::NodeKind: \
2154  return fill(fieldJson, static_cast<NodeType*>(node))
2155 
2156  CASE(IntraBlock, IntraICFGNode);
2157  CASE(FunEntryBlock, FunEntryICFGNode);
2158  CASE(FunExitBlock, FunExitICFGNode);
2159  CASE(FunCallBlock, CallICFGNode);
2160  CASE(FunRetBlock, RetICFGNode);
2161  CASE(GlobalBlock, GlobalICFGNode);
2162 #undef CASE
2163  }
2164 }
2165 
2166 void SVFIRReader::fill(const cJSON*& fieldJson, ICFGNode* node)
2167 {
2168  fill(fieldJson, static_cast<GenericICFGNodeTy*>(node));
2169  JSON_READ_FIELD_FWD(fieldJson, node, fun);
2170  JSON_READ_FIELD_FWD(fieldJson, node, bb);
2171  // Skip VFGNodes as it is empty
2172  JSON_READ_FIELD_FWD(fieldJson, node, pagEdges);
2173 }
2174 
2175 void SVFIRReader::fill(const cJSON*& fieldJson, GlobalICFGNode* node)
2176 {
2177  fill(fieldJson, static_cast<ICFGNode*>(node));
2178 }
2179 
2180 void SVFIRReader::fill(const cJSON*& fieldJson, IntraICFGNode* node)
2181 {
2182  fill(fieldJson, static_cast<ICFGNode*>(node));
2183  JSON_READ_FIELD_FWD(fieldJson, node, isRet);
2184 }
2185 
2186 void SVFIRReader::fill(const cJSON*& fieldJson, InterICFGNode* node)
2187 {
2188  fill(fieldJson, static_cast<ICFGNode*>(node));
2189 }
2190 
2191 void SVFIRReader::fill(const cJSON*& fieldJson, FunEntryICFGNode* node)
2192 {
2193  fill(fieldJson, static_cast<ICFGNode*>(node));
2194  JSON_READ_FIELD_FWD(fieldJson, node, FPNodes);
2195 }
2196 
2197 void SVFIRReader::fill(const cJSON*& fieldJson, FunExitICFGNode* node)
2198 {
2199  fill(fieldJson, static_cast<ICFGNode*>(node));
2200  JSON_READ_FIELD_FWD(fieldJson, node, formalRet);
2201 }
2202 
2203 void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
2204 {
2205  fill(fieldJson, static_cast<ICFGNode*>(node));
2206  JSON_READ_FIELD_FWD(fieldJson, node, ret);
2207  JSON_READ_FIELD_FWD(fieldJson, node, APNodes);
2208 }
2209 
2210 void SVFIRReader::fill(const cJSON*& fieldJson, RetICFGNode* node)
2211 {
2212  fill(fieldJson, static_cast<ICFGNode*>(node));
2213  JSON_READ_FIELD_FWD(fieldJson, node, actualRet);
2214  JSON_READ_FIELD_FWD(fieldJson, node, callBlockNode);
2215 }
2216 
2217 void SVFIRReader::virtFill(const cJSON*& fieldJson, ICFGEdge* edge)
2218 {
2219  auto kind = edge->getEdgeKind();
2220  switch (kind)
2221  {
2222  default:
2223  ABORT_MSG("Unknown ICFGEdge kind " << kind);
2224  case ICFGEdge::IntraCF:
2225  return fill(fieldJson, static_cast<IntraCFGEdge*>(edge));
2226  case ICFGEdge::CallCF:
2227  return fill(fieldJson, static_cast<CallCFGEdge*>(edge));
2228  case ICFGEdge::RetCF:
2229  return fill(fieldJson, static_cast<RetCFGEdge*>(edge));
2230  }
2231 }
2232 
2233 void SVFIRReader::fill(const cJSON*& fieldJson, ICFGEdge* edge)
2234 {
2235  fill(fieldJson, static_cast<GenericICFGEdgeTy*>(edge));
2236 }
2237 
2238 void SVFIRReader::fill(const cJSON*& fieldJson, IntraCFGEdge* edge)
2239 {
2240  fill(fieldJson, static_cast<ICFGEdge*>(edge));
2241  JSON_READ_FIELD_FWD(fieldJson, edge, conditionVar);
2242  JSON_READ_FIELD_FWD(fieldJson, edge, branchCondVal);
2243 }
2244 
2245 void SVFIRReader::fill(const cJSON*& fieldJson, CallCFGEdge* edge)
2246 {
2247  fill(fieldJson, static_cast<ICFGEdge*>(edge));
2248  JSON_READ_FIELD_FWD(fieldJson, edge, callPEs);
2249 }
2250 
2251 void SVFIRReader::fill(const cJSON*& fieldJson, RetCFGEdge* edge)
2252 {
2253  fill(fieldJson, static_cast<ICFGEdge*>(edge));
2254  JSON_READ_FIELD_FWD(fieldJson, edge, retPE);
2255 }
2256 
2257 void SVFIRReader::fill(const cJSON*& fieldJson, SVFLoop* loop)
2258 {
2259 #define F(field) JSON_READ_FIELD_FWD(fieldJson, loop, field)
2260  F(entryICFGEdges);
2261  F(backICFGEdges);
2262  F(inICFGEdges);
2263  F(outICFGEdges);
2264  F(icfgNodes);
2265  F(loopBound);
2266 #undef F
2267 }
2268 
2269 void SVFIRReader::virtFill(const cJSON*& fieldJson, CHNode* node)
2270 {
2271  assert(node->getNodeKind() == 0 && "Unknown CHNode kind");
2272  fill(fieldJson, static_cast<GenericCHNodeTy*>(node));
2273  JSON_READ_FIELD_FWD(fieldJson, node, vtable);
2274  JSON_READ_FIELD_FWD(fieldJson, node, className);
2275  JSON_READ_FIELD_FWD(fieldJson, node, flags);
2276  JSON_READ_FIELD_FWD(fieldJson, node, virtualFunctionVectors);
2277 }
2278 
2279 void SVFIRReader::virtFill(const cJSON*& fieldJson, CHEdge* edge)
2280 {
2281  assert(edge->getEdgeKind() == 0 && "Unknown CHEdge kind");
2282  fill(fieldJson, static_cast<GenericCHEdgeTy*>(edge));
2283  // edgeType is a enum
2284  JSON_DEF_READ_FWD(fieldJson, unsigned, edgeType);
2285  if (edgeType == CHEdge::INHERITANCE)
2286  edge->edgeType = CHEdge::INHERITANCE;
2287  else if (edgeType == CHEdge::INSTANTCE)
2288  edge->edgeType = CHEdge::INSTANTCE;
2289  else
2290  ABORT_MSG("Unknown CHEdge type " << edgeType);
2291 }
2292 
2293 void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFValue* value)
2294 {
2295  auto kind = value->getKind();
2296 
2297  switch (kind)
2298  {
2299  default:
2300  ABORT_MSG("Impossible SVFValue kind " << kind);
2301 
2302 #define CASE(ValueKind, Type) \
2303  case SVFValue::ValueKind: \
2304  return fill(fieldJson, static_cast<Type*>(value))
2305 
2306  CASE(SVFVal, SVFValue);
2307  CASE(SVFFunc, SVFFunction);
2308  CASE(SVFBB, SVFBasicBlock);
2309  CASE(SVFInst, SVFInstruction);
2310  CASE(SVFCall, SVFCallInst);
2311  CASE(SVFVCall, SVFVirtualCallInst);
2312  CASE(SVFGlob, SVFGlobalValue);
2313  CASE(SVFArg, SVFArgument);
2314  CASE(SVFConst, SVFConstant);
2315  CASE(SVFConstData, SVFConstantData);
2316  CASE(SVFConstInt, SVFConstantInt);
2317  CASE(SVFConstFP, SVFConstantFP);
2318  CASE(SVFNullPtr, SVFConstantNullPtr);
2319  CASE(SVFBlackHole, SVFBlackHoleValue);
2320  CASE(SVFMetaAsValue, SVFMetadataAsValue);
2321  CASE(SVFOther, SVFOtherValue);
2322 #undef CASE
2323  }
2324 }
2325 
2326 void SVFIRReader::fill(const cJSON*& fieldJson, SVFValue* value)
2327 {
2328  // kind, type, name have already been read.
2329  JSON_READ_FIELD_FWD(fieldJson, value, ptrInUncalledFun);
2330  JSON_READ_FIELD_FWD(fieldJson, value, constDataOrAggData);
2331  JSON_READ_FIELD_FWD(fieldJson, value, sourceLoc);
2332 }
2333 
2334 void SVFIRReader::fill(const cJSON*& fieldJson, SVFFunction* value)
2335 {
2336  fill(fieldJson, static_cast<SVFValue*>(value));
2337 #define F(f) JSON_READ_FIELD_FWD(fieldJson, value, f)
2338  F(isDecl);
2339  F(intrinsic);
2340  F(addrTaken);
2341  F(isUncalled);
2342  F(isNotRet);
2343  F(varArg);
2344  F(funcType);
2345  F(loopAndDom);
2346  F(realDefFun);
2347  F(allBBs);
2348  F(allArgs);
2349 #undef F
2350 }
2351 
2352 void SVFIRReader::fill(const cJSON*& fieldJson, SVFBasicBlock* value)
2353 {
2354  fill(fieldJson, static_cast<SVFValue*>(value));
2355  JSON_READ_FIELD_FWD(fieldJson, value, succBBs);
2356  JSON_READ_FIELD_FWD(fieldJson, value, predBBs);
2357  JSON_READ_FIELD_FWD(fieldJson, value, fun);
2358 }
2359 
2360 void SVFIRReader::fill(const cJSON*& fieldJson, SVFInstruction* value)
2361 {
2362  fill(fieldJson, static_cast<SVFValue*>(value));
2363  JSON_READ_FIELD_FWD(fieldJson, value, bb);
2364  JSON_READ_FIELD_FWD(fieldJson, value, terminator);
2365  JSON_READ_FIELD_FWD(fieldJson, value, ret);
2366 }
2367 
2368 void SVFIRReader::fill(const cJSON*& fieldJson, SVFCallInst* value)
2369 {
2370  fill(fieldJson, static_cast<SVFInstruction*>(value));
2371  JSON_READ_FIELD_FWD(fieldJson, value, args);
2372  JSON_READ_FIELD_FWD(fieldJson, value, varArg);
2373  JSON_READ_FIELD_FWD(fieldJson, value, calledVal);
2374 }
2375 
2376 void SVFIRReader::fill(const cJSON*& fieldJson, SVFVirtualCallInst* value)
2377 {
2378  fill(fieldJson, static_cast<SVFCallInst*>(value));
2379  JSON_READ_FIELD_FWD(fieldJson, value, vCallVtblPtr);
2380  JSON_READ_FIELD_FWD(fieldJson, value, virtualFunIdx);
2381  JSON_READ_FIELD_FWD(fieldJson, value, funNameOfVcall);
2382 }
2383 
2384 void SVFIRReader::fill(const cJSON*& fieldJson, SVFConstant* value)
2385 {
2386  fill(fieldJson, static_cast<SVFValue*>(value));
2387 }
2388 
2389 void SVFIRReader::fill(const cJSON*& fieldJson, SVFGlobalValue* value)
2390 {
2391  fill(fieldJson, static_cast<SVFConstant*>(value));
2392  JSON_READ_FIELD_FWD(fieldJson, value, realDefGlobal);
2393 }
2394 
2395 void SVFIRReader::fill(const cJSON*& fieldJson, SVFArgument* value)
2396 {
2397  fill(fieldJson, static_cast<SVFValue*>(value));
2398  JSON_READ_FIELD_FWD(fieldJson, value, fun);
2399  JSON_READ_FIELD_FWD(fieldJson, value, argNo);
2400  JSON_READ_FIELD_FWD(fieldJson, value, uncalled);
2401 }
2402 
2403 void SVFIRReader::fill(const cJSON*& fieldJson, SVFConstantData* value)
2404 {
2405  fill(fieldJson, static_cast<SVFConstant*>(value));
2406 }
2407 
2408 void SVFIRReader::fill(const cJSON*& fieldJson, SVFConstantInt* value)
2409 {
2410  fill(fieldJson, static_cast<SVFConstantData*>(value));
2411  JSON_READ_FIELD_FWD(fieldJson, value, zval);
2412  JSON_READ_FIELD_FWD(fieldJson, value, sval);
2413 }
2414 
2415 void SVFIRReader::fill(const cJSON*& fieldJson, SVFConstantFP* value)
2416 {
2417  fill(fieldJson, static_cast<SVFConstantData*>(value));
2418  JSON_READ_FIELD_FWD(fieldJson, value, dval);
2419 }
2420 
2421 void SVFIRReader::fill(const cJSON*& fieldJson, SVFConstantNullPtr* value)
2422 {
2423  fill(fieldJson, static_cast<SVFConstantData*>(value));
2424 }
2425 
2426 void SVFIRReader::fill(const cJSON*& fieldJson, SVFBlackHoleValue* value)
2427 {
2428  fill(fieldJson, static_cast<SVFConstantData*>(value));
2429 }
2430 
2431 void SVFIRReader::fill(const cJSON*& fieldJson, SVFOtherValue* value)
2432 {
2433  fill(fieldJson, static_cast<SVFValue*>(value));
2434 }
2435 
2436 void SVFIRReader::fill(const cJSON*& fieldJson, SVFMetadataAsValue* value)
2437 {
2438  fill(fieldJson, static_cast<SVFOtherValue*>(value));
2439 }
2440 
2441 void SVFIRReader::virtFill(const cJSON*& fieldJson, SVFType* type)
2442 {
2443  auto kind = type->getKind();
2444 
2445  switch (kind)
2446  {
2447  default:
2448  assert(false && "Impossible SVFType kind");
2449 
2450 #define CASE(Kind) \
2451  case SVFType::Kind: \
2452  return fill(fieldJson, SVFUtil::dyn_cast<Kind##pe>(type))
2453 
2454  CASE(SVFTy);
2455  CASE(SVFPointerTy);
2456  CASE(SVFIntegerTy);
2457  CASE(SVFFunctionTy);
2458  CASE(SVFStructTy);
2459  CASE(SVFArrayTy);
2460  CASE(SVFOtherTy);
2461 #undef CASE
2462  }
2463 }
2464 
2465 void SVFIRReader::fill(const cJSON*& fieldJson, SVFType* type)
2466 {
2467  // kind has already been read
2468  JSON_READ_FIELD_FWD(fieldJson, type, typeinfo);
2469 }
2470 
2471 void SVFIRReader::fill(const cJSON*& fieldJson, SVFPointerType* type)
2472 {
2473  fill(fieldJson, static_cast<SVFType*>(type));
2474 }
2475 
2476 void SVFIRReader::fill(const cJSON*& fieldJson, SVFIntegerType* type)
2477 {
2478  fill(fieldJson, static_cast<SVFType*>(type));
2479  JSON_READ_FIELD_FWD(fieldJson, type, signAndWidth);
2480 }
2481 
2482 void SVFIRReader::fill(const cJSON*& fieldJson, SVFFunctionType* type)
2483 {
2484  fill(fieldJson, static_cast<SVFType*>(type));
2485  JSON_READ_FIELD_FWD(fieldJson, type, retTy);
2486 }
2487 
2488 void SVFIRReader::fill(const cJSON*& fieldJson, SVFStructType* type)
2489 {
2490  fill(fieldJson, static_cast<SVFType*>(type));
2491  JSON_READ_FIELD_FWD(fieldJson, type, name);
2492 }
2493 
2494 void SVFIRReader::fill(const cJSON*& fieldJson, SVFArrayType* type)
2495 {
2496  fill(fieldJson, static_cast<SVFType*>(type));
2497  JSON_READ_FIELD_FWD(fieldJson, type, numOfElement);
2498  JSON_READ_FIELD_FWD(fieldJson, type, typeOfElement);
2499 }
2500 
2501 void SVFIRReader::fill(const cJSON*& fieldJson, SVFOtherType* type)
2502 {
2503  fill(fieldJson, static_cast<SVFType*>(type));
2504  JSON_READ_FIELD_FWD(fieldJson, type, repr);
2505 }
2506 
2508 {
2509  struct stat buf;
2510  int fd = open(path.c_str(), O_RDONLY);
2511  if (fd == -1)
2512  {
2513  std::string info = "open(\"" + path + "\")";
2514  perror(info.c_str());
2515  abort();
2516  }
2517  if (fstat(fd, &buf) == -1)
2518  {
2519  std::string info = "fstate(\"" + path + "\")";
2520  perror(info.c_str());
2521  abort();
2522  }
2523  auto addr =
2524  (char*)mmap(nullptr, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
2525  if (addr == MAP_FAILED)
2526  {
2527  std::string info = "mmap(content of \"" + path + "\")";
2528  perror(info.c_str());
2529  abort();
2530  }
2531 
2532  auto root = cJSON_ParseWithLength(addr, buf.st_size);
2533 
2534  if (munmap(addr, buf.st_size) == -1)
2535  perror("munmap()");
2536 
2537  if (close(fd) < 0)
2538  perror("close()");
2539 
2540  SVFIRReader reader;
2541  SVFIR* ir = reader.read(root);
2542 
2543  cJSON_Delete(root);
2544  return ir;
2545 }
2546 
2547 } // namespace SVF
#define ABORT_MSG(msg)
#define ABORT_IFNOT(condition, msg)
#define READ_CREATE_EDGE_FWD(GType)
#define CASE(Kind)
#define F(f)
#define READ_CREATE_NODE_FWD(GType)
static const Option< bool > humanReadableOption("human-readable", "Whether to output human-readable JSON", true)
#define JSON_READ_OBJ_FWD(json, obj)
Definition: SVFFileSystem.h:86
#define FIELD_NAME_ITEM(field)
Definition: SVFFileSystem.h:61
#define JSON_DEF_READ_FWD(json, type, obj,...)
Definition: SVFFileSystem.h:88
#define JSON_READ_FIELD_FWD(json, objptr, field)
Definition: SVFFileSystem.h:91
#define ENSURE_NOT_VISITED(graph)
Definition: SVFFileSystem.h:48
#define CHECK_JSON_KEY(obj)
Definition: SVFFileSystem.h:96
#define JSON_WRITE_FIELD(root, objptr, field)
Definition: SVFFileSystem.h:67
#define JSON_KEY(json)
Definition: SVFFileSystem.h:64
newitem type
Definition: cJSON.cpp:2739
cJSON * n
Definition: cJSON.cpp:2558
cJSON_Delete(null)
const char *const name
Definition: cJSON.h:264
const char *const const double number
Definition: cJSON.h:268
int index
Definition: cJSON.h:170
cJSON * item
Definition: cJSON.h:222
const char *const string
Definition: cJSON.h:172
@ INHERITANCE
Definition: CHG.h:86
@ INSTANTCE
Definition: CHG.h:87
CHEDGETYPE edgeType
Definition: CHG.h:104
Common base for class hierarchy graph. Only implements what PointerAnalysis needs.
Definition: CHG.h:51
GEdgeKind getEdgeKind() const
Definition: GenericGraph.h:89
void createObjs(const cJSON *graphJson, NodeCreator nodeCreator, EdgeCreator edgeCreator)
void saveToGenericGraph(GenericGraph< NodeTy, EdgeTy > *graph) const
EdgeTy * getEdgePtr(unsigned id) const
const cJSON * getFieldJson() const
NodeTy * getNodePtr(unsigned id) const
void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller)
size_t getEdgeID(const EdgeType *edge)
WriterPtrPool< EdgeType > edgePool
VFGNodeList VFGNodes
Definition: ICFGNode.h:150
SVFLoop * getSVFLoopPtr(size_t id) const
void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller, LoopFiller loopFiller)
void createObjs(const cJSON *icfgJson, NodeCreator nodeCreator, EdgeCreator edgeCreator, SVFLoopCreator svfLoopCreator)
WriterPtrPool< SVFLoop > svfLoopPool
size_t getSvfLoopID(const SVFLoop *loop)
ICFGWriter(const ICFG *icfg)
Definition: ICFG.h:48
const ICFGNodeToSVFLoopVec & getIcfgNodeToSVFLoopVec() const
Definition: ICFG.h:137
ValueToEdgeMap valueToEdgeMap
Map SVFValues (e.g., ICFGNodes) to all corresponding PAGEdges.
Definition: IRGraph.h:64
SymbolTableInfo * symInfo
Definition: IRGraph.h:65
SymID getId() const
Get the memory object id.
static NodeIDAllocator * get(void)
Return (singleton) allocator.
enum Strategy strategy
Strategy to allocate with.
static NodeIDAllocator * allocator
Single allocator.
Strategy
Allocation strategy to use.
u32_t elemNum
Size of the object or number of elements.
u32_t flags
Type flags.
GNodeK getNodeKind() const
Get node kind.
Definition: GenericGraph.h:266
NodeID getId() const
Get ID.
Definition: GenericGraph.h:260
IRGraphReader irGraphReader
SVFModuleReader svfModuleReader
static CHNode * createCHNode(NodeID id, GNodeK kind)
static ICFGEdge * createICFGEdge(GEdgeKind kind)
void fill(const cJSON *&fieldJson, SVFVar *var)
GenericEdge< void >::GEdgeKind GEdgeKind
static void readJson(const cJSON *obj, bool &flag)
static ICFGNode * createICFGNode(NodeID id, GNodeK type)
static CHEdge * createCHEdge(GEdgeKind kind)
static SVFStmt * createPAGEdge(GEdgeKind kind)
CHGraphReader chGraphReader
ICFGReader icfgReader
static SVFIR * read(const std::string &path)
const cJSON * createObjs(const cJSON *root)
static SVFVar * createPAGNode(NodeID id, GNodeK kind)
void virtFill(const cJSON *&fieldJson, SVFVar *var)
SymbolTableInfoReader symTableReader
const char * numToStr(size_t n)
static void writeJsonToOstream(const SVFIR *svfir, std::ostream &os)
std::unique_ptr< char, decltype(&cJSON_free)> autoCStr
static void writeJsonToPath(const SVFIR *svfir, const std::string &path)
const SVFIR * svfIR
std::unique_ptr< cJSON, decltype(&cJSON_Delete)> autoJSON
cJSON * genericNodeToJson(const GenericNode< NodeTy, EdgeTy > *node)
OrderedMap< size_t, std::string > numToStrMap
autoJSON generateJson()
Main logic to dump a SVFIR to a JSON object.
cJSON * toJson(const NodeIDAllocator *nodeIDAllocator)
cJSON * genericGraphToJson(const GenericGraph< NodeTy, EdgeTy > *graph, const std::vector< const EdgeTy * > &edgePool)
IRGraphWriter irGraphWriter
SVFIRWriter(const SVFIR *svfir)
Constructor.
SVFModuleWriter svfModuleWriter
cJSON * contentToJson(const SVFVar *var)
CHGraphWriter chgWriter
autoCStr generateJsonString()
ICFGWriter icfgWriter
bool jsonAddJsonableToObject(cJSON *obj, const char *name, const T &item)
cJSON * virtToJson(const SVFType *type)
Parameter types of these functions are all pointers. When they are used as arguments of toJson(),...
cJSON * genericEdgeToJson(const GenericEdge< NodeTy > *edge)
CommonCHGraph * chgraph
Definition: SVFIR.h:99
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
Definition: SVFIR.h:115
SVFModule * svfModule
Definition: SVFIR.h:97
ICFG * icfg
SVF Module.
Definition: SVFIR.h:98
ReaderPtrPool< StInfo > stInfoPool
StInfo * getStInfoPtr(size_t id) const
void createObjs(const cJSON *svfModuleJson, SVFTypeCreator typeCreator, SVFTypeFiller typeFiller, SVFValueCreator valueCreator, SVFValueFiller valueFiller, StInfoCreator stInfoCreator)
ReaderPtrPool< SVFType > svfTypePool
SVFValue * getSVFValuePtr(size_t id) const
SVFType * getSVFTypePtr(size_t id) const
const cJSON * getFieldJson() const
size_t getSVFValueID(const SVFValue *value)
size_t sizeSVFValuePool() const
const SVFValue * getSVFValuePtr(size_t id) const
SVFModuleWriter(const SVFModule *svfModule)
WriterPtrPool< SVFValue > svfValuePool
size_t getStInfoID(const StInfo *stInfo)
size_t getSVFTypeID(const SVFType *type)
WriterPtrPool< StInfo > stInfoPool
WriterPtrPool< SVFType > svfTypePool
const ConstantType & getConstantSet() const
Definition: SVFModule.h:203
static SVFModule * getSVFModule()
Definition: SVFModule.cpp:60
const FunctionSetType & getFunctionSet() const
Definition: SVFModule.h:199
const OtherValueType & getOtherValueSet() const
Definition: SVFModule.h:215
@ SVFFunctionTy
Definition: SVFType.h:170
@ SVFIntegerTy
Definition: SVFType.h:169
@ SVFPointerTy
Definition: SVFType.h:168
s64_t GNodeK
Definition: SVFType.h:163
GNodeK getKind() const
Get the type of this SVFValue.
Definition: SVFValue.h:238
s64_t GNodeK
Definition: SVFValue.h:184
ReaderIDToObjMap< MemObj > memObjMap
void createObjs(const cJSON *symTabJson, MemObjCreator memObjCreator)
MemObj * getMemObjPtr(unsigned id) const
const cJSON * getFieldJson() const
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
static SymbolTableInfo * symInfo
IDToMemMapTy objMap
map a memory sym id to its obj
SVFModule * mod
Module.
const std::vector< const T * > & getPool() const
long long strtoll(const char *str, char **endptr, int base)
Definition: extapi.c:971
unsigned long long strtoull(const char *str, char **endptr, int base)
Definition: extapi.c:989
unsigned long int strtoul(const char *str, char **endptr, int base)
Definition: extapi.c:983
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
Definition: SVFUtil.h:447
std::ostream & errs()
Overwrite llvm::errs()
Definition: SVFUtil.h:56
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
Definition: Casting.h:405
for isBitcode
Definition: BasicTypes.h:68
bool jsonAddNumberToObject(cJSON *obj, const char *name, double number)
Helper function to write a number to a JSON object.
cJSON * jsonCreateNullId()
double jsonGetNumber(const cJSON *item)
static void readSmallNumber(const cJSON *obj, SmallNumberType &val)
cJSON * jsonCreateNumber(double num)
bool jsonKeyEquals(const cJSON *item, const char *key)
bool jsonIsNumber(const cJSON *item)
bool jsonIsNullId(const cJSON *item)
u32_t NodeID
Definition: GeneralType.h:55
static SVFValue * createSVFValue(SVFValue::GNodeK kind, const SVFType *type, std::string &&name)
bool jsonAddPairToMap(cJSON *obj, cJSON *key, cJSON *value)
bool jsonIsMap(const cJSON *item)
cJSON * jsonCreateBool(bool flag)
bool jsonIsArray(const cJSON *item)
cJSON * jsonCreateMap()
bool jsonAddItemToArray(cJSON *array, cJSON *item)
SVFType * createSVFType(SVFType::GNodeK kind, bool isSingleValTy)
bool jsonAddStringToObject(cJSON *obj, const char *name, const char *str)
std::pair< const cJSON *, const cJSON * > jsonUnpackPair(const cJSON *item)
bool jsonIsObject(const cJSON *item)
static void readBigNumber(const cJSON *obj, BigNumberType &val, CStrToVal conv)
cJSON * jsonCreateObject()
bool jsonAddItemToObject(cJSON *obj, const char *name, cJSON *item)
unsigned SymID
Definition: GeneralType.h:57
unsigned u32_t
Definition: GeneralType.h:46
bool jsonIsBool(const cJSON *item)
cJSON * jsonCreateString(const char *str)
bool jsonIsString(const cJSON *item)
cJSON * jsonCreateIndex(size_t index)
cJSON * jsonCreateArray()
Definition: cJSON.h:104
struct cJSON * child
Definition: cJSON.h:109
double valuedouble
Definition: cJSON.h:119
char * string
Definition: cJSON.h:122
char * valuestring
Definition: cJSON.h:115
struct cJSON * next
Definition: cJSON.h:106