12 "human-readable",
"Whether to output human-readable JSON",
true);
22 ABORT_MSG(kind <<
" is an impossible SVFTyKind in create()");
24 ABORT_MSG(
"Creation of RAW SVFType isn't allowed");
26 ABORT_IFNOT(isSingleValTy,
"Pointer type must be single-valued");
29 ABORT_IFNOT(isSingleValTy,
"Integer type must be single-valued");
32 ABORT_IFNOT(!isSingleValTy,
"Function type must be multi-valued");
35 ABORT_IFNOT(!isSingleValTy,
"Struct type must be multi-valued");
38 ABORT_IFNOT(!isSingleValTy,
"Array type must be multi-valued");
53 ABORT_MSG(kind <<
" is an impossible SVFValueKind in create()");
55 ABORT_MSG(
"Creation of RAW SVFValue isn't allowed");
91template <
typename SmallNumberType>
97template <
typename BigNumberType,
typename CStrToVal>
101 "Expect (number) string JSON for " <<
JSON_KEY(
obj));
150 auto kind =
type->getKind();
155 assert(
false &&
"Impossible SVFType kind");
158 case SVFType::Kind: \
159 return contentToJson(static_cast<const Kind##pe*>(type))
179 assert(
false &&
"Impossible SVFValue kind");
181#define CASE(ValueKind, type) \
182 case SVFValue::ValueKind: \
183 return contentToJson(static_cast<const type*>(value))
206 switch (
var->getNodeKind())
209 assert(
false &&
"Unknown SVFVar kind");
211#define CASE(VarKind, VarType) \
212 case SVFVar::VarKind: \
213 return contentToJson(static_cast<const VarType*>(var))
245 switch (
stmt->getEdgeKind())
248 assert(
false &&
"Unknown SVFStmt kind");
250#define CASE(EdgeKind, EdgeType) \
251 case SVFStmt::EdgeKind: \
252 return contentToJson(static_cast<const EdgeType*>(stmt))
278 assert(
false &&
"Unknown ICFGNode kind");
280#define CASE(NodeKind, NodeType) \
281 case ICFGNode::NodeKind: \
282 return contentToJson(static_cast<const NodeType*>(node))
296 switch (
edge->getEdgeKind())
299 assert(
false &&
"Unknown ICFGEdge kind");
550#define F(f) JSON_WRITE_FIELD(root, value, f);
667#define F(field) JSON_WRITE_FIELD(root, loop, field)
968 const auto& svfTypes =
symTab->getSVFTypes();
975 const auto& stInfos =
symTab->getStInfos();
988 : svfIR(svfir), svfModuleWriter(svfir->svfModule), icfgWriter(svfir->icfg),
989 chgWriter(SVFUtil::dyn_cast<
CHGraph>(svfir->chgraph)),
997 os <<
writer.generateJsonString().get() <<
'\n';
1011 <<
"' to write SVFIR's JSON\n";
1020 return it->second.c_str();
1022 return numToStrMap.emplace_hint(
it,
n, std::to_string(
n))->second.c_str();
1040#define F(field) JSON_WRITE_FIELD(root, svfIR, field)
1046 F(icfgNode2SVFStmtsMap);
1047 F(icfgNode2PTASVFStmtsMap);
1055 F(callSiteArgsListMap);
1058 F(indCallSiteToFunPtrMap);
1059 F(funPtrToCallSitesMap);
1060 F(candidatePointers);
1083#define F(field) JSON_WRITE_FIELD(root, graph, field)
1084 F(KindToSVFStmtSetMap);
1085 F(KindToPTASVFStmtSetMap);
1087 F(nodeNumAfterPAGBuild);
1113#define F(field) JSON_WRITE_FIELD(root, icfg, field)
1117 F(FunToFunEntryNodeMap);
1118 F(FunToFunExitNodeMap);
1120 F(icfgNodeToSVFLoopVec);
1127 assert(node &&
"ICFGNode is null!");
1139 auto chg = SVFUtil::dyn_cast<CHGraph>(graph);
1140 assert(chg &&
"Unsupported CHGraph type!");
1147#define F(field) JSON_WRITE_FIELD(root, graph, field)
1152 F(classNameToNodeMap);
1153 F(classNameToDescendantsMap);
1154 F(classNameToAncestorsMap);
1155 F(classNameToInstAndDescsMap);
1156 F(templateNameToInstancesMap);
1157 F(callNodeToClassesMap);
1158 F(virtualFunctionToIDMap);
1159 F(callNodeToCHAVtblsMap);
1160 F(callNodeToCHAVFnsMap);
1192#define F(field) JSON_WRITE_FIELD(root, stInfo, field)
1194 F(numOfFlattenElements);
1195 F(numOfFlattenFields);
1200 F(flattenElementTypes);
1276#define F(field) JSON_WRITE_FIELD(root, symTable, field)
1316#define F(field) JSON_WRITE_FIELD(root, module, field)
1321 F(moduleIdentifier);
1347 auto icfg =
new ICFG();
1348 auto chgraph =
new CHGraph(svfModule);
1350 symInfo->mod = svfModule;
1356#define F(field) JSON_READ_FIELD_FWD(svfirField, svfIR, field)
1363 F(icfgNode2SVFStmtsMap);
1364 F(icfgNode2PTASVFStmtsMap);
1372 F(callSiteArgsListMap);
1375 F(indCallSiteToFunPtrMap);
1376 F(funPtrToCallSitesMap);
1377 F(candidatePointers);
1389#define READ_CREATE_NODE_FWD(GType) \
1390 [](const cJSON*& nodeJson) { \
1391 JSON_DEF_READ_FWD(nodeJson, NodeID, id); \
1392 JSON_DEF_READ_FWD(nodeJson, GNodeK, nodeKind); \
1393 return std::make_pair(id, create##GType##Node(id, nodeKind)); \
1395#define READ_CREATE_EDGE_FWD(GType) \
1396 [](const cJSON*& edgeJson) { \
1397 JSON_DEF_READ_FWD(edgeJson, GEdgeFlag, edgeFlag); \
1398 auto kind = applyEdgeMask(edgeFlag); \
1399 auto edge = create##GType##Edge(kind); \
1400 setEdgeFlag(edge, edgeFlag); \
1445 const cJSON*
const symInfo = svfModule->
next;
1455 return std::make_pair(symId,
new MemObj(symId, typeInfo, refVal));
1458 const cJSON*
const icfg = symInfo->
next;
1467 const cJSON*
const chgraph = icfg->
next;
1511#undef READ_CREATE_EDGE_FWD
1512#undef READ_CREATE_NODE_FWD
1545 return std::strtoul(
s,
nullptr, 10);
1554 return std::strtoll(
s,
nullptr, 10);
1563 return std::strtoull(
s,
nullptr, 10);
1578 ABORT_MSG(kind <<
" is an impossible ICFGNodeKind in create()");
1579#define CASE(kind, constructor) \
1580 case ICFGNode::kind: \
1581 return new constructor(id);
1600 ABORT_MSG(kind <<
" is an impossible ICFGEdgeKind in create()");
1612 ABORT_IFNOT(kind == 0,
"Impossible CHNode kind " << kind);
1613 return new CHNode(
"",
id);
1618 ABORT_IFNOT(kind == 0,
"Unsupported CHEdge kind " << kind);
1619 return new CHEdge(
nullptr,
nullptr, {});
1627 ABORT_MSG(kind <<
" is an impossible SVFVarKind in create()");
1628#define CASE(kind, constructor) \
1629 case SVFVar::kind: \
1630 return new constructor(id);
1649 ABORT_MSG(kind <<
" is an impossible SVFStmtKind in create()");
1650#define CASE(kind, constructor) \
1651 case SVFStmt::kind: \
1652 return new constructor;
1680 static_assert(
sizeof(
idAllocator->strategy) ==
sizeof(strategy),
1681 "idAllocator->strategy should be represented by int");
1694#define F(field) JSON_READ_FIELD_FWD(obj, symTabInfo, field)
1719#define F(field) JSON_READ_FIELD_FWD(obj, graph, field)
1721 F(KindToSVFStmtSetMap);
1722 F(KindToPTASVFStmtSetMap);
1724 F(nodeNumAfterPAGBuild);
1738#define F(field) JSON_READ_FIELD_FWD(obj, icfg, field)
1740 F(FunToFunEntryNodeMap);
1741 F(FunToFunExitNodeMap);
1743 F(icfgNodeToSVFLoopVec);
1751#define F(field) JSON_READ_FIELD_FWD(obj, graph, field)
1754 F(classNameToNodeMap);
1755 F(classNameToDescendantsMap);
1756 F(classNameToAncestorsMap);
1757 F(classNameToInstAndDescsMap);
1758 F(templateNameToInstancesMap);
1759 F(callNodeToClassesMap);
1760 F(virtualFunctionToIDMap);
1761 F(callNodeToCHAVtblsMap);
1762 F(callNodeToCHAVFnsMap);
1770 assert(symInfo &&
"SymbolTableInfo should be non-NULL");
1774#define F(field) JSON_READ_FIELD_FWD(obj, module, field)
1776 F(moduleIdentifier);
1799 assert(!value &&
"SVFValue already read?");
1820 assert(!node &&
"ICFGNode already read?");
1833 assert(!node &&
"CHNode already read?");
1904 switch (
var->getNodeKind())
1907 assert(
false &&
"Unknown SVFVar kind");
1909#define CASE(VarKind, VarType) \
1910 case SVFVar::VarKind: \
1911 return fill(fieldJson, static_cast<VarType*>(var))
1987 auto kind =
stmt->getEdgeKind();
1992 ABORT_MSG(
"Unknown SVFStmt kind " << kind);
1994#define CASE(EdgeKind, EdgeType) \
1995 case SVFStmt::EdgeKind: \
1996 return fill(fieldJson, static_cast<EdgeType*>(stmt))
2136#define F(field) JSON_READ_FIELD_FWD(fieldJson, stInfo, field)
2138 F(numOfFlattenElements);
2139 F(numOfFlattenFields);
2144 F(flattenElementTypes);
2155#define CASE(NodeKind, NodeType) \
2156 case ICFGNode::NodeKind: \
2157 return fill(fieldJson, static_cast<NodeType*>(node))
2222 auto kind =
edge->getEdgeKind();
2226 ABORT_MSG(
"Unknown ICFGEdge kind " << kind);
2262#define F(field) JSON_READ_FIELD_FWD(fieldJson, loop, field)
2284 assert(
edge->getEdgeKind() == 0 &&
"Unknown CHEdge kind");
2293 ABORT_MSG(
"Unknown CHEdge type " << edgeType);
2303 ABORT_MSG(
"Impossible SVFValue kind " << kind);
2305#define CASE(ValueKind, Type) \
2306 case SVFValue::ValueKind: \
2307 return fill(fieldJson, static_cast<Type*>(value))
2339#define F(f) JSON_READ_FIELD_FWD(fieldJson, value, f)
2437 auto kind =
type->getKind();
2442 assert(
false &&
"Impossible SVFType kind");
2445 case SVFType::Kind: \
2446 return fill(fieldJson, SVFUtil::dyn_cast<Kind##pe>(type))
2451 CASE(SVFFunctionTy);
2507 std::string
info =
"open(\"" +
path +
"\")";
2513 std::string
info =
"fstate(\"" +
path +
"\")";
2521 std::string
info =
"mmap(content of \"" +
path +
"\")";
#define ABORT_IFNOT(condition, msg)
#define READ_CREATE_EDGE_FWD(GType)
static const Option< bool > humanReadableOption("human-readable", "Whether to output human-readable JSON", true)
#define READ_CREATE_NODE_FWD(GType)
#define JSON_READ_OBJ_FWD(json, obj)
#define FIELD_NAME_ITEM(field)
#define JSON_DEF_READ_FWD(json, type, obj,...)
#define JSON_READ_FIELD_FWD(json, objptr, field)
#define ENSURE_NOT_VISITED(graph)
#define CHECK_JSON_KEY(obj)
#define JSON_WRITE_FIELD(root, objptr, field)
const char *const const double number
Common base for class hierarchy graph. Only implements what PointerAnalysis needs.
EdgeTy * getEdgePtr(unsigned id) const
void createObjs(const cJSON *graphJson, NodeCreator nodeCreator, EdgeCreator edgeCreator)
void saveToGenericGraph(GenericGraph< NodeTy, EdgeTy > *graph) const
NodeTy * getNodePtr(unsigned id) const
const cJSON * getFieldJson() const
void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller)
size_t getEdgeID(const EdgeType *edge)
WriterPtrPool< EdgeType > edgePool
Class representing a heap object variable in the SVFIR.
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)
const ICFGNodeToSVFLoopVec & getIcfgNodeToSVFLoopVec() const
ValueToEdgeMap valueToEdgeMap
Map SVFValues (e.g., ICFGNodes) to all corresponding PAGEdges.
SymbolTableInfo * symInfo
static NodeIDAllocator * get(void)
Return (singleton) allocator.
static NodeIDAllocator * allocator
Single allocator.
Strategy
Allocation strategy to use.
GNodeK getNodeKind() const
Get node kind.
NodeID getId() const
Get ID.
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
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)
std::unique_ptr< cJSON, decltype(&cJSON_Delete)> autoJSON
cJSON * genericGraphToJson(const GenericGraph< NodeTy, EdgeTy > *graph, const std::vector< const EdgeTy * > &edgePool)
OrderedMap< size_t, std::string > numToStrMap
cJSON * genericNodeToJson(const GenericNode< NodeTy, EdgeTy > *node)
autoJSON generateJson()
Main logic to dump a SVFIR to a JSON object.
cJSON * toJson(const NodeIDAllocator *nodeIDAllocator)
IRGraphWriter irGraphWriter
SVFIRWriter(const SVFIR *svfir)
Constructor.
SVFModuleWriter svfModuleWriter
cJSON * contentToJson(const SVFVar *var)
autoCStr generateJsonString()
cJSON * contentToJson(const SVFFunctionType *type)
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)
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
SVFType * getSVFTypePtr(size_t id) const
const cJSON * getFieldJson() const
StInfo * getStInfoPtr(size_t id) const
SVFValue * getSVFValuePtr(size_t id) const
ReaderPtrPool< StInfo > stInfoPool
void createObjs(const cJSON *svfModuleJson, SVFTypeCreator typeCreator, SVFTypeFiller typeFiller, SVFValueCreator valueCreator, SVFValueFiller valueFiller, StInfoCreator stInfoCreator)
ReaderPtrPool< SVFType > svfTypePool
size_t getSVFValueID(const SVFValue *value)
size_t sizeSVFValuePool() 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 SVFValue * getSVFValuePtr(size_t id) const
const OtherValueType & getOtherValueSet() const
const FunctionSetType & getFunctionSet() const
static SVFModule * getSVFModule()
const ConstantType & getConstantSet() const
GNodeK getKind() const
Get the type of this SVFValue.
Represents a stack-allocated object variable in the SVFIR (SVF Intermediate Representation) @inherits...
ReaderIDToObjMap< MemObj > memObjMap
const cJSON * getFieldJson() const
void createObjs(const cJSON *symTabJson, MemObjCreator memObjCreator)
MemObj * getMemObjPtr(unsigned id) const
static SymbolTableInfo * SymbolInfo()
Singleton design here to make sure we only have one instance during any analysis.
static SymbolTableInfo * symInfo
const std::vector< const T * > & getPool() const
std::ostream & errs()
Overwrite llvm::errs()
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)
bool jsonAddPairToMap(cJSON *obj, cJSON *key, cJSON *value)
bool jsonIsMap(const cJSON *item)
cJSON * jsonCreateBool(bool flag)
bool jsonIsArray(const cJSON *item)
llvm::IRBuilder IRBuilder
bool jsonAddItemToArray(cJSON *array, cJSON *item)
static SVFValue * createSVFValue(SVFValue::GNodeK kind, const SVFType *type, std::string &&name)
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)
bool jsonIsBool(const cJSON *item)
cJSON * jsonCreateString(const char *str)
bool jsonIsString(const cJSON *item)
cJSON * jsonCreateIndex(size_t index)
cJSON * jsonCreateArray()
SVFType * createSVFType(SVFType::GNodeK kind, bool isSingleValTy)