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 std::string SEGIndex;
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 std::string getSEGIndex()
const {
return SEGIndex; }
204 void setObjIndex(int64_t index) { ObjIndex = index; }
206 int64_t getObjIndex()
const {
207 assert(ObjIndex != -1 &&
"Index should not be -1");
211 const char *getKindName()
const;
213 void setParentBasicBlock(BasicBlock *BB) { this->ParentBasicBlock = BB; }
215 BasicBlock *getParentBasicBlock()
const {
return ParentBasicBlock; }
217 Function *getParentFunction()
const {
return ParentBasicBlock->getParent(); }
222 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGObject &N);
227 std::string indexSEGA = A ? A->getSEGIndex() :
"";
228 std::string indexSEGB = B ? B->getSEGIndex() :
"";
229 if (indexSEGA != indexSEGB || (indexSEGA.empty() && indexSEGB.empty())) {
230 return indexSEGA < indexSEGB;
232 int64_t indexA = A ? A->getObjIndex() : -1;
233 int64_t indexB = B ? B->getObjIndex() : -1;
234 return indexA < indexB;
241 friend class SEGSerializer;
242 friend class SEGHash;
251 void setDescription(std::string &Desc) { Description = Desc; }
257 std::string Description;
261 std::vector<SEGNodeBase *> Children;
264 std::map<const SEGNodeBase *, float, seg_cmp> Parents;
267 std::vector<SEGSiteBase *> UseSites;
268 std::set<SEGSiteBase *> UseSiteSet;
271 Type *LLVMType =
nullptr;
283 assert(Children.size() > I &&
284 "Invalid child index when querying SEG edges");
288 float getConfidence(
const SEGNodeBase *ParentNode)
const {
289 auto It = Parents.find(ParentNode);
290 assert(It != Parents.end() &&
291 "Invalid parent node when querying SEG edges");
295 unsigned getNumChildren()
const {
return Children.size(); }
297 unsigned getNumParents()
const {
return Parents.size(); }
299 void addChild(
SEGNodeBase *N,
float Confidence = 1.0f) {
300 Children.push_back(N);
301 N->Parents.insert(std::make_pair(
this, Confidence));
304 void eraseAllChildren() {
305 for (
auto *Child : Children) {
306 Child->Parents.erase(
this);
312 if (!UseSiteSet.count(U)) {
313 UseSiteSet.insert(U);
314 UseSites.push_back(U);
318 virtual bool isTerminalNode()
const {
return Children.empty(); }
322 bool containsParentNode(
const SEGNodeBase *N)
const {
323 return Parents.count(N);
326 const std::string &getDescription()
const {
return Description; }
329 virtual void dot(raw_fd_ostream &O)
const = 0;
331 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGNodeBase &N);
337 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator> It;
342 It = N->parent_end();
344 It = N->parent_begin();
350 : Node(VFIt.Node), It(VFIt.It) {}
354 this->Node = VFIt.Node;
384 ValueFlowIterator vflow_end()
const {
return {
this,
true}; }
386 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
387 parent_begin()
const {
388 return {Parents.begin()};
391 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
393 return {Parents.end()};
396 iterator_range<std::map<const SEGNodeBase *, float>::const_iterator>
398 return {Parents.begin(), Parents.end()};
401 std::vector<SEGNodeBase *>::const_iterator child_begin()
const {
402 return Children.begin();
405 std::vector<SEGNodeBase *>::const_iterator child_end()
const {
406 return Children.end();
409 iterator_range<std::vector<SEGNodeBase *>::const_iterator> children()
const {
410 return {Children.begin(), Children.end()};
413 std::map<const SEGNodeBase *, float>::const_iterator
414 parent_confidence_begin()
const {
415 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
419 std::map<const SEGNodeBase *, float>::const_iterator
420 parent_confidence_end()
const {
421 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
425 size_t child_size()
const {
return Children.size(); }
427 size_t parent_size()
const {
return Parents.size(); }
429 std::vector<SEGSiteBase *>::const_iterator use_site_begin()
const {
430 return UseSites.begin();
433 std::vector<SEGSiteBase *>::const_iterator use_site_end()
const {
434 return UseSites.end();
437 iterator_range<std::vector<SEGSiteBase *>::const_iterator> use_sites() {
438 return {UseSites.begin(), UseSites.end()};
441 size_t use_site_size()
const {
return UseSites.size(); }
444 static bool classof(
const SEGObject *N) {
445 return N->getKind() >= SEGOBJK_NodeBegin && N->getKind() <= SEGOBJK_NodeEnd;
456 Value *LLVMValue =
nullptr;
462 BasicBlock *BB,
bool fromDisk);
476 BasicBlock *BB,
bool fromDisk);
480 friend class SEGHash;
485 Value *getLLVMValue()
const {
return LLVMValue; }
487 SEGValue *getSEGValue()
const {
return segValue; }
489 void dot(raw_fd_ostream &O)
const override;
491 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
493 if (Value *Val = N.getLLVMValue()) {
496 Out << N.getDescription();
501 virtual Value *getLLVMDbgValue()
const override {
return getLLVMValue(); }
504 static bool classof(
const SEGObject *N) {
505 return N->getKind() >= SEGOBJK_OperandBegin &&
506 N->getKind() <= SEGOBJK_OperandEnd;
510 void initialize(Value *Val);
520 CK_URem = CK_BinaryBegin,
538 CK_BinaryEnd = CK_AShr,
541 CK_AddressCast = CK_CastBegin,
554 CK_CastEnd = CK_FP2UI,
568 CK_FFalse = CK_CmpBegin,
614 CodeKind getOpcode()
const {
return Opcode; }
616 virtual void dot(raw_fd_ostream &O)
const;
618 bool isCmpNode()
const {
619 return Opcode <= CK_CmpEnd && Opcode >= CK_CmpBegin;
622 bool isSignedCmp()
const {
return Opcode <= CK_ISLE && Opcode >= CK_ISGT; }
624 bool isUnSignedCmp()
const {
return Opcode <= CK_IULE && Opcode >= CK_IUGT; }
626 bool isFloatCmp()
const {
return Opcode <= CK_FTrue && Opcode >= CK_FFalse; }
628 bool isAddNode()
const {
return Opcode == CK_Add; }
630 bool isSubNode()
const {
return Opcode == CK_Sub; }
632 bool isGEPNode()
const {
return Opcode == CK_GetElmtPtr; }
634 bool isSelectNode()
const {
return Opcode == CK_Select; }
636 bool isCastNode()
const {
637 return Opcode <= CK_CastEnd && Opcode >= CK_CastBegin;
640 bool isBinaryNode()
const {
641 return Opcode <= CK_BinaryEnd && Opcode >= CK_BinaryBegin;
644 bool isExtractElmtNode()
const {
return Opcode == CK_ExtractElmt; }
646 bool isInsertElmtNode()
const {
return Opcode == CK_InsertElmt; }
648 bool isConcatNode()
const {
return Opcode == CK_Concat; }
651 static bool classof(
const SEGObject *N) {
652 return N->getKind() >= SEGOBJK_OpcodeBegin &&
653 N->getKind() <= SEGOBJK_OpcodeEnd;
656 static const char *getOpcodeName(CodeKind CK);
662 Instruction *User =
nullptr;
674 CallSite getLLVMCallSite()
const {
return CallSite(User); }
676 Instruction *getInstruction()
const {
return User; }
678 SEGValue *getSEGValue()
const {
return segValue; }
680 virtual Value *getLLVMDbgValue()
const override {
return getInstruction(); }
682 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
689 static bool classof(
const SEGObject *O) {
690 return O->getKind() >= SEGOBJK_SiteBegin && O->getKind() <= SEGOBJK_SiteEnd;
694 namespace FalconPlus {
698 class AbstractCondPtr;
702 namespace SymbolicExecution {
710 friend class IntraFalcon;
711 friend class PTGraph;
714 friend class SEGSerializer;
716 friend class FalconPlus::AbstractCond;
717 friend class FalconPlus::RegionCond;
718 friend class FalconPlus::IntraFalcon;
719 friend class FalconPlus::AbstractCondPtr;
720 friend class FalconPlus::MemValueSet;
722 friend class SymbolicExecution::AnalysisState;
732 : CondNode(CN), BB(B), Cond(C) {}
734 bool operator<(
const CDGCond &RHS)
const {
735 return (CondNode < RHS.CondNode) ||
736 (CondNode == RHS.CondNode && BB < RHS.BB) ||
737 (CondNode == RHS.CondNode && BB == RHS.BB && Cond < RHS.Cond);
740 bool operator==(
const CDGCond &RHS)
const {
741 return CondNode == RHS.CondNode && BB == RHS.BB && Cond == RHS.Cond;
744 BasicBlock *getBB()
const {
return BB; }
749 Function *BaseFunc =
nullptr;
752 std::vector<SEGObject *> NodesList;
755 std::unordered_map<Value *, SEGOperandNode *> ValueNodesMap;
760 std::vector<std::pair<Value *, SEGOperandNode *>> ValueNodePairs;
764 std::set<SEGNodeBase *> NonValueNodes;
771 std::map<Instruction *, SEGSiteBase *> InstSiteMap;
772 std::vector<SEGCallSite *> CallSites;
781 std::map<BasicBlock *, std::set<CDGCond> *> BlockCondMap;
783 std::string SEGIndex;
787 std::string getSEGIndex()
const {
788 assert(!SEGIndex.empty() &&
"SEGIndex should not be empty");
792 template <
class T> T *getSEGObject(int64_t index) {
793 assert(index == -1 || (index >= 0 && index < NodesList.size()));
796 auto *Obj = NodesList[index];
805 kvec<SEGPseudoReturnNode *> PseudoReturns;
807 kvec<SEGCommonArgumentNode *> CommonArgumentNodes;
808 kvec<SEGPseudoArgumentNode *> PseudoArgumentNodes;
809 kvec<SEGVarArgumentNode *> VarArgumentNodes;
823 std::unordered_map<SEGNodeBase *, int> SummaryArgNodes;
824 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
825 SummaryArgNodesCache;
826 std::unordered_map<SEGNodeBase *, int> SummaryReturnNodes;
827 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
828 SummaryReturnNodesCache;
831 std::map<std::string, SEGOperandNode *> NameToPseudoArgNode;
832 std::unordered_map<std::string, SEGOperandNode *> NameToNonArgPseudoNode;
833 std::unordered_map<std::string, std::unique_ptr<PseudoVal>> PseudoValStorage;
845 void addSummaryArgNode(
SEGNodeBase *Node,
int APDepth);
847 void addSummaryReturnNode(
SEGNodeBase *Node,
int APDepth);
850 size_t getNumCommonArgument()
const {
return CommonArgumentNodes.size(); }
852 size_t getNumPseudoArgument()
const {
return PseudoArgumentNodes.size(); }
854 size_t getNumVarArgument()
const {
return VarArgumentNodes.size(); }
856 size_t getNumPseudoReturn()
const {
return PseudoReturns.size(); }
858 bool hasCommonReturnNode()
const {
868 return PseudoReturns[Index];
872 return CommonArgumentNodes[Index];
876 return PseudoArgumentNodes[Index];
880 return VarArgumentNodes[Index];
883 bool isSummaryArgument(
const SEGNodeBase *Node)
const;
887 int getSummaryArgumentAPDepth(
const SEGNodeBase *Node)
const;
891 std::unordered_set<SEGNodeBase *> *getSummaryArgument(
int APDepth)
const;
893 bool isSummaryReturn(
const SEGNodeBase *Node)
const;
897 int getSummaryReturnAPDepth(
const SEGNodeBase *Node)
const;
901 std::unordered_set<SEGNodeBase *> *getSummaryReturn(
int APDepth)
const;
908 bool isDirectlyPassedToCaller(
const SEGNodeBase *Node)
const;
909 bool isDirectlyPassedFromCaller(
const SEGNodeBase *Node)
const;
919 std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
920 std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
922 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
923 compound_regions_cache_and;
925 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
926 compound_regions_cache_or;
929 std::unordered_map<BasicBlock *, SEGRegionNode *> bb_region_cache;
932 void clearRegionNodeCache();
950 SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
954 template <
class OperandNodeTy>
955 OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
956 bool fromDisk =
false) {
958 assert(Val && !Val->getType()->isVoidTy());
959 assert((!(dyn_cast<Instruction>(Val)) ||
960 BB == ((Instruction *)Val)->getParent()) &&
961 "Incorrect BasicBlock detected");
963 auto It = ValueNodesMap.find(Val);
964 if (It != ValueNodesMap.end()) {
965 assert(isa<OperandNodeTy>(It->second));
966 return (OperandNodeTy *)It->second;
968 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
969 ValueNodePairs.push_back({Val, N});
970 ValueNodesMap[Val] = N;
977 template <
class OperandNodeTy>
979 clonePseudoVal(
const PseudoVal *Arg,
980 std::function<OperandNodeTy *(
const PseudoVal *)> Proc) {
981 const std::string &ArgName = Arg->getName();
982 auto ClonedArg = std::unique_ptr<PseudoVal>(Arg->clone());
983 auto *ArgNode = Proc(ClonedArg.get());
985 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
986 NameToPseudoArgNode.insert(std::make_pair(ArgName, ArgNode));
988 NameToNonArgPseudoNode.insert(std::make_pair(ArgName, ArgNode));
991 assert(!PseudoValStorage.count(ArgName));
992 PseudoValStorage.insert({ArgName, std::move(ClonedArg)});
996 template <
class OperandNodeTy>
998 findOrClonePseudoVal(
const PseudoVal *Arg,
999 std::function<OperandNodeTy *(
const PseudoVal *)> Proc) {
1000 const std::string &ArgName = Arg->getName();
1001 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
1002 if (NameToPseudoArgNode.count(ArgName)) {
1003 return cast<OperandNodeTy>(NameToPseudoArgNode.at(ArgName));
1006 if (NameToNonArgPseudoNode.count(ArgName)) {
1008 std::is_base_of<SEGOperandNode, OperandNodeTy>::value,
1009 "OperandNodeTy must be a derived class of SEGOperandNode.");
1010 return cast<OperandNodeTy>(NameToNonArgPseudoNode.at(ArgName));
1014 return clonePseudoVal<OperandNodeTy>(Arg, Proc);
1020 void finalizePseudoArgumentNodes();
1021 SEGOperandNode *findOrCreateSimpleOperandFromPseudoVal(
const PseudoVal *Arg,
1026 BasicBlock *BB, CallSite CS,
1033 template <
class OperandNodeTy>
1034 OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
1035 bool fromDisk =
false) {
1037 assert(Val && !Val->getType()->isVoidTy());
1038 assert((!(dyn_cast<Instruction>(Val)) ||
1039 BB == ((Instruction *)Val)->getParent()) &&
1040 "Incorrect BasicBlock detected");
1042 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
1043 ValueNodesMap[Val] = N;
1044 ValueNodePairs.push_back({Val, N});
1048 template <
class OperandNodeTy>
1049 OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB,
1050 bool fromDisk =
false) {
1053 auto *Ret =
new OperandNodeTy(Ty,
this, BB, fromDisk);
1054 NonValueNodes.insert(Ret);
1060 template <
class SiteTy>
1061 SiteTy *findOrCreateSite(Instruction *I,
bool fromDisk =
false) {
1064 auto It = InstSiteMap.find(I);
1065 if (It != InstSiteMap.end()) {
1066 assert(isa<SiteTy>(It->second));
1067 return (SiteTy *)It->second;
1069 SiteTy *N =
new SiteTy(I,
this, fromDisk);
1073 CallSites.push_back(CS);
1084 createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1085 Instruction *Callsite,
int APDepth,
1086 bool fromDisk =
false);
1092 createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1093 Instruction *Callsite,
float Confidence,
1094 bool fromDisk =
false);
1098 findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1099 CallSite CS, Function *Callee,
bool IsCommon);
1102 BasicBlock *BB, CallSite CS,
1105 bool fromDisk =
false);
1109 findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1110 CallSite CS, Function *Callee,
1111 bool fromDisk =
false);
1114 SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1115 Value *StoreVal, BasicBlock *BB,
1116 bool fromDisk =
false);
1120 bool cond =
false,
bool fromDisk =
false);
1152 BasicBlock *BB,
const kvec<SEGNodeBase *> &,
1153 bool fromDisk =
false);
1158 uint64_t TSz,
bool fromDisk =
false);
1164 bool fromDisk =
false);
1167 void addBlockCond(BasicBlock *CurrBB,
SEGNodeBase *BrNode, BasicBlock *DepBB,
1174 Function *getBaseFunc()
const {
return BaseFunc; }
1176 Module *getBaseModule()
const {
return BaseFunc->getParent(); }
1180 template <
class SiteTy> SiteTy *
findSite(Instruction *I)
const {
1183 auto It = InstSiteMap.find(I);
1184 if (It != InstSiteMap.end()) {
1186 return dyn_cast<SiteTy>(It->second);
1199 Instruction *I = dyn_cast<Instruction>(sValue->
getValue());
1202 auto It = InstSiteMap.find(I);
1203 if (It != InstSiteMap.end()) {
1205 return dyn_cast<SiteTy>(It->second);
1240 auto It = BlockCondMap.find(BB);
1241 if (It != BlockCondMap.end()) {
1248 void dot(
const char *FileName)
const;
1251 void dot(std::vector<const SEGNodeBase *> Srcs,
const char *FileName)
const;
1265 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1266 value_node_begin()
const {
1267 return ValueNodesMap.begin();
1270 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1271 value_node_end()
const {
1272 return ValueNodesMap.end();
1275 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1276 value_node_pair_begin()
const {
1277 return ValueNodePairs.begin();
1280 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1281 value_node_pair_end()
const {
1282 return ValueNodePairs.end();
1285 std::set<SEGNodeBase *>::const_iterator non_value_node_begin()
const {
1286 return NonValueNodes.begin();
1289 std::set<SEGNodeBase *>::const_iterator non_value_node_end()
const {
1290 return NonValueNodes.end();
1293 std::map<Instruction *, SEGSiteBase *>::const_iterator
1294 inst_site_begin()
const {
1295 return InstSiteMap.begin();
1298 std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end()
const {
1299 return InstSiteMap.end();
1302 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1303 store_mem_node_begin()
const {
1304 return StoreMemNodesMap.begin();
1307 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1308 store_mem_node_end()
const {
1309 return StoreMemNodesMap.end();
1312 std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin()
const {
1313 return InstSiteMap.begin();
1316 std::map<Instruction *, SEGSiteBase *>::const_iterator site_end()
const {
1317 return InstSiteMap.end();
1320 std::vector<SEGObject *>::const_iterator node_begin()
const {
1321 return NodesList.begin();
1324 std::vector<SEGObject *>::const_iterator node_end()
const {
1325 return NodesList.end();
1332 const kvec<SEGPseudoReturnNode *> &PseudoRets;
1336 const kvec<SEGPseudoReturnNode *> &PRs)
1337 : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1340 : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1374 ReturnIterator return_end()
const {
1375 return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1376 CommonReturn, PseudoReturns);
1379 ReturnIterator pseudo_return_begin()
const {
1380 size_t StartIndex = getCommonReturn() ? 1 : 0;
1381 return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1384 ReturnIterator pseudo_return_end()
const {
return return_end(); }
1389 const kvec<SEGCommonArgumentNode *> &CommonArgs;
1390 const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1391 const kvec<SEGVarArgumentNode *> &VarArgs;
1395 const kvec<SEGPseudoArgumentNode *> &PA,
1396 const kvec<SEGVarArgumentNode *> &VA)
1397 : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1400 : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1401 VarArgs(It.VarArgs) {}
1415 if (I < (
size_t)CommonArgs.size()) {
1419 if (I < (
size_t)(CommonArgs.size() + PseudoArgs.size())) {
1424 (
size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1426 VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1439 ArgumentIterator arg_end()
const {
1441 getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1442 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1446 ArgumentIterator common_arg_begin()
const {
return arg_begin(); }
1448 ArgumentIterator common_arg_end()
const {
1449 size_t NumArgs = getNumCommonArgument();
1450 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1454 ArgumentIterator pseudo_arg_begin()
const {
return common_arg_end(); }
1456 ArgumentIterator pseudo_arg_end()
const {
1457 size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1458 return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1462 ArgumentIterator var_arg_begin()
const {
return pseudo_arg_end(); }
1464 ArgumentIterator var_arg_end()
const {
return arg_end(); }
1466 typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1467 SEGCallSiteIterator seg_callsite_begin()
const {
return CallSites.begin(); }
1469 SEGCallSiteIterator seg_callsite_end()
const {
return CallSites.end(); }