Home | History | Annotate | Download | only in PathSensitive
      1 //== SubEngine.h - Interface of the subengine of CoreEngine --------*- C++ -*-//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the interface of a subengine of the CoreEngine.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #ifndef LLVM_CLANG_GR_SUBENGINE_H
     14 #define LLVM_CLANG_GR_SUBENGINE_H
     15 
     16 #include "clang/Analysis/ProgramPoint.h"
     17 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
     18 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
     19 
     20 namespace clang {
     21 
     22 class CFGBlock;
     23 class CFGElement;
     24 class LocationContext;
     25 class Stmt;
     26 
     27 namespace ento {
     28 
     29 struct NodeBuilderContext;
     30 class AnalysisManager;
     31 class ExplodedNodeSet;
     32 class ExplodedNode;
     33 class ProgramState;
     34 class ProgramStateManager;
     35 class BlockCounter;
     36 class BranchNodeBuilder;
     37 class IndirectGotoNodeBuilder;
     38 class SwitchNodeBuilder;
     39 class EndOfFunctionNodeBuilder;
     40 class NodeBuilderWithSinks;
     41 class MemRegion;
     42 
     43 class SubEngine {
     44   virtual void anchor();
     45 public:
     46   virtual ~SubEngine() {}
     47 
     48   virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0;
     49 
     50   virtual AnalysisManager &getAnalysisManager() = 0;
     51 
     52   virtual ProgramStateManager &getStateManager() = 0;
     53 
     54   /// Called by CoreEngine. Used to generate new successor
     55   /// nodes by processing the 'effects' of a block-level statement.
     56   virtual void processCFGElement(const CFGElement E, ExplodedNode* Pred,
     57                                  unsigned StmtIdx, NodeBuilderContext *Ctx)=0;
     58 
     59   /// Called by CoreEngine when it starts processing a CFGBlock.  The
     60   /// SubEngine is expected to populate dstNodes with new nodes representing
     61   /// updated analysis state, or generate no nodes at all if it doesn't.
     62   virtual void processCFGBlockEntrance(const BlockEdge &L,
     63                                        NodeBuilderWithSinks &nodeBuilder) = 0;
     64 
     65   /// Called by CoreEngine.  Used to generate successor
     66   ///  nodes by processing the 'effects' of a branch condition.
     67   virtual void processBranch(const Stmt *Condition, const Stmt *Term,
     68                              NodeBuilderContext& BuilderCtx,
     69                              ExplodedNode *Pred,
     70                              ExplodedNodeSet &Dst,
     71                              const CFGBlock *DstT,
     72                              const CFGBlock *DstF) = 0;
     73 
     74   /// Called by CoreEngine.  Used to generate successor
     75   /// nodes by processing the 'effects' of a computed goto jump.
     76   virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0;
     77 
     78   /// Called by CoreEngine.  Used to generate successor
     79   /// nodes by processing the 'effects' of a switch statement.
     80   virtual void processSwitch(SwitchNodeBuilder& builder) = 0;
     81 
     82   /// Called by CoreEngine.  Used to generate end-of-path
     83   /// nodes when the control reaches the end of a function.
     84   virtual void processEndOfFunction(NodeBuilderContext& BC) = 0;
     85 
     86   // Generate the entry node of the callee.
     87   virtual void processCallEnter(CallEnter CE, ExplodedNode *Pred) = 0;
     88 
     89   // Generate the first post callsite node.
     90   virtual void processCallExit(ExplodedNode *Pred) = 0;
     91 
     92   /// Called by ConstraintManager. Used to call checker-specific
     93   /// logic for handling assumptions on symbolic values.
     94   virtual ProgramStateRef processAssume(ProgramStateRef state,
     95                                        SVal cond, bool assumption) = 0;
     96 
     97   /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
     98   ///  region change should trigger a processRegionChanges update.
     99   virtual bool wantsRegionChangeUpdate(ProgramStateRef state) = 0;
    100 
    101   /// processRegionChanges - Called by ProgramStateManager whenever a change is
    102   /// made to the store. Used to update checkers that track region values.
    103   virtual ProgramStateRef
    104   processRegionChanges(ProgramStateRef state,
    105                        const StoreManager::InvalidatedSymbols *invalidated,
    106                        ArrayRef<const MemRegion *> ExplicitRegions,
    107                        ArrayRef<const MemRegion *> Regions,
    108                        const CallEvent *Call) = 0;
    109 
    110 
    111   inline ProgramStateRef
    112   processRegionChange(ProgramStateRef state,
    113                       const MemRegion* MR) {
    114     return processRegionChanges(state, 0, MR, MR, 0);
    115   }
    116 
    117   /// printState - Called by ProgramStateManager to print checker-specific data.
    118   virtual void printState(raw_ostream &Out, ProgramStateRef State,
    119                           const char *NL, const char *Sep) = 0;
    120 
    121   /// Called by CoreEngine when the analysis worklist is either empty or the
    122   //  maximum number of analysis steps have been reached.
    123   virtual void processEndWorklist(bool hasWorkRemaining) = 0;
    124 };
    125 
    126 } // end GR namespace
    127 
    128 } // end clang namespace
    129 
    130 #endif
    131