24#ifndef INCLUDE_SVFFILESYSTEM_H_
25#define INCLUDE_SVFFILESYSTEM_H_
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)
102class NodeIDAllocator;
107class SVFFunctionType;
122class SVFConstantData;
125class SVFConstantNullPtr;
126class SVFBlackHoleValue;
128class SVFMetadataAsValue;
130class SVFLoopAndDomInfo;
140class FunEntryICFGNode;
141class FunExitICFGNode;
157class SymbolTableInfo;
225#define jsonForEach(field, array) \
226 for (const cJSON* field = JSON_CHILD(array); field; field = field->next)
259 return id ?
ptrPool[
id - 1] :
nullptr;
262 inline const std::vector<const T*>&
getPool()
const
303 assert(graph &&
"Graph pointer should never be null");
306 for (
const auto&
pair : graph->IDToNodeMap)
535 template <
typename NodeTy,
typename EdgeTy>
546 template <
typename NodeTy>
556 template <
typename NodeTy,
typename EdgeTy>
558 const std::vector<const EdgeTy*>& edgePool)
619 template <
typename T,
620 typename = std::enable_if_t<SVFUtil::is_iterable_v<T>>>
632 template <
typename T>
639 template <
typename T>
657#define KIND_BASE(B, KindGetter) \
658 template <typename T> \
659 struct KindBaseHelper<T, std::enable_if_t<std::is_base_of<B, T>::value>> \
662 static inline s64_t getKind(T* p) \
664 return {p->KindGetter()}; \
689 template <
typename IdObjCreator>
694 "idToObjMap should be empty when creating objects");
714 return it->second.second;
739 unsigned id =
pair.first;
742 idToObjMap.insert(std::make_pair(
id,
obj));
766 template <
typename Creator>
770 "jsonArray should be empty when creating objects");
786 "Invalid ID " <<
id <<
". Max ID = " <<
ptrPool.size());
787 return id ?
ptrPool[
id - 1] :
nullptr;
793 "jsonArray and ptrPool should have same size");
829 template <
typename NodeCreator,
typename EdgeCreator>
872 template <
typename NodeFiller,
typename EdgeFiller>
910 template <
typename MemObjCreator>
941 template <
typename NodeCreator,
typename EdgeCreator,
typename SVFLoopCreator>
958 template <
typename NodeFiller,
typename EdgeFiller,
typename LoopFiller>
987 "svfModuleJson not an JSON object?");
1057 template <
typename T>
1061 edge->edgeFlag = edgeFlag;
1075 template <
typename EdgeCreator>
1113 template <
unsigned ElementSize>
1137 template <
typename T>
1153 assert(!
cptr &&
"const pointer should be NULL");
1159 template <
typename T1,
typename T2>
1167 template <
typename T,
size_t N>
1170 static_assert(
N > 0,
"array size should be greater than 0");
1182 template <
typename C>
1183 std::enable_if_t<SVFUtil::is_sequence_container_v<C>>
readJson(
1186 using T =
typename C::value_type;
1196 template <
typename C>
1199 assert(
map.empty() &&
"map should be empty");
1204 typename C::key_type
key{};
1206 auto it =
map.emplace(std::move(
key),
typename C::mapped_type{});
1212 template <
typename C>
1215 using T =
typename C::value_type;
1216 assert(
set.empty() &&
"set should be empty");
1311 template <
typename NodeTy,
typename EdgeTy>
1319 template <
typename NodeTy>
#define ABORT_IFNOT(condition, msg)
#define FIELD_NAME_ITEM(field)
#define jsonForEach(field, array)
#define JSON_READ_FIELD_FWD(json, objptr, field)
#define CHECK_JSON_KEY(obj)
#define JSON_WRITE_FIELD(root, objptr, field)
#define KIND_BASE(B, KindGetter)
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.
EdgeTy * getEdgePtr(unsigned id) const
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
NodeTy * getNodePtr(unsigned id) const
const cJSON * getFieldJson() const
void fillObjs(NodeFiller nodeFiller, EdgeFiller edgeFiller)
GenericGraph< NodeType, EdgeType > GraphType
size_t getEdgeID(const EdgeType *edge)
WriterPtrPool< EdgeType > edgePool
GenericGraphWriter(const GraphType *graph)
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)
Keeps a map from IDs to T objects, such as XXNode.
T * getPtr(unsigned id) const
void saveToIDToObjMap(Map &idToObjMap) const
void fillObjs(FillFunc fillFunc)
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
void readJson(const cJSON *obj, SparseBitVector< ElementSize > &bv)
static s64_t applyEdgeMask(u64_t edgeFlag)
std::enable_if_t< SVFUtil::is_sequence_container_v< C > > readJson(const cJSON *obj, C &container)
static SVFIR * read(const std::string &path)
static auto createEdgeWithFlag(GEdgeFlag flag, EdgeCreator creator)
std::enable_if_t< SVFUtil::is_map_v< C > > readJson(const cJSON *obj, C &map)
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
std::enable_if_t< SVFUtil::is_set_v< C > > readJson(const cJSON *obj, C &set)
const char * numToStr(size_t n)
static void writeJsonToOstream(const SVFIR *svfir, std::ostream &os)
std::unique_ptr< char, decltype(&cJSON_free)> autoCStr
cJSON * toJson(const std::pair< T, U > &pair)
static void writeJsonToPath(const SVFIR *svfir, const std::string &path)
std::unique_ptr< cJSON, decltype(&cJSON_Delete)> autoJSON
bool jsonAddContentToObject(cJSON *obj, const char *name, const T &item)
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
SVFModuleWriter svfModuleWriter
cJSON * contentToJson(const SVFVar *var)
autoCStr generateJsonString()
cJSON * toJson(const T &container)
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)
SVFType * getSVFTypePtr(size_t id) const
ReaderPtrPool< SVFValue > svfValuePool
const cJSON * getFieldJson() const
StInfo * getStInfoPtr(size_t id) const
SVFValue * getSVFValuePtr(size_t id) const
const cJSON * svfModuleFieldJson
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
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
ReaderIDToObjMap< MemObj > memObjMap
const cJSON * symTabFieldJson
const cJSON * getFieldJson() const
void createObjs(const cJSON *symTabJson, MemObjCreator memObjCreator)
MemObj * getMemObjPtr(unsigned id) const
Bookkeeping class to keep track of the IDs of objects that doesn't have any ID. E....
const T * getPtr(size_t id) const
const std::vector< const T * > & getPool() const
size_t getID(const T *ptr)
std::vector< const T * > ptrPool
void saveID(const T *ptr)
Map< const T *, size_t > ptrToId
void reserve(size_t size)
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
llvm::IRBuilder IRBuilder
bool jsonAddItemToArray(cJSON *array, cJSON *item)
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
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.