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"
70 class SealEnhancedSEGWrapper;
74 static bool EnableValueToString;
75 static bool EnableArithmeticFlow;
79 friend class SEGSerializer;
89 SEGOBJK_ArgumentBegin,
90 SEGOBJK_CommonArgument,
92 SEGOBJK_PseudoArgument,
95 SEGOBJK_CallSiteOutputBegin,
96 SEGOBJK_CallSiteCommonOutput,
97 SEGOBJK_CallSitePseudoOutput,
98 SEGOBJK_CallSiteOutputEnd,
101 SEGOBJK_CommonReturn,
102 SEGOBJK_PseudoReturn,
109 SEGOBJK_SimpleOperand,
111 SEGOBJK_CallSitePseudoInput,
112 SEGOBJK_CallSiteSummaryArgument,
113 SEGOBJK_CallSiteSummaryReturn,
119 SEGOBJK_BinaryWithIntConst,
121 SEGOBJK_SimpleOpcode,
132 SEGOBJK_SimpleSiteBegin,
134 SEGOBJK_DereferenceSite,
138 SEGOBJK_SimpleSiteEnd,
144 const SEGObjectKind ObjKind;
150 BasicBlock *ParentBasicBlock =
nullptr;
153 int64_t ObjIndex = -1;
156 int64_t SEGIndex = -1;
184 virtual Value *getLLVMDbgValue()
const {
return nullptr; }
193 virtual Instruction *getLLVMDbgInstruction()
const {
194 Value *val = getLLVMDbgValue();
195 if (val !=
nullptr) {
196 return dyn_cast<Instruction>(val);
202 SEGObjectKind getKind()
const {
return ObjKind; }
204 int64_t getSEGIndex()
const {
205 assert(SEGIndex != -1 &&
"Index should not be -1");
209 void setObjIndex(int64_t index) { ObjIndex = index; }
211 int64_t getObjIndex()
const {
212 assert(ObjIndex != -1 &&
"Index should not be -1");
216 const char *getKindName()
const;
218 void setParentBasicBlock(BasicBlock *BB) { this->ParentBasicBlock = BB; }
220 BasicBlock *getParentBasicBlock()
const {
return ParentBasicBlock; }
222 Function *getParentFunction()
const {
return ParentBasicBlock->getParent(); }
227 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGObject &N);
231 LLVMValueIndexer *instance;
232 seg_cmp() : instance(LLVMValueIndexer::get()) {}
235 int64_t indexSEGA = A ? A->getSEGIndex() : -1;
236 int64_t indexSEGB = B ? B->getSEGIndex() : -1;
237 if (indexSEGA != indexSEGB || (indexSEGA == -1 && indexSEGB == -1)) {
238 return indexSEGA < indexSEGB;
240 int64_t indexA = A ? A->getObjIndex() : -1;
241 int64_t indexB = B ? B->getObjIndex() : -1;
242 return indexA < indexB;
249 friend class SEGSerializer;
250 friend class SEGHash;
259 void setDescription(std::string &Desc) { Description = Desc; }
262 friend class SealEnhancedSEGWrapper;
266 std::string Description;
270 std::vector<SEGNodeBase *> Children;
273 std::map<const SEGNodeBase *, float, seg_cmp> Parents;
276 std::vector<SEGSiteBase *> UseSites;
277 std::set<SEGSiteBase *> UseSiteSet;
280 Type *LLVMType =
nullptr;
292 assert(Children.size() > I &&
293 "Invalid child index when querying SEG edges");
297 float getConfidence(
const SEGNodeBase *ParentNode)
const {
298 auto It = Parents.find(ParentNode);
299 assert(It != Parents.end() &&
300 "Invalid parent node when querying SEG edges");
304 unsigned getNumChildren()
const {
return Children.size(); }
306 unsigned getNumParents()
const {
return Parents.size(); }
308 void addChild(
SEGNodeBase *N,
float Confidence = 1.0f) {
309 Children.push_back(N);
310 N->Parents.insert(std::make_pair(
this, Confidence));
313 void eraseAllChildren() {
314 for (
auto *Child : Children) {
315 Child->Parents.erase(
this);
321 if (!UseSiteSet.count(U)) {
322 UseSiteSet.insert(U);
323 UseSites.push_back(U);
327 virtual bool isTerminalNode()
const {
return Children.empty(); }
331 bool containsParentNode(
const SEGNodeBase *N)
const {
332 return Parents.count(N);
335 const std::string &getDescription()
const {
return Description; }
338 virtual void dot(raw_fd_ostream &O)
const = 0;
340 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
const SEGNodeBase &N);
346 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator> It;
351 It = N->parent_end();
353 It = N->parent_begin();
359 : Node(VFIt.Node), It(VFIt.It) {}
363 this->Node = VFIt.Node;
393 ValueFlowIterator vflow_end()
const {
return {
this,
true}; }
395 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
396 parent_begin()
const {
397 return {Parents.begin()};
400 key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>
402 return {Parents.end()};
405 iterator_range<std::map<const SEGNodeBase *, float>::const_iterator>
407 return {Parents.begin(), Parents.end()};
410 std::vector<SEGNodeBase *>::const_iterator child_begin()
const {
411 return Children.begin();
414 std::vector<SEGNodeBase *>::const_iterator child_end()
const {
415 return Children.end();
418 iterator_range<std::vector<SEGNodeBase *>::const_iterator> children()
const {
419 return {Children.begin(), Children.end()};
422 std::map<const SEGNodeBase *, float>::const_iterator
423 parent_confidence_begin()
const {
424 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
428 std::map<const SEGNodeBase *, float>::const_iterator
429 parent_confidence_end()
const {
430 return key_iterator<std::map<const SEGNodeBase *, float>::const_iterator>(
434 size_t child_size()
const {
return Children.size(); }
436 size_t parent_size()
const {
return Parents.size(); }
438 std::vector<SEGSiteBase *>::const_iterator use_site_begin()
const {
439 return UseSites.begin();
442 std::vector<SEGSiteBase *>::const_iterator use_site_end()
const {
443 return UseSites.end();
446 iterator_range<std::vector<SEGSiteBase *>::const_iterator> use_sites() {
447 return {UseSites.begin(), UseSites.end()};
450 size_t use_site_size()
const {
return UseSites.size(); }
453 static bool classof(
const SEGObject *N) {
454 return N->getKind() >= SEGOBJK_NodeBegin && N->getKind() <= SEGOBJK_NodeEnd;
465 Value *LLVMValue =
nullptr;
471 BasicBlock *BB,
bool fromDisk);
485 BasicBlock *BB,
bool fromDisk);
489 friend class SEGHash;
494 Value *getLLVMValue()
const {
return LLVMValue; }
496 SEGValue *getSEGValue()
const {
return segValue; }
498 void dot(raw_fd_ostream &O)
const override;
500 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
502 if (Value *Val = N.getLLVMValue()) {
505 Out << N.getDescription();
510 virtual Value *getLLVMDbgValue()
const override {
return getLLVMValue(); }
513 static bool classof(
const SEGObject *N) {
514 return N->getKind() >= SEGOBJK_OperandBegin &&
515 N->getKind() <= SEGOBJK_OperandEnd;
519 void initialize(Value *Val);
529 CK_URem = CK_BinaryBegin,
547 CK_BinaryEnd = CK_AShr,
550 CK_AddressCast = CK_CastBegin,
563 CK_CastEnd = CK_FP2UI,
577 CK_FFalse = CK_CmpBegin,
623 CodeKind getOpcode()
const {
return Opcode; }
625 virtual void dot(raw_fd_ostream &O)
const;
627 bool isCmpNode()
const {
628 return Opcode <= CK_CmpEnd && Opcode >= CK_CmpBegin;
631 bool isSignedCmp()
const {
return Opcode <= CK_ISLE && Opcode >= CK_ISGT; }
633 bool isUnSignedCmp()
const {
return Opcode <= CK_IULE && Opcode >= CK_IUGT; }
635 bool isFloatCmp()
const {
return Opcode <= CK_FTrue && Opcode >= CK_FFalse; }
637 bool isAddNode()
const {
return Opcode == CK_Add; }
639 bool isSubNode()
const {
return Opcode == CK_Sub; }
641 bool isGEPNode()
const {
return Opcode == CK_GetElmtPtr; }
643 bool isSelectNode()
const {
return Opcode == CK_Select; }
645 bool isCastNode()
const {
646 return Opcode <= CK_CastEnd && Opcode >= CK_CastBegin;
649 bool isBinaryNode()
const {
650 return Opcode <= CK_BinaryEnd && Opcode >= CK_BinaryBegin;
653 bool isExtractElmtNode()
const {
return Opcode == CK_ExtractElmt; }
655 bool isInsertElmtNode()
const {
return Opcode == CK_InsertElmt; }
657 bool isConcatNode()
const {
return Opcode == CK_Concat; }
660 static bool classof(
const SEGObject *N) {
661 return N->getKind() >= SEGOBJK_OpcodeBegin &&
662 N->getKind() <= SEGOBJK_OpcodeEnd;
665 static const char *getOpcodeName(CodeKind CK);
671 Instruction *User =
nullptr;
683 CallSite getLLVMCallSite()
const {
return CallSite(User); }
685 Instruction *getInstruction()
const {
return User; }
687 SEGValue *getSEGValue()
const {
return segValue; }
689 virtual Value *getLLVMDbgValue()
const override {
return getInstruction(); }
691 friend raw_ostream &operator<<(llvm::raw_ostream &Out,
698 static bool classof(
const SEGObject *O) {
699 return O->getKind() >= SEGOBJK_SiteBegin && O->getKind() <= SEGOBJK_SiteEnd;
703 namespace FalconPlus {
707 class AbstractCondPtr;
711 namespace SymbolicExecution {
719 friend class IntraFalcon;
720 friend class PTGraph;
723 friend class SEGSerializer;
725 friend class FalconPlus::AbstractCond;
726 friend class FalconPlus::RegionCond;
727 friend class FalconPlus::IntraFalcon;
728 friend class FalconPlus::AbstractCondPtr;
729 friend class FalconPlus::MemValueSet;
731 friend class SymbolicExecution::AnalysisState;
741 : CondNode(CN), BB(B), Cond(C) {}
743 bool operator<(
const CDGCond &RHS)
const {
744 return (CondNode < RHS.CondNode) ||
745 (CondNode == RHS.CondNode && BB < RHS.BB) ||
746 (CondNode == RHS.CondNode && BB == RHS.BB && Cond < RHS.Cond);
749 bool operator==(
const CDGCond &RHS)
const {
750 return CondNode == RHS.CondNode && BB == RHS.BB && Cond == RHS.Cond;
753 BasicBlock *getBB()
const {
return BB; }
758 Function *BaseFunc =
nullptr;
761 std::vector<SEGObject *> NodesList;
764 std::unordered_map<Value *, SEGOperandNode *> ValueNodesMap;
769 std::vector<std::pair<Value *, SEGOperandNode *>> ValueNodePairs;
773 std::set<SEGNodeBase *> NonValueNodes;
780 std::map<Instruction *, SEGSiteBase *> InstSiteMap;
781 std::vector<SEGCallSite *> CallSites;
790 std::map<BasicBlock *, std::set<CDGCond> *> BlockCondMap;
792 int64_t SEGIndex = -1;
796 int64_t getSEGIndex()
const {
return SEGIndex; }
798 template <
class T> T *getSEGObject(int64_t index) {
799 assert(index == -1 || (index >= 0 && index < NodesList.size()));
802 auto *Obj = NodesList[index];
811 kvec<SEGPseudoReturnNode *> PseudoReturns;
813 kvec<SEGCommonArgumentNode *> CommonArgumentNodes;
814 kvec<SEGPseudoArgumentNode *> PseudoArgumentNodes;
815 kvec<SEGVarArgumentNode *> VarArgumentNodes;
829 std::unordered_map<SEGNodeBase *, int> SummaryArgNodes;
830 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
831 SummaryArgNodesCache;
832 std::unordered_map<SEGNodeBase *, int> SummaryReturnNodes;
833 std::unordered_map<int, std::unordered_set<SEGNodeBase *>>
834 SummaryReturnNodesCache;
837 std::map<std::string, SEGOperandNode *> NameToPseudoArgNode;
838 std::unordered_map<std::string, SEGOperandNode *> NameToNonArgPseudoNode;
839 std::unordered_map<std::string, std::unique_ptr<PseudoVal>> PseudoValStorage;
851 void addSummaryArgNode(
SEGNodeBase *Node,
int APDepth);
853 void addSummaryReturnNode(
SEGNodeBase *Node,
int APDepth);
856 size_t getNumCommonArgument()
const {
return CommonArgumentNodes.size(); }
858 size_t getNumPseudoArgument()
const {
return PseudoArgumentNodes.size(); }
860 size_t getNumVarArgument()
const {
return VarArgumentNodes.size(); }
862 size_t getNumPseudoReturn()
const {
return PseudoReturns.size(); }
864 bool hasCommonReturnNode()
const {
874 return PseudoReturns[Index];
878 return CommonArgumentNodes[Index];
882 return PseudoArgumentNodes[Index];
886 return VarArgumentNodes[Index];
889 bool isSummaryArgument(
const SEGNodeBase *Node)
const;
893 int getSummaryArgumentAPDepth(
const SEGNodeBase *Node)
const;
897 std::unordered_set<SEGNodeBase *> *getSummaryArgument(
int APDepth)
const;
899 bool isSummaryReturn(
const SEGNodeBase *Node)
const;
903 int getSummaryReturnAPDepth(
const SEGNodeBase *Node)
const;
907 std::unordered_set<SEGNodeBase *> *getSummaryReturn(
int APDepth)
const;
914 bool isDirectlyPassedToCaller(
const SEGNodeBase *Node)
const;
915 bool isDirectlyPassedFromCaller(
const SEGNodeBase *Node)
const;
925 std::unordered_map<SEGNodeBase *, SEGRegionNode *> positive_regions_cache;
926 std::unordered_map<SEGNodeBase *, SEGRegionNode *> negative_regions_cache;
928 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
929 compound_regions_cache_and;
931 std::unordered_map<SEGRegionNode *, SEGRegionNode *>>
932 compound_regions_cache_or;
935 std::unordered_map<BasicBlock *, SEGRegionNode *> bb_region_cache;
938 void clearRegionNodeCache();
956 SEGOperandNode *findOrCreateNode(Value *Val, Type *Ty, BasicBlock *BB);
960 template <
class OperandNodeTy>
961 OperandNodeTy *findOrCreateOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
962 bool fromDisk =
false) {
964 assert(Val && !Val->getType()->isVoidTy());
965 assert((!(dyn_cast<Instruction>(Val)) ||
966 BB == ((Instruction *)Val)->getParent()) &&
967 "Incorrect BasicBlock detected");
969 auto It = ValueNodesMap.find(Val);
970 if (It != ValueNodesMap.end()) {
971 assert(isa<OperandNodeTy>(It->second));
972 return (OperandNodeTy *)It->second;
974 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
975 ValueNodePairs.push_back({Val, N});
976 ValueNodesMap[Val] = N;
983 template <
class OperandNodeTy>
985 clonePseudoVal(
const PseudoVal *Arg,
986 std::function<OperandNodeTy *(
const PseudoVal *)> Proc) {
987 const std::string &ArgName = Arg->getName();
988 auto ClonedArg = std::unique_ptr<PseudoVal>(Arg->clone());
989 auto *ArgNode = Proc(ClonedArg.get());
991 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
992 NameToPseudoArgNode.insert(std::make_pair(ArgName, ArgNode));
994 NameToNonArgPseudoNode.insert(std::make_pair(ArgName, ArgNode));
997 assert(!PseudoValStorage.count(ArgName));
998 PseudoValStorage.insert({ArgName, std::move(ClonedArg)});
1002 template <
class OperandNodeTy>
1004 findOrClonePseudoVal(
const PseudoVal *Arg,
1005 std::function<OperandNodeTy *(
const PseudoVal *)> Proc) {
1006 const std::string &ArgName = Arg->getName();
1007 if (std::is_same<OperandNodeTy, SEGPseudoArgumentNode>::value) {
1008 if (NameToPseudoArgNode.count(ArgName)) {
1009 return cast<OperandNodeTy>(NameToPseudoArgNode.at(ArgName));
1012 if (NameToNonArgPseudoNode.count(ArgName)) {
1014 std::is_base_of<SEGOperandNode, OperandNodeTy>::value,
1015 "OperandNodeTy must be a derived class of SEGOperandNode.");
1016 return cast<OperandNodeTy>(NameToNonArgPseudoNode.at(ArgName));
1020 return clonePseudoVal<OperandNodeTy>(Arg, Proc);
1026 void finalizePseudoArgumentNodes();
1027 SEGOperandNode *findOrCreateSimpleOperandFromPseudoVal(
const PseudoVal *Arg,
1032 BasicBlock *BB, CallSite CS,
1039 template <
class OperandNodeTy>
1040 OperandNodeTy *CreateUniqueOperandNode(Value *Val, Type *Ty, BasicBlock *BB,
1041 bool fromDisk =
false) {
1043 assert(Val && !Val->getType()->isVoidTy());
1044 assert((!(dyn_cast<Instruction>(Val)) ||
1045 BB == ((Instruction *)Val)->getParent()) &&
1046 "Incorrect BasicBlock detected");
1048 auto *N =
new OperandNodeTy(Val, Ty,
this, BB, fromDisk);
1049 ValueNodesMap[Val] = N;
1050 ValueNodePairs.push_back({Val, N});
1054 template <
class OperandNodeTy>
1055 OperandNodeTy *createOperandNode(Type *Ty, BasicBlock *BB,
1056 bool fromDisk =
false) {
1059 auto *Ret =
new OperandNodeTy(Ty,
this, BB, fromDisk);
1060 NonValueNodes.insert(Ret);
1066 template <
class SiteTy>
1067 SiteTy *findOrCreateSite(Instruction *I,
bool fromDisk =
false) {
1070 auto It = InstSiteMap.find(I);
1071 if (It != InstSiteMap.end()) {
1072 assert(isa<SiteTy>(It->second));
1073 return (SiteTy *)It->second;
1075 SiteTy *N =
new SiteTy(I,
this, fromDisk);
1079 CallSites.push_back(CS);
1090 createCallSiteArgumentSummaryNode(Type *Ty, BasicBlock *BB,
1091 Instruction *Callsite,
int APDepth,
1092 bool fromDisk =
false);
1098 createCallSiteReturnSummaryNode(Type *Ty, BasicBlock *BB,
1099 Instruction *Callsite,
float Confidence,
1100 bool fromDisk =
false);
1104 findOrCreateCallSiteOutputNode(Value *Val, Type *Ty, BasicBlock *BB,
1105 CallSite CS, Function *Callee,
bool IsCommon);
1108 BasicBlock *BB, CallSite CS,
1111 bool fromDisk =
false);
1115 findOrCreateCallSitePseudoInputNode(Value *Val, Type *Ty, BasicBlock *BB,
1116 CallSite CS, Function *Callee,
1117 bool fromDisk =
false);
1120 SEGStoreMemNode *findOrCreateStoreMemNode(Type *Ty, Instruction *StoreSite,
1121 Value *StoreVal, BasicBlock *BB,
1122 bool fromDisk =
false);
1126 bool cond =
false,
bool fromDisk =
false);
1158 BasicBlock *BB,
const kvec<SEGNodeBase *> &,
1159 bool fromDisk =
false);
1164 uint64_t TSz,
bool fromDisk =
false);
1170 bool fromDisk =
false);
1173 void addBlockCond(BasicBlock *CurrBB,
SEGNodeBase *BrNode, BasicBlock *DepBB,
1180 Function *getBaseFunc()
const {
return BaseFunc; }
1184 template <
class SiteTy> SiteTy *
findSite(Instruction *I)
const {
1187 auto It = InstSiteMap.find(I);
1188 if (It != InstSiteMap.end()) {
1190 return dyn_cast<SiteTy>(It->second);
1203 Instruction *I = dyn_cast<Instruction>(sValue->
getValue());
1206 auto It = InstSiteMap.find(I);
1207 if (It != InstSiteMap.end()) {
1209 return dyn_cast<SiteTy>(It->second);
1244 auto It = BlockCondMap.find(BB);
1245 if (It != BlockCondMap.end()) {
1252 void dot(
const char *FileName)
const;
1255 void dot(std::vector<const SEGNodeBase *> Srcs,
const char *FileName)
const;
1269 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1270 value_node_begin()
const {
1271 return ValueNodesMap.begin();
1274 std::unordered_map<Value *, SEGOperandNode *>::const_iterator
1275 value_node_end()
const {
1276 return ValueNodesMap.end();
1279 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1280 value_node_pair_begin()
const {
1281 return ValueNodePairs.begin();
1284 std::vector<std::pair<Value *, SEGOperandNode *>>::const_iterator
1285 value_node_pair_end()
const {
1286 return ValueNodePairs.end();
1289 std::set<SEGNodeBase *>::const_iterator non_value_node_begin()
const {
1290 return NonValueNodes.begin();
1293 std::set<SEGNodeBase *>::const_iterator non_value_node_end()
const {
1294 return NonValueNodes.end();
1297 std::map<Instruction *, SEGSiteBase *>::const_iterator
1298 inst_site_begin()
const {
1299 return InstSiteMap.begin();
1302 std::map<Instruction *, SEGSiteBase *>::const_iterator inst_site_end()
const {
1303 return InstSiteMap.end();
1306 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1307 store_mem_node_begin()
const {
1308 return StoreMemNodesMap.begin();
1311 std::map<std::pair<Instruction *, Value *>,
SEGStoreMemNode *>::const_iterator
1312 store_mem_node_end()
const {
1313 return StoreMemNodesMap.end();
1316 std::map<Instruction *, SEGSiteBase *>::const_iterator site_begin()
const {
1317 return InstSiteMap.begin();
1320 std::map<Instruction *, SEGSiteBase *>::const_iterator site_end()
const {
1321 return InstSiteMap.end();
1324 std::vector<SEGObject *>::const_iterator node_begin()
const {
1325 return NodesList.begin();
1328 std::vector<SEGObject *>::const_iterator node_end()
const {
1329 return NodesList.end();
1336 const kvec<SEGPseudoReturnNode *> &PseudoRets;
1340 const kvec<SEGPseudoReturnNode *> &PRs)
1341 : I(Id), CommonRet(CR), PseudoRets(PRs) {}
1344 : I(It.I), CommonRet(It.CommonRet), PseudoRets(It.PseudoRets) {}
1378 ReturnIterator return_end()
const {
1379 return ReturnIterator(getNumPseudoReturn() + (getCommonReturn() ? 1 : 0),
1380 CommonReturn, PseudoReturns);
1383 ReturnIterator pseudo_return_begin()
const {
1384 size_t StartIndex = getCommonReturn() ? 1 : 0;
1385 return ReturnIterator(StartIndex, CommonReturn, PseudoReturns);
1388 ReturnIterator pseudo_return_end()
const {
return return_end(); }
1393 const kvec<SEGCommonArgumentNode *> &CommonArgs;
1394 const kvec<SEGPseudoArgumentNode *> &PseudoArgs;
1395 const kvec<SEGVarArgumentNode *> &VarArgs;
1399 const kvec<SEGPseudoArgumentNode *> &PA,
1400 const kvec<SEGVarArgumentNode *> &VA)
1401 : I(Id), CommonArgs(CA), PseudoArgs(PA), VarArgs(VA) {}
1404 : I(It.I), CommonArgs(It.CommonArgs), PseudoArgs(It.PseudoArgs),
1405 VarArgs(It.VarArgs) {}
1419 if (I < (
size_t)CommonArgs.size()) {
1423 if (I < (
size_t)(CommonArgs.size() + PseudoArgs.size())) {
1428 (
size_t)(CommonArgs.size() + PseudoArgs.size() + VarArgs.size()));
1430 VarArgs[I - (CommonArgs.size() + PseudoArgs.size())];
1443 ArgumentIterator arg_end()
const {
1445 getNumCommonArgument() + getNumPseudoArgument() + getNumVarArgument();
1446 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1450 ArgumentIterator common_arg_begin()
const {
return arg_begin(); }
1452 ArgumentIterator common_arg_end()
const {
1453 size_t NumArgs = getNumCommonArgument();
1454 return ArgumentIterator(NumArgs, CommonArgumentNodes, PseudoArgumentNodes,
1458 ArgumentIterator pseudo_arg_begin()
const {
return common_arg_end(); }
1460 ArgumentIterator pseudo_arg_end()
const {
1461 size_t EndId = getNumCommonArgument() + getNumPseudoArgument();
1462 return ArgumentIterator(EndId, CommonArgumentNodes, PseudoArgumentNodes,
1466 ArgumentIterator var_arg_begin()
const {
return pseudo_arg_end(); }
1468 ArgumentIterator var_arg_end()
const {
return arg_end(); }
1470 typedef std::vector<SEGCallSite *>::const_iterator SEGCallSiteIterator;
1471 SEGCallSiteIterator seg_callsite_begin()
const {
return CallSites.begin(); }
1473 SEGCallSiteIterator seg_callsite_end()
const {
return CallSites.end(); }