CoreEngine.h revision cca79db2ea94f71fb088f4b0f104cef8bedf8ff2
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//==- CoreEngine.h - Path-Sensitive Dataflow Engine ----------------*- C++ -*-// 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// The LLVM Compiler Infrastructure 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// This file is distributed under the University of Illinois Open Source 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// License. See LICENSE.TXT for details. 7a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang// 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===// 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// This file defines a generic engine for intraprocedural, path-sensitive, 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// dataflow analysis via graph reachability. 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project// 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===// 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef LLVM_CLANG_GR_COREENGINE 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define LLVM_CLANG_GR_COREENGINE 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "clang/AST/Expr.h" 19a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" 20a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h" 21a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h" 22a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang#include "llvm/ADT/OwningPtr.h" 23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace clang { 25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass ProgramPointTag; 27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectnamespace ento { 29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass NodeBuilder; 31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project//===----------------------------------------------------------------------===// 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// CoreEngine - Implements the core logic of the graph-reachability 34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// analysis. It traverses the CFG and generates the ExplodedGraph. 35a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang/// Program "states" are treated as opaque void pointers. 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// The template class CoreEngine (which subclasses CoreEngine) 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// provides the matching component to the engine that knows the actual types 38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// for states. Note that this engine only dispatches to transfer functions 39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// at the statement and block-level. The analyses themselves must implement 40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/// any transfer function logic and the sub-expression level (if any). 41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass CoreEngine { 42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend struct NodeBuilderContext; 43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class NodeBuilder; 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class CommonNodeBuilder; 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class GenericNodeBuilderImpl; 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class IndirectGotoNodeBuilder; 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class SwitchNodeBuilder; 48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class EndOfFunctionNodeBuilder; 49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class CallEnterNodeBuilder; 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class CallExitNodeBuilder; 51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class ExprEngine; 52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> > 5577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner BlocksExhausted; 5677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> > 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlocksAborted; 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprivate: 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SubEngine& SubEng; 63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// G - The simulation graph. Each node is a (location,state) pair. 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project llvm::OwningPtr<ExplodedGraph> G; 66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// WList - A set of queued nodes that need to be processed by the 68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// worklist algorithm. It is up to the implementation of WList to decide 69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// the order that nodes are processed. 70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project WorkList* WList; 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// BCounterFactory - A factory object for created BlockCounter objects. 73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// These are used to record for key nodes in the ExplodedGraph the 74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// number of times different CFGBlocks have been visited along a path. 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlockCounter::Factory BCounterFactory; 76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// The locations where we stopped doing work because we visited a location 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// too many times. 79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlocksExhausted blocksExhausted; 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 8177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner /// The locations where we stopped because the engine aborted analysis, 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// usually because it could not reason about something. 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlocksAborted blocksAborted; 8477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void generateNode(const ProgramPoint &Loc, 86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *State, 87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred); 88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred); 90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred); 91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred); 92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred); 93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B, 95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred); 96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void HandleCallEnter(const CallEnter &L, const CFGBlock *Block, 97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned Index, ExplodedNode *Pred); 98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void HandleCallExit(const CallExit &L, ExplodedNode *Pred); 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprivate: 101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine(const CoreEngine&); // Do not implement. 102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine& operator=(const CoreEngine&); 103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Construct a CoreEngine object to analyze the provided CFG using 106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// a DFS exploration of the exploded graph. 107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine(SubEngine& subengine) 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : SubEng(subengine), G(new ExplodedGraph()), 109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project WList(WorkList::makeBFS()), 110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BCounterFactory(G->getAllocator()) {} 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Construct a CoreEngine object to analyze the provided CFG and to 113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// use the provided worklist object to execute the worklist algorithm. 114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// The CoreEngine object assumes ownership of 'wlist'. 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine(WorkList* wlist, SubEngine& subengine) 116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : SubEng(subengine), G(new ExplodedGraph()), WList(wlist), 117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BCounterFactory(G->getAllocator()) {} 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ~CoreEngine() { 120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delete WList; 121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// getGraph - Returns the exploded graph. 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedGraph& getGraph() { return *G.get(); } 125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// takeGraph - Returns the exploded graph. Ownership of the graph is 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// transferred to the caller. 128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedGraph* takeGraph() { return G.take(); } 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// ExecuteWorkList - Run the worklist algorithm for a maximum number of 131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// steps. Returns true if there is still simulation state on the worklist. 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool ExecuteWorkList(const LocationContext *L, unsigned Steps, 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *InitState); 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void ExecuteWorkListWithInitialState(const LocationContext *L, 135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned Steps, 136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *InitState, 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNodeSet &Dst); 138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // Functions for external checking of whether we have unfinished work 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool wasBlockAborted() const { return !blocksAborted.empty(); } 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool wasBlocksExhausted() const { return !blocksExhausted.empty(); } 142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool hasWorkRemaining() const { return wasBlocksExhausted() || 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project WList->hasWork() || 144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project wasBlockAborted(); } 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Inform the CoreEngine that a basic block was aborted because 147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// it could not be completely analyzed. 148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) { 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project blocksAborted.push_back(std::make_pair(block, node)); 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project WorkList *getWorkList() const { return WList; } 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlocksExhausted::const_iterator blocks_exhausted_begin() const { 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return blocksExhausted.begin(); 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlocksExhausted::const_iterator blocks_exhausted_end() const { 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return blocksExhausted.end(); 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlocksAborted::const_iterator blocks_aborted_begin() const { 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return blocksAborted.begin(); 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlocksAborted::const_iterator blocks_aborted_end() const { 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return blocksAborted.end(); 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Enqueue the results of the node builder onto the work list. 168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void enqueue(ExplodedNodeSet &NB); 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectstruct NodeBuilderContext { 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine &Eng; 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *Block; 174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *ContextPred; 175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project NodeBuilderContext(CoreEngine &E, const CFGBlock *B, ExplodedNode *N) 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : Eng(E), Block(B), ContextPred(N) { assert(B); assert(!N->isSink()); } 177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Return the CFGBlock associated with this builder. 179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *getBlock() const { return Block; } 180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Returns the number of times the current basic block has been 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// visited on the exploded graph path. 183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned getCurrentBlockCount() const { 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Eng.WList->getBlockCounter().getNumVisited( 185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ContextPred->getLocationContext()->getCurrentStackFrame(), 18677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner Block->getBlockID()); 18777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 18877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 18977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner}; 19077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 19177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner/// This is the simplest builder which generates nodes in the ExplodedGraph. 19277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass NodeBuilder { 19377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerprotected: 19477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const NodeBuilderContext &C; 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Specifies if the builder results have been finalized. For example, if it 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// is set to false, autotransitions are yet to be generated. 198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool Finalized; 199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool HasGeneratedNodes; 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief The frontier set - a set of nodes which need to be propagated after 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// the builder dies. 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNodeSet &Frontier; 205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Checkes if the results are ready. 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project virtual bool checkResults() { 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (!Finalized) 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return false; 210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return true; 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool haveNoSinksInFrontier() { 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (iterator I = Frontier.begin(), E = Frontier.end(); I != E; ++I) { 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ((*I)->isSink()) 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return false; 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return true; 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// Allow subclasses to finalize results before result_begin() is executed. 222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project virtual void finalizeResults() {} 223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateNodeImpl(const ProgramPoint &PP, 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *State, 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred, 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool MarkAsSink = false); 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 229c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turnerpublic: 230c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner NodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const NodeBuilderContext &Ctx, bool F = true) 232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) { 233c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner // assert(DstSet.empty()); 234c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner Frontier.Add(SrcNode); 235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 236295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 237295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner NodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, 238295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner const NodeBuilderContext &Ctx, bool F = true) 239295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner : C(Ctx), Finalized(F), HasGeneratedNodes(false), Frontier(DstSet) { 240a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang //assert(DstSet.empty()); 241a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang //assert(!SrcSet.empty()); 242a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang Frontier.insert(SrcSet); 243a2b9955b49034a51dfbc8bf9f4e9d312149cecacXianzhu Wang assert(haveNoSinksInFrontier()); 244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project virtual ~NodeBuilder() {} 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Generates a node in the ExplodedGraph. 249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// 250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// When a node is marked as sink, the exploration from the node is stopped - 251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// the node becomes the last node on the path. 252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateNode(const ProgramPoint &PP, 253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *State, 254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred, 255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool MarkAsSink = false) { 256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return generateNodeImpl(PP, State, Pred, MarkAsSink); 257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // TODO: will get removed. 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool hasGeneratedNodes() const { 261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return HasGeneratedNodes; 262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ExplodedNodeSet &getResults() { 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project finalizeResults(); 266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(checkResults()); 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Frontier; 268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project typedef ExplodedNodeSet::iterator iterator; 271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /// \brief Iterators through the results frontier. 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project inline iterator begin() { 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project finalizeResults(); 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(checkResults()); 275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Frontier.begin(); 276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project inline iterator end() { 278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project finalizeResults(); 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return Frontier.end(); 280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const NodeBuilderContext &getContext() { return C; } 283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void takeNodes(const ExplodedNodeSet &S) { 285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (ExplodedNodeSet::iterator I = S.begin(), E = S.end(); I != E; ++I ) 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Frontier.erase(*I); 287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void takeNodes(ExplodedNode *N) { 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Frontier.erase(N); 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void addNodes(const ExplodedNodeSet &S) { 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Frontier.insert(S); 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void addNodes(ExplodedNode *N) { 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Frontier.Add(N); 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass CommonNodeBuilder { 304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprotected: 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred; 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine &Eng; 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CommonNodeBuilder(CoreEngine* E, ExplodedNode *P) : Pred(P), Eng(*E) {} 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter(); } 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass PureStmtNodeBuilder: public NodeBuilder { 314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project NodeBuilder *EnclosingBldr; 315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project PureStmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, 317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0) 318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) { 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (EnclosingBldr) 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project EnclosingBldr->takeNodes(SrcNode); 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project PureStmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0) 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) { 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (EnclosingBldr) 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project for (ExplodedNodeSet::iterator I = SrcSet.begin(), 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project E = SrcSet.end(); I != E; ++I ) 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project EnclosingBldr->takeNodes(*I); 330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project virtual ~PureStmtNodeBuilder(); 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateNode(const Stmt *S, 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred, 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *St, 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool MarkAsSink = false, 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramPointTag *tag = 0, 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ProgramPoint::Kind K = ProgramPoint::PostStmtKind, 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool Purging = false) { 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (Purging) { 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project assert(K == ProgramPoint::PostStmtKind); 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project K = ProgramPoint::PostPurgeDeadSymbolsKind; 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K, 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project Pred->getLocationContext(), tag); 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return generateNodeImpl(L, St, Pred, MarkAsSink); 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateNode(const ProgramPoint &PP, 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred, 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *State, 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool MarkAsSink = false) { 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return generateNodeImpl(PP, State, Pred, MarkAsSink); 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass BranchNodeBuilder: public NodeBuilder { 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *DstT; 363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *DstF; 364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool InFeasibleTrue; 366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool InFeasibleFalse; 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BranchNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet, 370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const NodeBuilderContext &C, 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *dstT, const CFGBlock *dstF) 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : NodeBuilder(SrcNode, DstSet, C), DstT(dstT), DstF(dstF), 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BranchNodeBuilder(const ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet, 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const NodeBuilderContext &C, 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *dstT, const CFGBlock *dstF) 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : NodeBuilder(SrcSet, DstSet, C), DstT(dstT), DstF(dstF), 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project InFeasibleTrue(!DstT), InFeasibleFalse(!DstF) {} 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateNode(const ProgramState *State, bool branch, 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred); 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *getTargetBlock(bool branch) const { 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return branch ? DstT : DstF; 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project void markInfeasible(bool branch) { 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if (branch) 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project InFeasibleTrue = true; 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project InFeasibleFalse = true; 393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isFeasible(bool branch) { 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return branch ? !InFeasibleTrue : !InFeasibleFalse; 397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 40077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass IndirectGotoNodeBuilder { 40177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner CoreEngine& Eng; 402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *Src; 403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock &DispatchBlock; 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const Expr *E; 405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred; 406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, 409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const Expr *e, const CFGBlock *dispatch, CoreEngine* eng) 410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {} 411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project class iterator { 413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CFGBlock::const_succ_iterator I; 414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class IndirectGotoNodeBuilder; 416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterator(CFGBlock::const_succ_iterator i) : I(i) {} 417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project public: 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterator &operator++() { ++I; return *this; } 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool operator!=(const iterator &X) const { return I != X.I; } 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const LabelDecl *getLabel() const { 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return llvm::cast<LabelStmt>((*I)->getLabel())->getDecl(); 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *getBlock() const { 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return *I; 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 43077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 43177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner iterator begin() { return iterator(DispatchBlock.succ_begin()); } 432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterator end() { return iterator(DispatchBlock.succ_end()); } 433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateNode(const iterator &I, 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *State, 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isSink = false); 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const Expr *getTarget() const { return E; } 439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *getState() const { return Pred->State; } 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 44377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass SwitchNodeBuilder { 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine& Eng; 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *Src; 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const Expr *Condition; 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *Pred; 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SwitchNodeBuilder(ExplodedNode *pred, const CFGBlock *src, 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const Expr *condition, CoreEngine* eng) 45277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner : Eng(*eng), Src(src), Condition(condition), Pred(pred) {} 453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project class iterator { 455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CFGBlock::const_succ_reverse_iterator I; 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project friend class SwitchNodeBuilder; 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterator(CFGBlock::const_succ_reverse_iterator i) : I(i) {} 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project public: 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterator &operator++() { ++I; return *this; } 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool operator!=(const iterator &X) const { return I != X.I; } 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool operator==(const iterator &X) const { return I == X.I; } 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CaseStmt *getCase() const { 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return llvm::cast<CaseStmt>((*I)->getLabel()); 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *getBlock() const { 470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return *I; 471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterator begin() { return iterator(Src->succ_rbegin()+1); } 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project iterator end() { return iterator(Src->succ_rend()); } 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SwitchStmt *getSwitch() const { 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return llvm::cast<SwitchStmt>(Src->getTerminator()); 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateCaseStmtNode(const iterator &I, 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *State); 48377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 48477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner ExplodedNode *generateDefaultCaseNode(const ProgramState *State, 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool isSink = false); 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const Expr *getCondition() const { return Condition; } 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramState *getState() const { return Pred->State; } 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass GenericNodeBuilderImpl { 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectprotected: 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project CoreEngine &engine; 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *pred; 496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ProgramPoint pp; 497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project SmallVector<ExplodedNode*, 2> sinksGenerated; 498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 49977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner ExplodedNode *generateNodeImpl(const ProgramState *state, 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *pred, 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ProgramPoint programPoint, 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool asSink); 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GenericNodeBuilderImpl(CoreEngine &eng, ExplodedNode *pr, ProgramPoint p) 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : engine(eng), pred(pr), pp(p), hasGeneratedNode(false) {} 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project bool hasGeneratedNode; 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project WorkList &getWorkList() { return *engine.WList; } 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *getPredecessor() const { return pred; } 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project BlockCounter getBlockCounter() const { 515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return engine.WList->getBlockCounter(); 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const SmallVectorImpl<ExplodedNode*> &sinks() const { 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return sinksGenerated; 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projecttemplate <typename PP_T> 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass GenericNodeBuilder : public GenericNodeBuilderImpl { 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project GenericNodeBuilder(CoreEngine &eng, ExplodedNode *pr, const PP_T &p) 527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project : GenericNodeBuilderImpl(eng, pr, p) {} 528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *generateNode(const ProgramState *state, ExplodedNode *pred, 530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const ProgramPointTag *tag, bool asSink) { 531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return generateNodeImpl(state, pred, cast<PP_T>(pp).withTag(tag), 532295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner asSink); 533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const PP_T &getProgramPoint() const { return cast<PP_T>(pp); } 536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 53777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 53877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass EndOfFunctionNodeBuilder : public CommonNodeBuilder { 539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock &B; 54077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ProgramPointTag *Tag; 54177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 54277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerpublic: 54377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner bool hasGeneratedNode; 54477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectpublic: 546295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner EndOfFunctionNodeBuilder(const CFGBlock *b, ExplodedNode *N, CoreEngine* e, 547295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner const ProgramPointTag *tag = 0) 548295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner : CommonNodeBuilder(e, N), B(*b), Tag(tag), hasGeneratedNode(false) {} 549295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner 55077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner ~EndOfFunctionNodeBuilder(); 55177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 55277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner EndOfFunctionNodeBuilder withCheckerTag(const ProgramPointTag *tag) { 55377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner return EndOfFunctionNodeBuilder(&B, Pred, &Eng, tag); 554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 55577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 55677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner WorkList &getWorkList() { return *Eng.WList; } 55777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 55877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner ExplodedNode *getPredecessor() const { return Pred; } 559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 56077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner unsigned getCurrentBlockCount() const { 56177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner return getBlockCounter().getNumVisited( 56277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner Pred->getLocationContext()->getCurrentStackFrame(), 563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project B.getBlockID()); 56477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 56577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 56677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner ExplodedNode *generateNode(const ProgramState *State, 567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ExplodedNode *P = 0, 56877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ProgramPointTag *tag = 0); 56977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 57077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner void GenerateCallExitNode(const ProgramState *state); 57177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *getBlock() const { return &B; } 57377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 57477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ProgramState *getState() const { 57577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner return getPredecessor()->getState(); 57677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner } 577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project}; 57877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 57977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerclass CallEnterNodeBuilder { 58077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner CoreEngine &Eng; 581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 58277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ExplodedNode *Pred; 58377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 58477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner // The call site. For implicit automatic object dtor, this is the trigger 58577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner // statement. 586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const Stmt *CE; 58777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 58877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner // The context of the callee. 58977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const StackFrameContext *CalleeCtx; 59077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project // The parent block of the CallExpr. 59277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const CFGBlock *Block; 59377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 59477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner // The CFGBlock index of the CallExpr. 595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project unsigned Index; 59677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 59777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerpublic: 59877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner CallEnterNodeBuilder(CoreEngine &eng, const ExplodedNode *pred, 59977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const Stmt *s, const StackFrameContext *callee, 600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *blk, unsigned idx) 60177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner : Eng(eng), Pred(pred), CE(s), CalleeCtx(callee), Block(blk), Index(idx) {} 60277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 60377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ProgramState *getState() const { return Pred->getState(); } 604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 60577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const LocationContext *getLocationContext() const { 60677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner return Pred->getLocationContext(); 607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 60877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 60977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const Stmt *getCallExpr() const { return CE; } 610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 61177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const StackFrameContext *getCalleeContext() const { return CalleeCtx; } 61277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project const CFGBlock *getBlock() const { return Block; } 61477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 61577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner unsigned getIndex() const { return Index; } 616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 61777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner void generateNode(const ProgramState *state); 61877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner}; 619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Projectclass CallExitNodeBuilder { 62177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner CoreEngine &Eng; 62277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ExplodedNode *Pred; 62377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 62477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turnerpublic: 62577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner CallExitNodeBuilder(CoreEngine &eng, const ExplodedNode *pred) 62677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner : Eng(eng), Pred(pred) {} 62777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 62877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ExplodedNode *getPredecessor() const { return Pred; } 62977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 63077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner const ProgramState *getState() const { return Pred->getState(); } 63177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 63277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner void generateNode(const ProgramState *state); 63377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner}; 63477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 63577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner} // end GR namespace 63677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 63777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner} // end clang namespace 63877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner 63977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif 64077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner