7 #ifndef SYMBOLIC_EXPR_GRAPH_H
8 #define SYMBOLIC_EXPR_GRAPH_H
10 #include <llvm/IR/BasicBlock.h>
11 #include <llvm/IR/CallSite.h>
12 #include <llvm/IR/Constants.h>
13 #include <llvm/IR/Function.h>
14 #include <llvm/IR/InstIterator.h>
15 #include <llvm/IR/Instructions.h>
16 #include <llvm/IR/Value.h>
18 #include <llvm/Support/Casting.h>
19 #include <llvm/Support/FileSystem.h>
20 #include <llvm/Support/Format.h>
21 #include <llvm/Support/raw_ostream.h>
25 #include <unordered_map>
26 #include <unordered_set>
29 #include "Analysis/Alias/PathSensitiveAADriver/ProgramVal.h"
30 #include "IR/SEG/SEGValue.h"
31 #include "Transform/ValueComparator.h"
32 #include "Utils/ADT/MapIterators.h"
33 #include "Utils/ADT/kvec.h"
72 static bool EnableValueToString;
73 static bool EnableArithmeticFlow;
77 friend class SEGSerializer;
87 SEGOBJK_ArgumentBegin,
88 SEGOBJK_CommonArgument,
90 SEGOBJK_PseudoArgument,
93 SEGOBJK_CallSiteOutputBegin,
94 SEGOBJK_CallSiteCommonOutput,
95 SEGOBJK_CallSitePseudoOutput,
96 SEGOBJK_CallSiteOutputEnd,
100 SEGOBJK_PseudoReturn,
107 SEGOBJK_SimpleOperand,
109 SEGOBJK_CallSitePseudoInput,
110 SEGOBJK_CallSiteSummaryArgument,
111 SEGOBJK_CallSiteSummaryReturn,
117 SEGOBJK_BinaryWithIntConst,
119 SEGOBJK_SimpleOpcode,
130 SEGOBJK_SimpleSiteBegin,
132 SEGOBJK_DereferenceSite,
136 SEGOBJK_SimpleSiteEnd,
142 const SEGObjectKind ObjKind;
148 BasicBlock *ParentBasicBlock =
nullptr;
151 int64_t ObjIndex = -1;
154 int64_t SEGIndex = -1;
182 virtual Value *getLLVMDbgValue()
const {
return nullptr; }
191 virtual Instruction *getLLVMDbgInstruction()
const {
192 Value *val = getLLVMDbgValue();
193 if (val !=
nullptr) {
194 return dyn_cast<Instruction>(val);
200 SEGObjectKind getKind()
const {
return ObjKind; }
202 int64_t getSEGIndex()
const {
203 assert(SEGIndex != -1 &&
"Index should not be -1");
207 void setObjIndex(int64_t index) { ObjIndex = index; }
209 int64_t getObjIndex()
const {
210 assert(ObjIndex != -1 &&
"Index should not be -1");
214 const char *getKindName()
const;
216 BasicBlock *getParentBasicBlock()
const {
return ParentBasicBlock; }
218 Function *getParentFunction()
const {
return ParentBasicBlock->getParent(); }
223 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGObject &N);
227 LLVMValueIndexer *instance;
228 seg_cmp() : instance(LLVMValueIndexer::get()) {}
231 int64_t indexSEGA = A ? A->getSEGIndex() : -1;
232 int64_t indexSEGB = B ? B->getSEGIndex() : -1;
233 if (indexSEGA != indexSEGB || (indexSEGA == -1 && indexSEGB == -1)) {
234 return indexSEGA < indexSEGB;
236 int64_t indexA = A ? A->getObjIndex() : -1;
237 int64_t indexB = B ? B->getObjIndex() : -1;
238 return indexA < indexB;
245 friend class SEGSerializer;
246 friend class SEGHash;
255 void setDescription(std::string &Desc) { Description = Desc; }
261 std::string Description;
265 std::vector<SEGNodeBase *> Children;
268 std::map<const SEGNodeBase *, float, seg_cmp> Parents;
271 std::vector<SEGSiteBase *> UseSites;
272 std::set<SEGSiteBase *> UseSiteSet;
275 Type *LLVMType =
nullptr;
287 assert(Children.size() > I &&
288 "Invalid child index when querying SEG edges");
292 float getConfidence(
const SEGNodeBase *ParentNode)
const {
293 auto It = Parents.find(ParentNode);
294 assert(It != Parents.end() &&
295 "Invalid parent node when querying SEG edges");
299 unsigned getNumChildren()
const {
return Children.size(); }
301 unsigned getNumParents()
const {
return Parents.size(); }
303 void addChild(
SEGNodeBase *N,
float Confidence = 1.0f) {
304 Children.push_back(N);
305 N->Parents.insert(std::make_pair(
this, Confidence));
308 void eraseAllChildren() {
309 for (
auto *Child : Children) {
310 Child->Parents.erase(
this);
316 if (!UseSiteSet.count(U)) {
317 UseSiteSet.insert(U);
318 UseSites.push_back(U);
322 virtual bool isTerminalNode()
const {
return Children.empty(); }
326 bool containsParentNode(
const SEGNodeBase *N)
const {
327 return Parents.count(N);
330 const std::string &getDescription()
const {
return Description; }
333 virtual void dot(raw_fd_ostream &O)
const = 0;
335 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGNodeBase &N);
341 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator> It;
346 It = N->parent_end();
348 It = N->parent_begin();
354 : Node(VFIt.Node), It(VFIt.It) {}
358 this->Node = VFIt.Node;
388 ValueFlowIterator vflow_end()
const {
return {
this,
true}; }
390 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
391 parent_begin()
const {
392 return {Parents.begin()};
395 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
397 return {Parents.end()};
400 iterator_range<std::map<const SEGNodeBase *, float>::const_iterator>
402 return {Parents.begin(), Parents.end()};
405 std::vector<SEGNodeBase *>::const_iterator child_begin()
const {
406 return Children.begin();
409 std::vector<SEGNodeBase *>::const_iterator child_end()
const {
410 return Children.end();
413 iterator_range<std::vector<SEGNodeBase *>::const_iterator> children()
const {
414 return {Children.begin(), Children.end()};
417 std::map<const SEGNodeBase *, float>::const_iterator
418 parent_confidence_begin()
const {
419 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
423 std::map<const SEGNodeBase *, float>::const_iterator
424 parent_confidence_end()
const {
425 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
429 size_t child_size()
const {
return Children.size(); }
431 size_t parent_size()
const {
return Parents.size(); }
433 std::vector<SEGSiteBase *>::const_iterator use_site_begin()
const {
434 return UseSites.begin();
437 std::vector<SEGSiteBase *>::const_iterator use_site_end()
const {
438 return UseSites.end();
441 iterator_range<std::vector<SEGSiteBase *>::const_iterator> use_sites() {
442 return {UseSites.begin(), UseSites.end()};
445 size_t use_site_size()
const {
return UseSites.size(); }
448 static bool classof(
const SEGObject *N) {
449 return N->getKind() >= SEGOBJK_NodeBegin && N->getKind() <= SEGOBJK_NodeEnd;
460 Value *LLVMValue =
nullptr;
466 BasicBlock *BB,
bool fromDisk);
480 BasicBlock *BB,
bool fromDisk);
484 friend class SEGHash;
489 Value *getLLVMValue()
const {
return LLVMValue; }
491 SEGValue *getSEGValue()
const {
return segValue; }
493 void dot(raw_fd_ostream &O)
const override;
495 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
497 if (Value *Val = N.getLLVMValue()) {
500 Out << N.getDescription();
505 virtual Value *getLLVMDbgValue()
const override {
return getLLVMValue(); }
508 static bool classof(
const SEGObject *N) {
509 return N->getKind() >= SEGOBJK_OperandBegin &&
510 N->getKind() <= SEGOBJK_OperandEnd;
514 void initialize(Value *Val);
524 CK_URem = CK_BinaryBegin,
542 CK_BinaryEnd = CK_AShr,
545 CK_AddressCast = CK_CastBegin,
558 CK_CastEnd = CK_FP2UI,
572 CK_FFalse = CK_CmpBegin,
618 CodeKind getOpcode()
const {
return Opcode; }
620 virtual void dot(raw_fd_ostream &O)
const;
622 bool isCmpNode()
const {
623 return Opcode <= CK_CmpEnd && Opcode >= CK_CmpBegin;
626 bool isSignedCmp()
const {
return Opcode <= CK_ISLE && Opcode >= CK_ISGT; }
628 bool isUnSignedCmp()
const {
return Opcode <= CK_IULE && Opcode >= CK_IUGT; }
630 bool isFloatCmp()
const {
return Opcode <= CK_FTrue && Opcode >= CK_FFalse; }
632 bool isAddNode()
const {
return Opcode == CK_Add; }
634 bool isSubNode()
const {
return Opcode == CK_Sub; }
636 bool isGEPNode()
const {
return Opcode == CK_GetElmtPtr; }
638 bool isSelectNode()
const {
return Opcode == CK_Select; }
640 bool isCastNode()
const {
641 return Opcode <= CK_CastEnd && Opcode >= CK_CastBegin;
644 bool isBinaryNode()
const {
645 return Opcode <= CK_BinaryEnd && Opcode >= CK_BinaryBegin;
648 bool isExtractElmtNode()
const {
return Opcode == CK_ExtractElmt; }
650 bool isInsertElmtNode()
const {
return Opcode == CK_InsertElmt; }
652 bool isConcatNode()
const {
return Opcode == CK_Concat; }
655 static bool classof(
const SEGObject *N) {
656 return N->getKind() >= SEGOBJK_OpcodeBegin &&
657 N->getKind() <= SEGOBJK_OpcodeEnd;
660 static const char *getOpcodeName(CodeKind CK);
666 Instruction *User =
nullptr;
678 CallSite getLLVMCallSite()
const {
return CallSite(User); }
680 Instruction *getInstruction()
const {
return User; }
682 SEGValue *getSEGValue()
const {
return segValue; }
684 virtual Value *getLLVMDbgValue()
const override {
return getInstruction(); }
686 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
693 static bool classof(
const SEGObject *O) {
694 return O->getKind() >= SEGOBJK_SiteBegin && O->getKind() <= SEGOBJK_SiteEnd;
698 namespace FalconPlus {
702 class AbstractCondPtr;
711 friend class IntraFalcon;
712 friend class MantaIntraFalcon;
713 friend class PTGraph;
716 friend class SEGSerializer;
718 friend class FalconPlus::AbstractCond;
719 friend class FalconPlus::RegionCond;
720 friend class FalconPlus::IntraFalcon;
721 friend class FalconPlus::AbstractCondPtr;
722 friend class FalconPlus::FalconAA;
723 friend class FalconPlus::MemValueSet;
733 : CondNode(CN), BB(B), Cond(C) {}
735 bool operator<(
const CDGCond &RHS)
const {
736 return (CondNode < RHS.CondNode) ||
737 (CondNode == RHS.CondNode && BB < RHS.BB) ||
738 (CondNode == RHS.CondNode && BB == RHS.BB && Cond < RHS.Cond);
741 bool operator==(
const CDGCond &RHS)
const {
742 return CondNode == RHS.CondNode && BB == RHS.BB && Cond == RHS.Cond;
745 BasicBlock *getBB()
const {
return BB; }
750 Function *BaseFunc =
nullptr;
753 std::vector<SEGObject *> NodesList;
756 std::unordered_map<Value *, SEGOperandNode *> ValueNodesMap;
761 std::vector<std::pair<Value *, SEGOperandNode *>> ValueNodePairs;
765 std::set<SEGNodeBase *> NonValueNodes;
772 std::map<Instruction *, SEGSiteBase *> InstSiteMap;
773 std::vector<SEGCallSite *> CallSites;
782 std::map<BasicBlock *, std::set<CDGCond> *> BlockCondMap;
784 int64_t SEGIndex = -1;
788 int64_t getSEGIndex()
const {
return SEGIndex; }
790 template <
class T> T *getSEGObject(int64_t index) {
791 assert(index == -1 || (index >= 0 && index < NodesList.size()));
794 auto *Obj = NodesList[index];
803 kvec<SEGPseudoReturnNode *> PseudoReturns;
805 kvec<SEGCommonArgumentNode *> CommonArgumentNodes;
806 kvec<SEGPseudoArgumentNode *> PseudoArgumentNodes;
807 kvec<SEGVarArgumentNode *> VarArgumentNodes;
821 std::unordered_map<SEGNodeBase *, int> SummaryArgNodes;
822 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
823 SummaryArgNodesCache;
824 std::unordered_map<SEGNodeBase *, int> SummaryReturnNodes;
825 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
826 SummaryReturnNodesCache;
829 std::map<std::string, SEGOperandNode *> NameToPseudoArgNode;
830 std::unordered_map<std::string, SEGOperandNode *> NameToNonArgPseudoNode;
831 std::unordered_map<std::string, std::unique_ptr<PseudoVal>> PseudoValStorage;
843 void addSummaryArgNode(
SEGNodeBase *Node,
int APDepth);
845 void addSummaryReturnNode(
SEGNodeBase *Node,
int APDepth);
848 size_t getNumCommonArgument()
const {
return CommonArgumentNodes.size(); }
850 size_t getNumPseudoArgument()
const {
return PseudoArgumentNodes.size(); }
852 size_t getNumVarArgument()
const {
return VarArgumentNodes.size(); }
854 size_t getNumPseudoReturn()
const {
return PseudoReturns.size(); }
856 bool hasCommonReturnNode()
const {
866 return PseudoReturns[Index];
870 return CommonArgumentNodes[Index];
874 return PseudoArgumentNodes[Index];
878 return VarArgumentNodes[Index];
881 bool isSummaryArgument(
const SEGNodeBase *Node)
const;
885 int getSummaryArgumentAPDepth(
const SEGNodeBase *Node)
const;
889 std::unordered_set<SEGNodeBase *> *getSummaryArgument(
int APDepth)
const;
891 bool isSummaryReturn(
const SEGNodeBase *Node)
const;
895 int getSummaryReturnAPDepth(
const SEGNodeBase *Node)
const;
899 std::unordered_set<SEGNodeBase *> *getSummaryReturn(
int APDepth)
const;
906 bool isDirectlyPassedToCaller(
const SEGNodeBase *Node)
const;
907 bool isDirectlyPassedFromCaller(
const SEGNodeBase *Node)
const;
917 std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
918 std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
920 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
921 compound_regions_cache_and;
923 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
924 compound_regions_cache_or;
927 std::unordered_map<BasicBlock *, SEGRegionNode *> bb_region_cache;
930 void clearRegionNodeCache();
948 SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
952 template <
class OperandNodeTy>
953 OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
954 bool fromDisk =
false) {
956 assert(Val && !Val->getType()->isVoidTy());
957 assert((!(dyn_cast<Instruction>(Val)) ||
958 BB == ((Instruction *)Val)->getParent()) &&
959 "Incorrect BasicBlock detected");
961 auto It = ValueNodesMap.find(Val);
962 if (It != ValueNodesMap.end()) {
963 assert(isa<OperandNodeTy>(It->second));
964 return (OperandNodeTy *)It->second;
966 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
967 ValueNodePairs.push_back({Val, N});
968 ValueNodesMap[Val] = N;
975 template <
class OperandNodeTy>
977 clonePseudoVal(
const PseudoVal *Arg,
978 std::function<OperandNodeTy *(
const PseudoVal *)> Proc) {
979 const std::string &ArgName = Arg->getName();
980 auto ClonedArg = std::unique_ptr<PseudoVal>(Arg->clone());
981 auto *ArgNode = Proc(ClonedArg.get());
983 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
984 NameToPseudoArgNode.insert(std::make_pair(ArgName, ArgNode));
986 NameToNonArgPseudoNode.insert(std::make_pair(ArgName, ArgNode));
989 assert(!PseudoValStorage.count(ArgName));
990 PseudoValStorage.insert({ArgName, std::move(ClonedArg)});
994 template <
class OperandNodeTy>
996 findOrClonePseudoVal(
const PseudoVal *Arg,
997 std::function<OperandNodeTy *(
const PseudoVal *)> Proc) {
998 const std::string &ArgName = Arg->getName();
999 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
1000 if (NameToPseudoArgNode.count(ArgName)) {
1001 return cast<OperandNodeTy>(NameToPseudoArgNode.at(ArgName));
1004 if (NameToNonArgPseudoNode.count(ArgName)) {
1006 std::is_base_of<SEGOperandNode, OperandNodeTy>::value,
1007 "OperandNodeTy must be a derived class of SEGOperandNode.");
1008 return cast<OperandNodeTy>(NameToNonArgPseudoNode.at(ArgName));
1012 return clonePseudoVal<OperandNodeTy>(Arg, Proc);
1018 void finalizePseudoArgumentNodes();
1019 SEGOperandNode *findOrCreateSimpleOperandFromPseudoVal(
const PseudoVal *Arg,
1024 BasicBlock *BB, CallSite CS,
1031 template <
class OperandNodeTy>
1032 OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
1033 bool fromDisk =
false) {
1035 assert(Val && !Val->getType()->isVoidTy());
1036 assert((!(dyn_cast<Instruction>(Val)) ||
1037 BB == ((Instruction *)Val)->getParent()) &&
1038 "Incorrect BasicBlock detected");
1040 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
1041 ValueNodesMap[Val] = N;
1042 ValueNodePairs.push_back({Val, N});
1046 template <
class OperandNodeTy>
1047 OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB,
1048 bool fromDisk =
false) {
1051 auto *Ret =
new OperandNodeTy(Ty,
this, BB, fromDisk);
1052 NonValueNodes.insert(Ret);
1058 template <
class SiteTy>
1059 SiteTy *findOrCreateSite(Instruction *I,
bool fromDisk =
false) {
1062 auto It = InstSiteMap.find(I);
1063 if (It != InstSiteMap.end()) {
1064 assert(isa<SiteTy>(It->second));
1065 return (SiteTy *)It->second;
1067 SiteTy *N =
new SiteTy(I,
this, fromDisk);
1071 CallSites.push_back(CS);
1082 createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1083 Instruction *Callsite,
int APDepth,
1084 bool fromDisk =
false);
1090 createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1091 Instruction *Callsite,
float Confidence,
1092 bool fromDisk =
false);
1096 findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1097 CallSite CS, Function *Callee,
bool IsCommon);
1100 BasicBlock *BB, CallSite CS,
1103 bool fromDisk =
false);
1107 findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1108 CallSite CS, Function *Callee,
1109 bool fromDisk =
false);
1112 SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1113 Value *StoreVal, BasicBlock *BB,
1114 bool fromDisk =
false);
1118 bool cond =
false,
bool fromDisk =
false);
1150 BasicBlock *BB,
const kvec<SEGNodeBase *> &,
1151 bool fromDisk =
false);
1156 uint64_t TSz,
bool fromDisk =
false);
1162 bool fromDisk =
false);
1165 void addBlockCond(BasicBlock *CurrBB,
SEGNodeBase *BrNode, BasicBlock *DepBB,
1172 Function *getBaseFunc()
const {
return BaseFunc; }
1176 template <
class SiteTy> SiteTy *
findSite(Instruction *I)
const {
1179 auto It = InstSiteMap.find(I);
1180 if (It != InstSiteMap.end()) {
1182 return dyn_cast<SiteTy>(It->second);
1195 Instruction *I = dyn_cast<Instruction>(sValue->
getValue());
1198 auto It = InstSiteMap.find(I);
1199 if (It != InstSiteMap.end()) {
1201 return dyn_cast<SiteTy>(It->second);
1236 auto It = BlockCondMap.find(BB);
1237 if (It != BlockCondMap.end()) {
1244 void dot(
const char *FileName)
const;
1247 void dot(std::vector<const SEGNodeBase *> Srcs,
const char *FileName)
const;
1261 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1262 value_node_begin()
const {
1263 return ValueNodesMap.begin();
1266 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1267 value_node_end()
const {
1268 return ValueNodesMap.end();
1271 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1272 value_node_pair_begin()
const {
1273 return ValueNodePairs.begin();
1276 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1277 value_node_pair_end()
const {
1278 return ValueNodePairs.end();
1281 std::set<SEGNodeBase *>::const_iterator non_value_node_begin()
const {
1282 return NonValueNodes.begin();
1285 std::set<SEGNodeBase *>::const_iterator non_value_node_end()
const {
1286 return NonValueNodes.end();
1289 std::map<Instruction *, SEGSiteBase *>::const_iterator
1290 inst_site_begin()
const {
1291 return InstSiteMap.begin();
1294 std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end()
const {
1295 return InstSiteMap.end();
1298 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1299 store_mem_node_begin()
const {
1300 return StoreMemNodesMap.begin();
1303 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1304 store_mem_node_end()
const {
1305 return StoreMemNodesMap.end();
1308 std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin()
const {
1309 return InstSiteMap.begin();
1312 std::map<Instruction *, SEGSiteBase *>::const_iterator site_end()
const {
1313 return InstSiteMap.end();
1316 std::vector<SEGObject *>::const_iterator node_begin()
const {
1317 return NodesList.begin();
1320 std::vector<SEGObject *>::const_iterator node_end()
const {
1321 return NodesList.end();
1328 const kvec<SEGPseudoReturnNode *> &PseudoRets;
1332 const kvec<SEGPseudoReturnNode *> &PRs)
1333 : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1336 : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1370 ReturnIterator return_end()
const {
1371 return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1372 CommonReturn, PseudoReturns);
1375 ReturnIterator pseudo_return_begin()
const {
1376 size_t StartIndex = getCommonReturn() ? 1 : 0;
1377 return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1380 ReturnIterator pseudo_return_end()
const {
return return_end(); }
1385 const kvec<SEGCommonArgumentNode *> &CommonArgs;
1386 const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1387 const kvec<SEGVarArgumentNode *> &VarArgs;
1391 const kvec<SEGPseudoArgumentNode *> &PA,
1392 const kvec<SEGVarArgumentNode *> &VA)
1393 : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1396 : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1397 VarArgs(It.VarArgs) {}
1411 if (I < (
size_t)CommonArgs.size()) {
1415 if (I < (
size_t)(CommonArgs.size() + PseudoArgs.size())) {
1420 (
size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1422 VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1435 ArgumentIterator arg_end()
const {
1437 getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1438 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1442 ArgumentIterator common_arg_begin()
const {
return arg_begin(); }
1444 ArgumentIterator common_arg_end()
const {
1445 size_t NumArgs = getNumCommonArgument();
1446 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1450 ArgumentIterator pseudo_arg_begin()
const {
return common_arg_end(); }
1452 ArgumentIterator pseudo_arg_end()
const {
1453 size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1454 return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1458 ArgumentIterator var_arg_begin()
const {
return pseudo_arg_end(); }
1460 ArgumentIterator var_arg_end()
const {
return arg_end(); }
1462 typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1463 SEGCallSiteIterator seg_callsite_begin()
const {
return CallSites.begin(); }
1465 SEGCallSiteIterator seg_callsite_end()
const {
return CallSites.end(); }