29 switch (compositeType->getTag())
31 case dwarf::DW_TAG_array_type:
35 case dwarf::DW_TAG_class_type:
36 case dwarf::DW_TAG_structure_type:
50 if (fm->getTag() == dwarf::DW_TAG_member && !fm->isStaticMember())
58 if (firstMember !=
nullptr)
70 case dwarf::DW_TAG_union_type:
76 for (
DINode *field : fields)
79 DIDerivedType *firstMember = SVFUtil::dyn_cast<DIDerivedType>(field);
80 assert(firstMember !=
nullptr &&
"DCHG: expected member type");
89 case dwarf::DW_TAG_enumeration_type:
93 assert(
false &&
"DCHGraph::buildCHG: unexpected CompositeType tag.");
99 switch (derivedType->getTag())
101 case dwarf::DW_TAG_inheritance:
103 assert(SVFUtil::isa<DIType>(derivedType->getScope()) &&
"inheriting from non-type?");
104 DCHEdge *edge =
addEdge(SVFUtil::dyn_cast<DIType>(derivedType->getScope()),
107 edge->
setOffset(derivedType->getOffsetInBits());
110 case dwarf::DW_TAG_member:
111 case dwarf::DW_TAG_friend:
114 case dwarf::DW_TAG_typedef:
117 case dwarf::DW_TAG_pointer_type:
118 case dwarf::DW_TAG_ptr_to_member_type:
119 case dwarf::DW_TAG_reference_type:
120 case dwarf::DW_TAG_rvalue_reference_type:
123 case dwarf::DW_TAG_const_type:
124 case dwarf::DW_TAG_atomic_type:
125 case dwarf::DW_TAG_volatile_type:
126 case dwarf::DW_TAG_restrict_type:
129 assert(
false &&
"DCHGraph::buildCHG: unexpected DerivedType tag.");
140 assert(typedefType && typedefType->getTag() == dwarf::DW_TAG_typedef);
144 std::vector<const DIDerivedType *> typedefs;
146 while (typedefType !=
nullptr && typedefType->getTag() == dwarf::DW_TAG_typedef)
148 const DIDerivedType *typedefDerivedType = SVFUtil::dyn_cast<DIDerivedType>(typedefType);
150 typedefs.push_back(typedefDerivedType);
153 typedefType = typedefDerivedType->getBaseType();
156 const DIType *baseType = typedefType;
170 for (Module::const_global_iterator gvI = M.global_begin(); gvI != M.global_end(); ++gvI)
173 const GlobalVariable *gv = SVFUtil::dyn_cast<const GlobalVariable>(&*gvI);
174 if (gv ==
nullptr)
continue;
178 assert(
type &&
"DCHG::buildVTables: bad metadata for ctir.vt");
185 for (
unsigned nthVtbl = 0; nthVtbl < vtbls->getNumOperands(); ++nthVtbl)
187 const ConstantArray *vtbl = SVFUtil::dyn_cast<ConstantArray>(vtbls->getOperand(nthVtbl));
188 assert(vtbl &&
"Element of vtbl struct not an array");
190 std::vector<const Function* > &vfns = node->
getVfnVector(nthVtbl);
196 for (
unsigned cN = 0; cN < vtbl->getNumOperands(); ++cN)
199 if (SVFUtil::isa<ConstantPointerNull>(c))
206 assert(ce &&
"non-ConstantExpr, non-ConstantPointerNull in vtable?");
207 if (ce->getOpcode() == Instruction::BitCast)
210 const Function* vfn = SVFUtil::dyn_cast<Function>(ce->getOperand(0));
229 if (cacheMap.find(
type) != cacheMap.end())
231 return cacheMap[
type];
254 const NodeBS &cchildren =
cha(edge->getSrcNode()->getDIType(), firstField);
256 for (
NodeID cchild : cchildren)
265 return cacheMap[
type];
271 assert(
type &&
"DCHG::flatten: canon type of struct/class is not struct/class");
281 assert(
type !=
nullptr
282 && (
type->getTag() == dwarf::DW_TAG_class_type
283 ||
type->getTag() == dwarf::DW_TAG_structure_type)
284 &&
"DCHG::flatten: expected a class/struct");
287 std::vector<const DIDerivedType *> fields;
289 for (
unsigned i = 0; i < fieldsDINA.size(); ++i)
291 if (
const DIDerivedType *dt = SVFUtil::dyn_cast<DIDerivedType>(fieldsDINA[i]))
294 fields.push_back(dt);
299 std::sort(fields.begin(), fields.end(),
301 { return a->getOffsetInBits() < b->getOffsetInBits(); });
305 assert((mt->getTag() == dwarf::DW_TAG_member || mt->getTag() == dwarf::DW_TAG_inheritance)
306 &&
"DCHG: expected member/inheritance");
308 const DIType *fieldType = mt->getBaseType();
309 if (fieldType->getTag() == dwarf::DW_TAG_structure_type
310 || fieldType->getTag() == dwarf::DW_TAG_class_type)
312 flatten(SVFUtil::dyn_cast<DICompositeType>(fieldType));
320 else if (fieldType->getTag() == dwarf::DW_TAG_array_type)
322 const DICompositeType *arrayType = SVFUtil::dyn_cast<DICompositeType>(fieldType);
323 const DIType *baseType = arrayType->getBaseType();
324 if (
const DICompositeType *cbt = SVFUtil::dyn_cast<DICompositeType>(baseType))
347 if (t ==
nullptr)
return false;
348 return t->getTag() == dwarf::DW_TAG_array_type
349 || t->getTag() == dwarf::DW_TAG_structure_type
350 || t->getTag() == dwarf::DW_TAG_class_type;
364 if (
type->getTag() == dwarf::DW_TAG_array_type)
383 for (
unsigned i = 0; i < fields.size(); ++i)
386 if (
const DIDerivedType *mt = SVFUtil::dyn_cast<DIDerivedType>(fields[i]))
388 const DIType *ft = mt->getBaseType();
427 assert(md !=
nullptr &&
"Missing type metadata at virtual callsite");
428 DIType *diType = SVFUtil::dyn_cast<DIType>(md);
429 assert(diType !=
nullptr &&
"Incorrect metadata type at virtual callsite");
442 edge =
new DCHEdge(src, dst, et);
457 DCHNode *node = edge->getDstNode();
459 if (node == dst && edgeType == et)
461 assert(SVFUtil::isa<DCHEdge>(edge) &&
"Non-DCHEdge in DCHNode edge set.");
475 finder.processModule(M);
481 const DIType *charType =
nullptr;
494 if (
const DIBasicType *basicType = SVFUtil::dyn_cast<DIBasicType>(
type))
496 if (basicType->getEncoding() == dwarf::DW_ATE_unsigned_char
497 || basicType->getEncoding() == dwarf::DW_ATE_signed_char)
508 else if (
const DIDerivedType *derivedType = SVFUtil::dyn_cast<DIDerivedType>(
type))
518 assert(
false &&
"DCHGraph::buildCHG: unexpected DIType.");
525 if (
extended && charType !=
nullptr)
533 if (nodeI->second->getDIType() !=
nullptr
534 && nodeI->second->getOutEdges().size() == 0)
582 vtblSet.insert(vtbl);
600 assert(
hasNode(
type) &&
"trying to get vtbl for type not in graph");
602 std::vector<std::vector<const Function* >> allVfns = node->
getVfnVectors();
603 for (std::vector<const Function* > vfnV : allVfns)
606 if (idx >= vfnV.size())
613 if (callsite->
arg_size() == callee->arg_size() || (callsite->
isVarArg() && callee->isVarArg()))
628 size_t suffixPos = calleeName.rfind(suffix);
629 if (suffixPos != std::string::npos)
631 calleeName.erase(suffixPos, suffix.size());
638 if (funName.size() == 0)
642 else if (funName[0] ==
'~')
654 if (calleeName[0] ==
'~')
665 if (funName.compare(calleeName) == 0)
679 assert(
hasNode(
a) &&
hasNode(
b) &&
"DCHG: isBase query for non-existent node!");
688 assert(f &&
b &&
"DCHG::isFieldOf: given nullptr!");
692 if (f ==
b)
return true;
694 if (
b->getTag() == dwarf::DW_TAG_array_type ||
b->getTag() == dwarf::DW_TAG_pointer_type)
696 const DIType *baseType =
nullptr;
697 if (
const DICompositeType *arrayType = SVFUtil::dyn_cast<DICompositeType>(
b))
699 baseType = arrayType->getBaseType();
701 else if (
const DIDerivedType *ptrType = SVFUtil::dyn_cast<DIDerivedType>(
b))
703 baseType = ptrType->getBaseType();
705 assert(baseType &&
"DCHG::isFieldOf: baseType is neither DIComposite nor DIDerived!");
708 return f == baseType || (baseType !=
nullptr &&
isFieldOf(f, baseType));
710 else if (
b->getTag() == dwarf::DW_TAG_class_type
711 ||
b->getTag() == dwarf::DW_TAG_structure_type)
714 return std::find(fields.begin(), fields.end(), f) != fields.end();
725 const DIType *unstrippedT = t;
736 if (unstrippedT != t)
748 if (
teq(t, canonType))
769 || SVFUtil::isa<DIBasicType>(t)
770 || SVFUtil::isa<DISubroutineType>(t))
775 unsigned tag = t->getTag();
777 if ( tag == dwarf::DW_TAG_const_type
778 || tag == dwarf::DW_TAG_atomic_type
779 || tag == dwarf::DW_TAG_volatile_type
780 || tag == dwarf::DW_TAG_restrict_type
781 || tag == dwarf::DW_TAG_typedef)
784 const DIDerivedType *dt = SVFUtil::dyn_cast<DIDerivedType>(t);
785 assert(t &&
"DCHG: expected DerivedType");
786 t = dt->getBaseType();
788 else if ( tag == dwarf::DW_TAG_array_type
789 || tag == dwarf::DW_TAG_class_type
790 || tag == dwarf::DW_TAG_structure_type
791 || tag == dwarf::DW_TAG_union_type
792 || tag == dwarf::DW_TAG_enumeration_type
793 || tag == dwarf::DW_TAG_member
794 || tag == dwarf::DW_TAG_pointer_type
795 || tag == dwarf::DW_TAG_ptr_to_member_type
796 || tag == dwarf::DW_TAG_reference_type
797 || tag == dwarf::DW_TAG_rvalue_reference_type)
802 else if ( tag == dwarf::DW_TAG_inheritance
803 || tag == dwarf::DW_TAG_friend)
805 assert(
false &&
"DCHG: unexpected tag when stripping qualifiers");
809 assert(
false &&
"DCHG: unhandled tag when stripping qualifiers");
819 if (t->getTag() == dwarf::DW_TAG_array_type)
839 if (t1 ==
nullptr || t2 ==
nullptr)
847 if (SVFUtil::isa<DIBasicType>(t1) && SVFUtil::isa<DIBasicType>(t2))
849 const DIBasicType *b1 = SVFUtil::dyn_cast<DIBasicType>(t1);
850 const DIBasicType *b2 = SVFUtil::dyn_cast<DIBasicType>(t2);
852 unsigned enc1 = b1->getEncoding();
853 unsigned enc2 = b2->getEncoding();
854 bool okayEnc = ((enc1 == dwarf::DW_ATE_signed || enc1 == dwarf::DW_ATE_unsigned || enc1 == dwarf::DW_ATE_boolean)
855 && (enc2 == dwarf::DW_ATE_signed || enc2 == dwarf::DW_ATE_unsigned || enc2 == dwarf::DW_ATE_boolean))
857 (enc1 == dwarf::DW_ATE_float && enc2 == dwarf::DW_ATE_float)
859 ((enc1 == dwarf::DW_ATE_signed_char || enc1 == dwarf::DW_ATE_unsigned_char)
861 (enc2 == dwarf::DW_ATE_signed_char || enc2 == dwarf::DW_ATE_unsigned_char));
863 if (!okayEnc)
return false;
866 return t1->getSizeInBits() == t2->getSizeInBits()
867 && t1->getAlignInBits() == t2->getAlignInBits();
873 if ((SVFUtil::isa<DIDerivedType>(t1) || t1->getTag() == dwarf::DW_TAG_array_type)
874 && (SVFUtil::isa<DIDerivedType>(t2) || t2->getTag() == dwarf::DW_TAG_array_type))
876 const DIType *base1, *base2;
879 if (
const DIDerivedType *d1 = SVFUtil::dyn_cast<DIDerivedType>(t1))
881 base1 = d1->getBaseType();
886 assert(c1 &&
"teq: bad cast for array type");
887 base1 = c1->getBaseType();
891 if (
const DIDerivedType *d2 = SVFUtil::dyn_cast<DIDerivedType>(t2))
893 base2 = d2->getBaseType();
898 assert(c2 &&
"teq: bad cast for array type");
899 base2 = c2->getBaseType();
904 return teq(base1, base2);
907 if (SVFUtil::isa<DICompositeType>(t1) && SVFUtil::isa<DICompositeType>(t2))
912 if (ct1->getTag() != ct2->getTag())
return false;
915 if (ct1->getTag() == dwarf::DW_TAG_enumeration_type)
921 if (ct1->getTag() == dwarf::DW_TAG_class_type)
923 return ct1->getIdentifier() == ct2->getIdentifier();
929 return ct1->getName() == ct2->getName()
930 && ct1->getFile() == ct2->getFile()
931 && ct1->getLine() == ct2->getLine();
949 if (f ==
b)
return true;
952 assert(node &&
"DCHG::isFirstField: node not found");
959 if (edge->getSrcNode()->getDIType() ==
b)
return true;
960 if (
isFirstField(edge->getSrcNode()->getDIType(),
b))
return true;
969 std::stringstream ss;
976 if (
const DIBasicType *bt = SVFUtil::dyn_cast<DIBasicType>(t))
978 ss << bt->getName().str();
980 else if (
const DIDerivedType *dt = SVFUtil::dyn_cast<DIDerivedType>(t))
982 if (dt->getName() ==
"__vtbl_ptr_type")
984 ss <<
"(vtbl * =) __vtbl_ptr_type";
986 else if (dt->getTag() == dwarf::DW_TAG_const_type)
990 else if (dt->getTag() == dwarf::DW_TAG_volatile_type)
992 ss <<
"volatile " <<
diTypeToStr(dt->getBaseType());
994 else if (dt->getTag() == dwarf::DW_TAG_restrict_type)
996 ss <<
"restrict " <<
diTypeToStr(dt->getBaseType());
998 else if (dt->getTag() == dwarf::DW_TAG_atomic_type)
1000 ss <<
"atomic " <<
diTypeToStr(dt->getBaseType());
1002 else if (dt->getTag() == dwarf::DW_TAG_pointer_type)
1006 else if (dt->getTag() == dwarf::DW_TAG_ptr_to_member_type)
1009 <<
" " <<
diTypeToStr(SVFUtil::dyn_cast<DIType>(dt->getExtraData())) <<
"::*";
1011 else if (dt->getTag() == dwarf::DW_TAG_reference_type)
1015 else if (dt->getTag() == dwarf::DW_TAG_rvalue_reference_type)
1019 else if (dt->getTag() == dwarf::DW_TAG_typedef)
1021 ss << dt->getName().str() <<
"->" <<
diTypeToStr(dt->getBaseType());
1024 else if (
const DICompositeType *ct = SVFUtil::dyn_cast<DICompositeType>(t))
1026 if (ct->getTag() == dwarf::DW_TAG_class_type
1027 || ct->getTag() == dwarf::DW_TAG_structure_type
1028 || ct->getTag() == dwarf::DW_TAG_union_type)
1031 if (ct->getTag() == dwarf::DW_TAG_class_type)
1035 else if (ct->getTag() == dwarf::DW_TAG_structure_type)
1039 else if (ct->getTag() == dwarf::DW_TAG_union_type)
1046 if (ct->getName() !=
"")
1048 ss << ct->getName().str();
1056 for (
unsigned i = 0; i < fields.size(); ++i)
1060 if (
const DISubprogram *sp = SVFUtil::dyn_cast<DISubprogram>(fields[i]))
1062 ss << sp->getName().str();
1064 else if (
const DIDerivedType *mt = SVFUtil::dyn_cast<DIDerivedType>(fields[i]))
1066 assert(mt->getTag() == dwarf::DW_TAG_member &&
"DCHG: expected member");
1070 if (i != fields.size() - 1)
1079 else if (ct->getTag() == dwarf::DW_TAG_array_type)
1083 for (
unsigned i = 0; i < sizes.size(); ++i)
1085 DISubrange *sr = SVFUtil::dyn_cast<DISubrange>(sizes[0]);
1086 assert(sr !=
nullptr &&
"DCHG: non-subrange as array element?");
1090 count = ci->getSExtValue();
1093 ss <<
"[" <<
count <<
"]";
1096 else if (ct->getTag() == dwarf::DW_TAG_enumeration_type)
1100 else if (ct->getTag() == dwarf::DW_TAG_union_type)
1105 else if (
const DISubroutineType *st = SVFUtil::dyn_cast<DISubroutineType>(t))
1110 if (types.size() == 1)
1116 for (
unsigned i = 1; i < types.size(); ++i)
1119 if (i + 1 != types.size())
1129 ss << st->getName().str();
1142 static const std::string line =
"-------------------------------------\n";
1143 static const std::string thickLine =
"=====================================\n";
1144 static const size_t singleIndent = 2;
1146 size_t currIndent = 0;
1148 unsigned numStructs = 0;
1149 unsigned largestStruct = 0;
1153 nodes.insert(it->first);
1158 if (*
nodes.begin() != id)
1167 && (node->
getDIType()->getTag() == dwarf::DW_TAG_class_type
1169 node->
getDIType()->getTag() == dwarf::DW_TAG_structure_type))
1173 largestStruct = numFields > largestStruct ? numFields : largestStruct;
1176 currIndent += singleIndent;
1178 currIndent += singleIndent;
1179 const std::vector<std::vector<const Function* >> &vfnVectors = node->
getVfnVectors();
1180 for (
unsigned i = 0; i < vfnVectors.size(); ++i)
1183 currIndent += singleIndent;
1184 for (
unsigned j = 0; j < vfnVectors[i].size(); ++j)
1191 currIndent -= singleIndent;
1195 if (vfnVectors.size() == 0)
1200 currIndent -= singleIndent;
1203 currIndent += singleIndent;
1209 arrow =
"--inheritance-->";
1213 arrow =
"--first-field-->";
1217 arrow =
"---instance---->";
1221 arrow =
"---standard---->";
1225 arrow =
"----unknown---->";
1229 << arrow <<
" [ " <<
diTypeToStr(edge->getDstNode()->getDIType()) <<
" ]\n";
1237 currIndent -= singleIndent;
1241 currIndent += singleIndent;
1247 if (tdef !=
nullptr)
1249 typedefName = tdef->getName().str();
1255 if (typedefs.size() == 0)
1260 currIndent -= singleIndent;
1262 currIndent -= singleIndent;
1271 SVFUtil::outs() <<
"Largest struct : " << largestStruct <<
" fields\n";
static std::string indent(size_t n)
const std::string & getFunNameOfVirtualCall() const
s32_t getFunIdxInVtable() const
void setOffset(u32_t offset)
const DIType * getCSStaticType(CallBase *cs) const
Retrieves the metadata associated with a virtual callsite.
const DIType * getCanonicalType(const DIType *t)
const NodeBS & cha(const DIType *type, bool firstField)
Returns a set of all children of type (CHA). Also gradually builds chaMap.
void buildVTables(const SVFModule &module)
Finds all defined virtual functions and attaches them to nodes.
static const DIType * stripQualifiers(const DIType *)
Returns the DIType beneath the qualifiers. Does not strip away "DW_TAG_members".
void handleDIDerivedType(const DIDerivedType *derivedType)
Construction helper to process DIDerivedTypes.
DCHEdge * addEdge(const DIType *t1, const DIType *t2, DCHEdge::GEdgeKind et)
Creates an edge between from t1 to t2.
bool isFirstField(const DIType *f, const DIType *b)
static std::string diTypeToStr(const DIType *)
Returns a human-readable version of the DIType.
void handleDICompositeType(const DICompositeType *compositeType)
Construction helper to process DICompositeTypes.
Map< const CallICFGNode *, VFunSet > csCHAMap
Maps callsites to a set of potential virtual functions based on CHA.
bool hasNode(const DIType *type)
Checks if a node exists for type.
Map< const DIType *, NodeBS > chaFFMap
Maps types to all children but also considering first field.
Map< const DIType *, const DIType * > canonicalTypeMap
Maps types to their canonical type (many-to-one).
void handleDISubroutineType(const DISubroutineType *subroutineType)
Construction helper to process DISubroutineTypes.
virtual void getVFnsFromVtbls(const CallICFGNode *cs, const VTableSet &vtbls, VFunSet &virtualFunctions) override
static const DIType * stripArray(const DIType *)
Returns the DIType beneath all qualifiers and arrays.
void handleTypedef(const DIType *typedefType)
Attaches the typedef(s) to the base node.
virtual void buildCHG(bool extend)
DCHEdge * hasEdge(const DIType *t1, const DIType *t2, DCHEdge::GEdgeKind et)
Returns the edge between t1 and t2 if it exists, returns nullptr otherwise.
NodeID numTypes
Number of types (nodes) in the graph.
void handleDIBasicType(const DIBasicType *basicType)
Construction helper to process DIBasicTypes.
virtual const VTableSet & getCSVtblsBasedonCHA(const CallICFGNode *cs) override
void gatherAggs(const DICompositeType *type)
Populates containingAggs for type and all its elements.
DCHNode * getNode(const DIType *type)
Returns the node for type (nullptr if it doesn't exist).
static bool isAgg(const DIType *t)
DCHNode * getOrCreateNode(const DIType *type)
Creates a node from type, or returns it if it exists.
Map< const DIType *, VTableSet > vtblCHAMap
Maps types to a set with their vtable and all their children's.
bool extended
Whether this CHG is an extended CHG (first-field). Set by buildCHG.
Map< const DIType *, Set< const DIType * > > containingAggs
Maps aggregate types to all the aggregate types it transitively contains.
virtual bool isBase(const DIType *a, const DIType *b, bool firstField)
void flatten(const DICompositeType *type)
Populates fieldTypes for type and all its elements.
virtual const VFunSet & getCSVFsBasedonCHA(const CallICFGNode *cs) override
static bool teq(const DIType *t1, const DIType *t2)
Map< const DIType *, std::vector< const DIType * > > fieldTypes
Maps types to their flattened fields' types.
Map< const DIType *, NodeBS > chaMap
Maps types to all children (i.e. CHA).
Map< const DIType *, DCHNode * > diTypeToNodeMap
Maps DITypes to their nodes.
const std::vector< const DIType * > & getFieldTypes(const DIType *base)
Returns a vector of the types of all fields in base.
virtual bool isFieldOf(const DIType *f, const DIType *b)
Returns true if f is a field of b (fields from getFieldTypes).
Map< const SVFGlobalValue *, const DIType * > vtblToTypeMap
Maps VTables to the DIType associated with them.
Set< const DIType * > canonicalTypes
Set of all possible canonical types (i.e. values of canonicalTypeMap).
const DIType * getDIType(void) const
std::vector< const Function * > & getVfnVector(unsigned n)
Return the nth virtual function vector in the vtable.
const std::vector< std::vector< const Function * > > & getVfnVectors(void) const
Returns the vector of virtual function vectors.
void addTypedef(const DIDerivedType *diTypedef)
const Set< const DIDerivedType * > & getTypedefs(void) const
void setVTable(const SVFGlobalValue *vtbl)
void addGNode(NodeID id, NodeType *node)
Add a Node.
iterator begin()
Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
IDToNodeMapTy::const_iterator const_iterator
IDToNodeMapTy::iterator iterator
Node Iterators.
const GEdgeSetTy & getOutEdges() const
bool addIncomingEdge(EdgeType *inEdge)
Add incoming and outgoing edges.
bool addOutgoingEdge(EdgeType *outEdge)
const GEdgeSetTy & getInEdges() const
SVFGlobalValue * getSVFGlobalValue(const GlobalValue *g) const
static LLVMModuleSet * getLLVMModuleSet()
static const Option< bool > PrintDCHG
NodeID getId() const
Get ID.
bool test(unsigned Idx) const
const SVFFunction * getFunction(const std::string &name)
Get the corresponding Function based on its name.
std::ostream & outs()
Overwrite llvm::outs()
const std::string derefMDName
const std::string vtMDName
struct DemangledName demangle(const std::string &name)
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
llvm::DISubroutineType DISubroutineType
llvm::GlobalVariable GlobalVariable
llvm::DINodeArray DINodeArray
llvm::ConstantStruct ConstantStruct
Set< const SVFGlobalValue * > VTableSet
llvm::ConstantArray ConstantArray
llvm::DebugInfoFinder DebugInfoFinder
iter_range< typename GenericGraphTraits< GraphType >::ChildIteratorType > children(const typename GenericGraphTraits< GraphType >::NodeRef &G)
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
llvm::DIDerivedType DIDerivedType
llvm::DISubprogram DISubprogram
llvm::ConstantExpr ConstantExpr
llvm::DISubrange DISubrange
llvm::DITypeRefArray DITypeRefArray
Set< const SVFFunction * > VFunSet
llvm::DIBasicType DIBasicType
llvm::DICompositeType DICompositeType
llvm::ConstantInt ConstantInt
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set