24 #ifndef INCLUDE_SVFFILESYSTEM_H_
25 #define INCLUDE_SVFFILESYSTEM_H_
30 #include <type_traits>
32 #define ABORT_MSG(reason) \
35 SVFUtil::errs() << __FILE__ << ':' << __LINE__ << ": " << reason \
39 #define ABORT_IFNOT(condition, reason) \
48 # define ENSURE_NOT_VISITED(graph) \
51 static std::set<decltype(graph)> visited; \
52 bool inserted = visited.insert(graph).second; \
53 ABORT_IFNOT(inserted, #graph << " already visited!"); \
56 # define ENSURE_NOT_VISITED(graph) \
61 #define FIELD_NAME_ITEM(field) #field, (field)
63 #define JSON_FIELD_OR(json, field, default) ((json) ? (json)->field : default)
64 #define JSON_KEY(json) JSON_FIELD_OR(json, string, "NULL")
65 #define JSON_CHILD(json) JSON_FIELD_OR(json, child, nullptr)
67 #define JSON_WRITE_FIELD(root, objptr, field) \
68 jsonAddJsonableToObject(root, #field, (objptr)->field)
70 #define JSON_READ_OBJ_WITH_NAME(json, obj, name) \
73 ABORT_IFNOT(jsonKeyEquals(json, name), \
74 "Expect name '" << name << "', got " << JSON_KEY(json)); \
75 SVFIRReader::readJson(json, obj); \
78 #define JSON_READ_OBJ_WITH_NAME_FWD(json, obj, name) \
81 JSON_READ_OBJ_WITH_NAME(json, obj, name); \
82 json = (json)->next; \
85 #define JSON_READ_OBJ(json, obj) JSON_READ_OBJ_WITH_NAME(json, obj, #obj)
86 #define JSON_READ_OBJ_FWD(json, obj) \
87 JSON_READ_OBJ_WITH_NAME_FWD(json, obj, #obj)
88 #define JSON_DEF_READ_FWD(json, type, obj, ...) \
89 type obj __VA_ARGS__; \
90 JSON_READ_OBJ_FWD(json, obj)
91 #define JSON_READ_FIELD_FWD(json, objptr, field) \
92 JSON_READ_OBJ_WITH_NAME_FWD(json, (objptr)->field, #field)
93 #define CHECK_JSON_KEY_EQUALS(obj, key) \
94 ABORT_IFNOT(jsonKeyEquals(obj, key), \
95 "Expect json key: " << key << ", but get " << JSON_KEY(obj));
96 #define CHECK_JSON_KEY(obj) CHECK_JSON_KEY_EQUALS(obj, #obj)
102 class NodeIDAllocator;
105 class SVFPointerType;
106 class SVFIntegerType;
107 class SVFFunctionType;
117 class SVFInstruction;
119 class SVFVirtualCallInst;
121 class SVFGlobalValue;
123 class SVFConstantData;
124 class SVFConstantInt;
126 class SVFConstantNullPtr;
127 class SVFBlackHoleValue;
129 class SVFMetadataAsValue;
131 class SVFLoopAndDomInfo;
138 class GlobalICFGNode;
141 class FunEntryICFGNode;
142 class FunExitICFGNode;
158 class SymbolTableInfo;
226 #define jsonForEach(field, array) \
227 for (const cJSON* field = JSON_CHILD(array); field; field = field->next)
244 typename decltype(
ptrToId)::iterator it;
246 std::tie(it, inserted) =
ptrToId.emplace(ptr, 1 +
ptrPool.size());
259 assert(
id <=
ptrPool.size() &&
"Invalid ID");
260 return id ?
ptrPool[
id - 1] :
nullptr;
263 inline const std::vector<const T*>&
getPool()
const
304 assert(graph &&
"Graph pointer should never be null");
311 for (
const EdgeType* edge : node->getOutEdges())
393 using autoCStr = std::unique_ptr<char, decltype(&cJSON_free)>;
537 template <
typename NodeTy,
typename EdgeTy>
548 template <
typename NodeTy>
558 template <
typename NodeTy,
typename EdgeTy>
560 const std::vector<const EdgeTy*>& edgePool)
567 NodeTy* node = pair.second;
573 for (
const EdgeTy* edge : edgePool)
613 template <
typename T,
typename U>
cJSON*
toJson(
const std::pair<T, U>& pair)
621 template <
typename T,
622 typename = std::enable_if_t<SVFUtil::is_iterable_v<T>>>
626 for (
const auto&
item : container)
634 template <
typename T>
641 template <
typename T>
659 #define KIND_BASE(B, KindGetter) \
660 template <typename T> \
661 struct KindBaseHelper<T, std::enable_if_t<std::is_base_of<B, T>::value>> \
664 static inline s64_t getKind(T* p) \
666 return {p->KindGetter()}; \
691 template <
typename IdObjCreator>
695 assert(
idMap.empty() &&
696 "idToObjMap should be empty when creating objects");
704 auto idObj = idObjCreator(objFieldJson);
705 auto pair = std::pair<const cJSON*, T*>(objFieldJson, idObj.second);
706 bool inserted =
idMap.emplace(idObj.first, pair).second;
707 ABORT_IFNOT(inserted,
"ID " << idObj.first <<
" duplicated in "
708 << idObjArrayJson->
string);
714 auto it =
idMap.find(
id);
716 return it->second.second;
719 template <
typename FillFunc>
void fillObjs(FillFunc fillFunc)
721 for (
auto& pair :
idMap)
723 const cJSON* objFieldJson = pair.second.first;
724 T* obj = pair.second.second;
725 fillFunc(objFieldJson, obj);
727 ABORT_IFNOT(!objFieldJson,
"json should be consumed by filler, but "
728 << objFieldJson->
string <<
" left");
739 for (
auto& pair :
idMap)
741 unsigned id = pair.first;
742 T* obj = pair.second.second;
743 assert(obj &&
"obj should not be null");
744 idToObjMap.insert(std::make_pair(
id, obj));
768 template <
typename Creator>
772 "jsonArray should be empty when creating objects");
779 T* obj = creator(objFieldJson);
788 "Invalid ID " <<
id <<
". Max ID = " <<
ptrPool.size());
789 return id ?
ptrPool[
id - 1] :
nullptr;
792 template <
typename FillFunc>
void fillObjs(FillFunc fillFunc)
795 "jsonArray and ptrPool should have same size");
796 for (
size_t i = 0; i <
jsonArray.size(); ++i)
799 fillFunc(objFieldJson,
ptrPool[i]);
800 ABORT_IFNOT(!objFieldJson,
"json should be consumed by filler, but "
801 << objFieldJson->
string <<
" left");
831 template <
typename NodeCreator,
typename EdgeCreator>
833 EdgeCreator edgeCreator)
874 template <
typename NodeFiller,
typename EdgeFiller>
875 void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller)
912 template <
typename MemObjCreator>
918 const cJSON*
const allMemObj = symTabJson->
child;
920 memObjMap.createObjs(allMemObj, memObjCreator);
943 template <
typename NodeCreator,
typename EdgeCreator,
typename SVFLoopCreator>
945 EdgeCreator edgeCreator, SVFLoopCreator svfLoopCreator)
960 template <
typename NodeFiller,
typename EdgeFiller,
typename LoopFiller>
961 void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller,
962 LoopFiller loopFiller)
980 template <
typename SVFTypeCreator,
typename SVFTypeFiller,
981 typename SVFValueCreator,
typename SVFValueFiller,
982 typename StInfoCreator>
984 SVFTypeFiller typeFiller, SVFValueCreator valueCreator,
985 SVFValueFiller valueFiller, StInfoCreator stInfoCreator)
989 "svfModuleJson not an JSON object?");
991 const cJSON*
const allSVFType = svfModuleJson->
child;
995 const cJSON*
const allStInfo = allSVFType->
next;
997 stInfoPool.createObjs(allStInfo, stInfoCreator);
1001 const cJSON*
const allSVFValue = allStInfo->
next;
1051 static void readJson(
const cJSON* obj,
unsigned long long& val);
1059 template <
typename T>
1077 template <
typename EdgeCreator>
1081 auto edge = creator(kind);
1115 template <
unsigned ElementSize>
1139 template <
typename T>
1147 ptr = SVFUtil::dyn_cast<T>(basePtr);
1155 assert(!cptr &&
"const pointer should be NULL");
1161 template <
typename T1,
typename T2>
1166 readJson(jpair.second, pair.second);
1169 template <
typename T,
size_t N>
1172 static_assert(N > 0,
"array size should be greater than 0");
1181 ABORT_IFNOT(i == N,
"expect array of size " << N);
1184 template <
typename C>
1185 std::enable_if_t<SVFUtil::is_sequence_container_v<C>>
readJson(
1186 const cJSON* obj, C& container)
1188 using T =
typename C::value_type;
1189 assert(container.empty() &&
"container should be empty");
1193 container.push_back(T{});
1194 readJson(elemJson, container.back());
1198 template <
typename C>
1201 assert(map.empty() &&
"map should be empty");
1206 typename C::key_type key{};
1208 auto it = map.emplace(
std::move(key),
typename C::mapped_type{});
1210 readJson(jpair.second, it.first->second);
1214 template <
typename C>
1217 using T =
typename C::value_type;
1218 assert(
set.empty() &&
"set should be empty");
1314 template <
typename NodeTy,
typename EdgeTy>
1322 template <
typename NodeTy>
#define FIELD_NAME_ITEM(field)
#define jsonForEach(field, array)
#define ABORT_IFNOT(condition, reason)
#define JSON_READ_FIELD_FWD(json, objptr, field)
#define CHECK_JSON_KEY(obj)
#define JSON_WRITE_FIELD(root, objptr, field)
set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) add_llvm_executable(wpa wpa.cpp) target_link_libraries(wpa PUBLIC $
const char *const const double number
Common base for class hierarchy graph. Only implements what PointerAnalysis needs.
GEdgeFlag edgeFlag
edge kind
const cJSON * graphFieldJson
void createObjs(const cJSON *graphJson, NodeCreator nodeCreator, EdgeCreator edgeCreator)
ReaderIDToObjMap< NodeTy > idToNodeMap
void saveToGenericGraph(GenericGraph< NodeTy, EdgeTy > *graph) const
ReaderPtrPool< EdgeTy > edgePool
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
GenericGraphWriter(const GraphType *graph)
u32_t getTotalEdgeNum() const
u32_t edgeNum
total num of node
u32_t nodeNum
total num of edge
IDToNodeMapTy IDToNodeMap
node map
ReaderPtrPool< SVFLoop > svfLoopPool
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)
Keeps a map from IDs to T objects, such as XXNode.
void saveToIDToObjMap(Map &idToObjMap) const
void fillObjs(FillFunc fillFunc)
T * getPtr(unsigned id) const
OrderedMap< unsigned, std::pair< const cJSON *, T * > > IDToPairMapTy
void createObjs(const cJSON *idObjArrayJson, IdObjCreator idObjCreator)
idObjcreator : (const cJSON*) -> (id, T*) with id set
Reverse of WriterPtrPool where T is object type without ID field.
std::vector< T * > ptrPool
std::vector< const cJSON * > jsonArray
void saveToSet(Set &set) const
T * getPtr(size_t id) const
void reserve(size_t size)
void fillObjs(FillFunc fillFunc)
void createObjs(const cJSON *objArrayJson, Creator creator)
IRGraphReader irGraphReader
SVFModuleReader svfModuleReader
static CHNode * createCHNode(NodeID id, GNodeK kind)
static ICFGEdge * createICFGEdge(GEdgeKind kind)
void fill(const cJSON *&fieldJson, SVFVar *var)
void fill(const cJSON *&fieldJson, GenericNode< NodeTy, EdgeTy > *node)
GenericEdge< void >::GEdgeKind GEdgeKind
void readJson(const cJSON *obj, const T *&cptr)
Read a const pointer.
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)
void fill(const cJSON *&fieldJson, GenericEdge< NodeTy > *edge)
CHGraphReader chGraphReader
GenericEdge< void >::GEdgeFlag GEdgeFlag
std::enable_if_t< SVFUtil::is_sequence_container_v< C > > readJson(const cJSON *obj, C &container)
void readJson(const cJSON *obj, SparseBitVector< ElementSize > &bv)
std::enable_if_t< SVFUtil::is_set_v< C > > readJson(const cJSON *obj, C &set)
static s64_t applyEdgeMask(u64_t edgeFlag)
std::enable_if_t< SVFUtil::is_map_v< C > > readJson(const cJSON *obj, C &map)
static SVFIR * read(const std::string &path)
static auto createEdgeWithFlag(GEdgeFlag flag, EdgeCreator creator)
SVFUtil::void_t< KindBaseT< T > > readJson(const cJSON *obj, T *&ptr)
Read a pointer of some child class of SVFType/SVFValue/SVFVar/SVFStmt/ICFGNode/ICFGEdge/CHNode/CHEdge...
const cJSON * createObjs(const cJSON *root)
void readJson(const cJSON *obj, std::pair< T1, T2 > &pair)
void readJson(const cJSON *obj, T(&array)[N])
static SVFVar * createPAGNode(NodeID id, GNodeK kind)
void virtFill(const cJSON *&fieldJson, SVFVar *var)
static void setEdgeFlag(GenericEdge< T > *edge, typename GenericEdge< T >::GEdgeFlag edgeFlag)
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 * genericNodeToJson(const GenericNode< NodeTy, EdgeTy > *node)
bool jsonAddContentToObject(cJSON *obj, const char *name, const T &item)
cJSON * toJson(const std::pair< T, U > &pair)
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 * toJson(const T &container)
cJSON * contentToJson(const SVFVar *var)
autoCStr generateJsonString()
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)
ReaderPtrPool< SVFValue > svfValuePool
const cJSON * svfModuleFieldJson
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
ReaderIDToObjMap< MemObj > memObjMap
const cJSON * symTabFieldJson
void createObjs(const cJSON *symTabJson, MemObjCreator memObjCreator)
MemObj * getMemObjPtr(unsigned id) const
const cJSON * getFieldJson() const
Bookkeeping class to keep track of the IDs of objects that doesn't have any ID. E....
const std::vector< const T * > & getPool() const
size_t getID(const T *ptr)
const T * getPtr(size_t id) const
std::vector< const T * > ptrPool
void saveID(const T *ptr)
Map< const T *, size_t > ptrToId
void reserve(size_t size)
constexpr std::remove_reference< T >::type && move(T &&t) noexcept
typename make_void< Ts... >::type void_t
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)
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)
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
bool jsonAddItemToArray(cJSON *array, cJSON *item)
KIND_BASE(SVFType, getKind)
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)
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)
typename KindBaseHelper< T >::type KindBaseT
std::map< Key, Value, Compare, Allocator > OrderedMap
cJSON * jsonCreateIndex(size_t index)
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
cJSON * jsonCreateArray()
Type trait to get base type. Helper struct to detect inheritance from Node/Edge.