ExprEngine.h revision 769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5
1d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis//===-- ExprEngine.h - Path-Sensitive Expression-Level Dataflow ---*- C++ -*-=//
277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//
377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//                     The LLVM Compiler Infrastructure
477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//
577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// This file is distributed under the University of Illinois Open Source
677349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek// License. See LICENSE.TXT for details.
777349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//
877349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//===----------------------------------------------------------------------===//
977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//
10b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek//  This file defines a meta-engine for path-sensitive dataflow analysis that
11d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis//  is built on CoreEngine, but provides the boilerplate to execute transfer
12b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek//  functions and build the ExplodedGraph at the expression level.
1377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//
1477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek//===----------------------------------------------------------------------===//
1577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek
16d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis#ifndef LLVM_CLANG_GR_EXPRENGINE
17d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis#define LLVM_CLANG_GR_EXPRENGINE
18d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek
199b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
209b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
219b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
229b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
239b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h"
249b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
25c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek#include "clang/AST/Type.h"
26f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "clang/AST/ExprObjC.h"
27bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu#include "clang/AST/ExprCXX.h"
284beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek#include "clang/AST/StmtObjC.h"
2977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek
301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpnamespace clang {
315a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
325a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisclass ObjCForCollectionStmt;
335a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
349ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremeneknamespace ento {
355a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
365e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramerclass AnalysisManager;
375e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramerclass Checker;
38f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff
39d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidisclass ExprEngine : public SubEngine {
4025e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  AnalysisManager &AMgr;
4125e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu
42d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  CoreEngine Engine;
431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// G - the simulation graph.
45031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedGraph& G;
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// Builder - The current StmtNodeBuilder which is used when building the
48b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  ///  nodes for a given statement.
49d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  StmtNodeBuilder* Builder;
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
51b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// StateMgr - Object that manages the data for all created states.
524adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek  GRStateManager StateMgr;
53cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
54b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// SymMgr - Object that manages the symbol information.
55b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  SymbolManager& SymMgr;
561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek  /// svalBuilder - SValBuilder object that creates SVals from expressions.
58846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek  SValBuilder &svalBuilder;
591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek  /// EntryNode - The immediate predecessor node.
61031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedNode* EntryNode;
62846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek
63846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek  /// CleanedState - The state for EntryNode "cleaned" of all dead
640d093d3005dd583675a45a85bd688063572cc8afTed Kremenek  ///  variables and symbols (as determined by a liveness analysis).
651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const GRState* CleanedState;
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
670a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  /// currentStmt - The current block-level statement.
680a3ed3143b00f237decb1288c1ff574ae09eba4eTed Kremenek  const Stmt* currentStmt;
691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek  // Obj-C Class Identifiers.
71e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek  IdentifierInfo* NSExceptionII;
721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek  // Obj-C Selectors.
74e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek  Selector* NSExceptionInstanceRaiseSelectors;
75e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek  Selector RaiseSel;
761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  enum CallbackKind {
7872905cfa81cfd126f322c4173f56d332aac5539eJordy Rose    PreVisitStmtCallback,
7972905cfa81cfd126f322c4173f56d332aac5539eJordy Rose    PostVisitStmtCallback,
80e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek    processAssumeCallback,
81c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose    EvalRegionChangesCallback
8272905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  };
8372905cfa81cfd126f322c4173f56d332aac5539eJordy Rose
8472905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  typedef uint32_t CallbackTag;
8572905cfa81cfd126f322c4173f56d332aac5539eJordy Rose
8672905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  /// GetCallbackTag - Create a tag for a certain kind of callback. The 'Sub'
8772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  ///  argument can be used to differentiate callbacks that depend on another
8872905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  ///  value from a small set of possibilities, such as statement classes.
8972905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  static inline CallbackTag GetCallbackTag(CallbackKind K, uint32_t Sub = 0) {
9072905cfa81cfd126f322c4173f56d332aac5539eJordy Rose    assert(Sub == ((Sub << 8) >> 8) && "Tag sub-kind must fit into 24 bits");
9172905cfa81cfd126f322c4173f56d332aac5539eJordy Rose    return K | (Sub << 8);
9272905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  }
9372905cfa81cfd126f322c4173f56d332aac5539eJordy Rose
94094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek  typedef llvm::DenseMap<void *, unsigned> CheckerMap;
95b94b81a9ab46c99b00c7ad28c5e1e212c63fc9acZhongxing Xu  typedef std::vector<std::pair<void *, Checker*> > CheckersOrdered;
9672905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  typedef llvm::DenseMap<CallbackTag, CheckersOrdered *> CheckersOrderedCache;
979e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek
989e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  /// A registration map from checker tag to the index into the
999e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  ///  ordered checkers vector.
1009e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  CheckerMap CheckerM;
1019e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek
1029e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  /// An ordered vector of checkers that are called when evaluating
1039e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  ///  various expressions and statements.
104094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek  CheckersOrdered Checkers;
105ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09fZhongxing Xu
1069e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  /// A map used for caching the checkers that respond to the callback for
10772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose  ///  a particular callback tag.
1089e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  CheckersOrderedCache COCache;
1099e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek
1109e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  /// The BugReporter associated with this engine.  It is important that
1119e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek  ///  this object be placed at the very end of member variables so that its
112d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ///  destructor is called before the rest of the ExprEngine is destroyed.
113cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  GRBugReporter BR;
11432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek
115d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  llvm::OwningPtr<TransferFuncs> TF;
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
117b22d589e2ccd09cada0bcea136f0966883a8bb11Ted Kremenekpublic:
118d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ExprEngine(AnalysisManager &mgr, TransferFuncs *tf);
119cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
120d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  ~ExprEngine();
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12225e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu  void ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
123d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    Engine.ExecuteWorkList(L, Steps, 0);
1242ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  }
1252ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu
1262ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  /// Execute the work list with an initial state. Nodes that reaches the exit
1272ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  /// of the function are added into the Dst set, which represent the exit
1282ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  /// state of the function call.
1292ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  void ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps,
1302ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu                                       const GRState *InitState,
1312ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu                                       ExplodedNodeSet &Dst) {
132d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst);
133b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  }
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
135b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// getContext - Return the ASTContext associated with this analysis.
136c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu  ASTContext& getContext() const { return AMgr.getASTContext(); }
1375032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu
1382ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  virtual AnalysisManager &getAnalysisManager() { return AMgr; }
1391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerManager &getCheckerManager() const {
141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    return *AMgr.getCheckerManager();
142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
144846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek  SValBuilder &getSValBuilder() { return svalBuilder; }
1451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
146d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  TransferFuncs& getTF() { return *TF; }
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
148cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugReporter& getBugReporter() { return BR; }
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
150d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  StmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; }
151ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu
152d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  // FIXME: Remove once TransferFuncs is no longer referenced.
153d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  void setTransferFunction(TransferFuncs* tf);
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
155e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek  /// ViewGraph - Visualize the ExplodedGraph created by executing the
156e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek  ///  simulation.
157ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek  void ViewGraph(bool trim = false);
1581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
159031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  void ViewGraph(ExplodedNode** Beg, ExplodedNode** End);
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
161b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// getInitialState - Return the initial state used for the root vertex
162b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  ///  in the ExplodedGraph.
16317fd8632dcda97022a51effc24060eacdad9dbe0Zhongxing Xu  const GRState* getInitialState(const LocationContext *InitLoc);
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
165031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  ExplodedGraph& getGraph() { return G; }
166031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const ExplodedGraph& getGraph() const { return G; }
16750a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
168ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu  template <typename CHECKER>
169094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek  void registerCheck(CHECKER *check) {
170094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek    unsigned entry = Checkers.size();
171094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek    void *tag = CHECKER::getTag();
172094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek    Checkers.push_back(std::make_pair(tag, check));
173094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek    CheckerM[tag] = entry;
174ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu  }
175094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek
176094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek  Checker *lookupChecker(void *tag) const;
177ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu
178ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu  template <typename CHECKER>
179094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek  CHECKER *getChecker() const {
180094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek     return static_cast<CHECKER*>(lookupChecker(CHECKER::getTag()));
1815a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek  }
1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
183e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  /// processCFGElement - Called by CoreEngine. Used to generate new successor
1849c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu  ///  nodes by processing the 'effects' of a CFG element.
185e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processCFGElement(const CFGElement E, StmtNodeBuilder& builder);
1869c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
187d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  void ProcessStmt(const CFGStmt S, StmtNodeBuilder &builder);
1889c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
189d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  void ProcessInitializer(const CFGInitializer I, StmtNodeBuilder &builder);
1909c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu
191d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  void ProcessImplicitDtor(const CFGImplicitDtor D, StmtNodeBuilder &builder);
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1934ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
194d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                            StmtNodeBuilder &builder);
195d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  void ProcessBaseDtor(const CFGBaseDtor D, StmtNodeBuilder &builder);
196d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  void ProcessMemberDtor(const CFGMemberDtor D, StmtNodeBuilder &builder);
1974ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu  void ProcessTemporaryDtor(const CFGTemporaryDtor D,
198d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                            StmtNodeBuilder &builder);
1994ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu
20027c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek  /// Called by CoreEngine when processing the entrance of a CFGBlock.
20127c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek  virtual void processCFGBlockEntrance(ExplodedNodeSet &dstNodes,
20227c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek                                GenericNodeBuilder<BlockEntrance> &nodeBuilder);
20327c54e57c4a012dcdf2b40cf985b70d0b9caa69eTed Kremenek
204d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// ProcessBranch - Called by CoreEngine.  Used to generate successor
205b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  ///  nodes by processing the 'effects' of a branch condition.
206e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processBranch(const Stmt* Condition, const Stmt* Term,
207d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis                     BranchNodeBuilder& builder);
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
209e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
210b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  ///  nodes by processing the 'effects' of a computed goto jump.
211e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processIndirectGoto(IndirectGotoNodeBuilder& builder);
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
213d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
214b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  ///  nodes by processing the 'effects' of a switch statement.
215e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processSwitch(SwitchNodeBuilder& builder);
2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
217d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// ProcessEndPath - Called by CoreEngine.  Used to generate end-of-path
21811062b118476368fa5b294954713e5df97d8599fTed Kremenek  ///  nodes when the control reaches the end of a function.
219e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processEndOfFunction(EndOfFunctionNodeBuilder& builder);
220102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
221ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek  /// Generate the entry node of the callee.
222e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processCallEnter(CallEnterNodeBuilder &builder);
223102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
224ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek  /// Generate the first post callsite node.
225e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processCallExit(CallExitNodeBuilder &builder);
226102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor
227d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  /// Called by CoreEngine when the analysis worklist has terminated.
228e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  void processEndWorklist(bool hasWorkRemaining);
229ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek
2309c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  /// evalAssume - Callback function invoked by the ConstraintManager when
23132a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek  ///  making assumptions about state values.
232e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  const GRState *processAssume(const GRState *state, SVal cond,bool assumption);
2331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
234e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  /// wantsRegionChangeUpdate - Called by GRStateManager to determine if a
235e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  ///  region change should trigger a processRegionChanges update.
236e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  bool wantsRegionChangeUpdate(const GRState* state);
237c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose
238e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  /// processRegionChanges - Called by GRStateManager whenever a change is made
239c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose  ///  to the store. Used to update checkers that track region values.
240e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek  const GRState* processRegionChanges(const GRState *state,
241c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose                                      const MemRegion * const *Begin,
242c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose                                      const MemRegion * const *End);
243c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose
2442ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu  virtual GRStateManager& getStateManager() { return StateMgr; }
24590e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu
24690e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu  StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
248a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek  ConstraintManager& getConstraintManager() {
249a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek    return StateMgr.getConstraintManager();
250a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek  }
2511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
252c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  // FIXME: Remove when we migrate over to just using SValBuilder.
2536297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek  BasicValueFactory& getBasicVals() {
2546297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek    return StateMgr.getBasicVals();
2556297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek  }
2566297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek  const BasicValueFactory& getBasicVals() const {
2576297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek    return StateMgr.getBasicVals();
2586297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek  }
2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
260044b6f0417cb98741f277602fabf5f07ec9a02c0Ted Kremenek  // FIXME: Remove when we migrate over to just using ValueManager.
26100a3a5f024ac54088ab887712b292171188064f0Ted Kremenek  SymbolManager& getSymbolManager() { return SymMgr; }
26200a3a5f024ac54088ab887712b292171188064f0Ted Kremenek  const SymbolManager& getSymbolManager() const { return SymMgr; }
2631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
264bc42c533e7d3d946704a49e242939dd232f33072Tom Care  // Functions for external checking of whether we have unfinished work
265d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  bool wasBlockAborted() const { return Engine.wasBlockAborted(); }
266d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
267bc42c533e7d3d946704a49e242939dd232f33072Tom Care  bool hasWorkRemaining() const {
268d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    return wasBlockAborted() || Engine.getWorkList()->hasWork();
269bc42c533e7d3d946704a49e242939dd232f33072Tom Care  }
270bc42c533e7d3d946704a49e242939dd232f33072Tom Care
271d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis  const CoreEngine &getCoreEngine() const { return Engine; }
272bc42c533e7d3d946704a49e242939dd232f33072Tom Care
27305a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenekprotected:
274031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu  const GRState* GetState(ExplodedNode* N) {
275846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek    return N == EntryNode ? CleanedState : N->getState();
276512c913a6f93d225faacdb8e20308f5c4065c3ebTed Kremenek  }
2771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2781670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic:
2793992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu  ExplodedNode* MakeNode(ExplodedNodeSet& Dst, const Stmt* S,
2803992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu                         ExplodedNode* Pred, const GRState* St,
281bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu                         ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
282bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu                         const void *tag = 0);
2837b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu
2845a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek  /// CheckerVisit - Dispatcher for performing checker-specific logic
2855a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek  ///  at specific statements.
28603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void CheckerVisit(const Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
28772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose                    CallbackKind Kind);
288a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu
289432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis  void CheckerVisitObjCMessage(const ObjCMessage &msg, ExplodedNodeSet &Dst,
290432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis                               ExplodedNodeSet &Src, bool isPrevisit);
291432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis
292935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu  bool CheckerEvalCall(const CallExpr *CE,
293935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu                       ExplodedNodeSet &Dst,
294935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu                       ExplodedNode *Pred);
295935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu
296432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis  void CheckerEvalNilReceiver(const ObjCMessage &msg,
297a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu                              ExplodedNodeSet &Dst,
298a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu                              const GRState *state,
299a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu                              ExplodedNode *Pred);
300b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek
30179d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek  void CheckerVisitBind(const Stmt *StoreE, ExplodedNodeSet &Dst,
30279d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek                        ExplodedNodeSet &Src,  SVal location, SVal val,
30379d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek                        bool isPrevisit);
304ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu
305b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// Visit - Transfer function logic for all statements.  Dispatches to
306b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  ///  other functions that handle specific kinds of statements.
30703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void Visit(const Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst);
3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
309c5b1bf10133a8ecbfe9e6b3ec92bae84e3d927e8Ted Kremenek  /// VisitArraySubscriptExpr - Transfer function for array accesses.
310892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  void VisitLvalArraySubscriptExpr(const ArraySubscriptExpr* Ex,
311892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                   ExplodedNode* Pred,
312892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                   ExplodedNodeSet& Dst);
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
314ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek  /// VisitAsmStmt - Transfer function logic for inline asm.
31503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitAsmStmt(const AsmStmt* A, ExplodedNode* Pred, ExplodedNodeSet& Dst);
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitAsmStmtHelperOutputs(const AsmStmt* A,
31803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                                 AsmStmt::const_outputs_iterator I,
31903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                                 AsmStmt::const_outputs_iterator E,
320031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                                 ExplodedNode* Pred, ExplodedNodeSet& Dst);
3211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
32203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitAsmStmtHelperInputs(const AsmStmt* A,
32303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                                AsmStmt::const_inputs_iterator I,
32403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                                AsmStmt::const_inputs_iterator E,
325031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                                ExplodedNode* Pred, ExplodedNodeSet& Dst);
326c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek
327c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek  /// VisitBlockExpr - Transfer function logic for BlockExprs.
32803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred,
32903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                      ExplodedNodeSet &Dst);
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
331b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// VisitBinaryOperator - Transfer function logic for binary operators.
33203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode* Pred,
333892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                           ExplodedNodeSet& Dst);
334469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek
3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
336de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek  /// VisitCall - Transfer function for function calls.
33703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCall(const CallExpr* CE, ExplodedNode* Pred,
33803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                 CallExpr::const_arg_iterator AI,
33903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                 CallExpr::const_arg_iterator AE,
340892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                 ExplodedNodeSet& Dst);
3411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
342b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// VisitCast - Transfer function logic for all casts (implicit and explicit).
34303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCast(const CastExpr *CastE, const Expr *Ex, ExplodedNode *Pred,
344892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                ExplodedNodeSet &Dst);
345e1c2a675e0c089e1f53cbd55d2197a8beaa852aeTed Kremenek
3464f09027385466f1f4c382c80ca77157e2aef97d9Ted Kremenek  /// VisitCompoundLiteralExpr - Transfer function logic for compound literals.
34703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCompoundLiteralExpr(const CompoundLiteralExpr* CL,
348892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                ExplodedNode* Pred, ExplodedNodeSet& Dst);
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
350892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs.
35103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCommonDeclRefExpr(const Expr* DR, const NamedDecl *D,
352892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                              ExplodedNode* Pred, ExplodedNodeSet& Dst);
35367d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek
354b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// VisitDeclStmt - Transfer function logic for DeclStmts.
35503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitDeclStmt(const DeclStmt* DS, ExplodedNode* Pred,
35603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                     ExplodedNodeSet& Dst);
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
358b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose
35903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitGuardedExpr(const Expr* Ex, const Expr* L, const Expr* R,
36003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                        ExplodedNode* Pred, ExplodedNodeSet& Dst);
361c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu
362fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek  /// VisitCondInit - Transfer function for handling the initialization
363fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek  ///  of a condition variable in an IfStmt, SwitchStmt, etc.
36403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCondInit(const VarDecl *VD, const Stmt *S, ExplodedNode *Pred,
365fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek                     ExplodedNodeSet& Dst);
36661dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek
36703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitInitListExpr(const InitListExpr* E, ExplodedNode* Pred,
368c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek                         ExplodedNodeSet& Dst);
369c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu
370b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// VisitLogicalExpr - Transfer function logic for '&&', '||'
37103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitLogicalExpr(const BinaryOperator* B, ExplodedNode* Pred,
372c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek                        ExplodedNodeSet& Dst);
3731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
374469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek  /// VisitMemberExpr - Transfer function for member expressions.
37503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitMemberExpr(const MemberExpr* M, ExplodedNode* Pred,
376892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                           ExplodedNodeSet& Dst);
3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3784beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek  /// Transfer function logic for ObjCAtSynchronizedStmts.
3794beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek  void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S,
3804beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
3814beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek
38214429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E,
38314429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
38414429b918bd2f4cb52abc75546a7fe37142054caArgyrios Kyrtzidis
385892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  /// Transfer function logic for computing the lvalue of an Objective-C ivar.
386892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek  void VisitLvalObjCIvarRefExpr(const ObjCIvarRefExpr* DR, ExplodedNode* Pred,
387892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                ExplodedNodeSet& Dst);
388af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek
389af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek  /// VisitObjCForCollectionStmt - Transfer function logic for
390af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek  ///  ObjCForCollectionStmt.
39103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitObjCForCollectionStmt(const ObjCForCollectionStmt* S,
39203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                                  ExplodedNode* Pred, ExplodedNodeSet& Dst);
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitObjCForCollectionStmtAux(const ObjCForCollectionStmt* S,
395bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu                                     ExplodedNode* Pred,
396031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                                     ExplodedNodeSet& Dst, SVal ElementV);
3971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
398469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek  /// VisitObjCMessageExpr - Transfer function for ObjC message expressions.
39903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitObjCMessageExpr(const ObjCMessageExpr* ME, ExplodedNode* Pred,
400892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                            ExplodedNodeSet& Dst);
4015286e2ddfd8332520de4c076e49991d6fe557adbArgyrios Kyrtzidis  void VisitObjCMessage(const ObjCMessage &msg, ExplodedNodeSet &Src,
4025286e2ddfd8332520de4c076e49991d6fe557adbArgyrios Kyrtzidis                        ExplodedNodeSet& Dst);
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
40402737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek  /// VisitReturnStmt - Transfer function logic for return statements.
40503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitReturnStmt(const ReturnStmt* R, ExplodedNode* Pred,
40603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                       ExplodedNodeSet& Dst);
4078ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor
4088ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor  /// VisitOffsetOfExpr - Transfer function for offsetof.
40903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitOffsetOfExpr(const OffsetOfExpr* Ex, ExplodedNode* Pred,
4108ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor                         ExplodedNodeSet& Dst);
4111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4120518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl  /// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
41303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
414031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu                              ExplodedNodeSet& Dst);
4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
416b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  /// VisitUnaryOperator - Transfer function logic for unary operators.
41703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode* Pred,
418892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                          ExplodedNodeSet& Dst);
419bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu
42003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
421bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu                        ExplodedNodeSet & Dst);
422d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu
423d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu  void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr,
424892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
425892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek    VisitCXXConstructExpr(expr, 0, Pred, Dst);
426d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu  }
427d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu
4287ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu  void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest,
429892697dd2287caf7c29aaaa82909b0e90b8b63feTed Kremenek                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
430950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu
431b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu  void VisitCXXDestructor(const CXXDestructorDecl *DD,
432b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                          const MemRegion *Dest, const Stmt *S,
433b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
434b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu
435950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu  void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
436950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu                              ExplodedNodeSet &Dst);
437950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu
4386a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *C,
4396a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
4406a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski
44103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
442856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu                       ExplodedNodeSet &Dst);
443856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu
44403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
4456b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu                          ExplodedNodeSet &Dst);
4466b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu
4477ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu  void VisitAggExpr(const Expr *E, const MemRegion *Dest, ExplodedNode *Pred,
4487b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu                    ExplodedNodeSet &Dst);
4497b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu
450bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu  /// Create a C++ temporary object for an rvalue.
45103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  void CreateCXXTemporaryObject(const Expr *Ex, ExplodedNode *Pred,
452bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu                                ExplodedNodeSet &Dst);
453bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu
4548e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu  /// Synthesize CXXThisRegion.
4559dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu  const CXXThisRegion *getCXXThisRegion(const CXXRecordDecl *RD,
4568e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu                                        const StackFrameContext *SFC);
4578e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu
45832303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu  const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *decl,
45932303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu                                        const StackFrameContext *frameCtx);
46032303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu
461b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu  /// Evaluate arguments with a work list algorithm.
4629c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalArguments(ConstExprIterator AI, ConstExprIterator AE,
463b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu                     const FunctionProtoType *FnType,
46482c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski                     ExplodedNode *Pred, ExplodedNodeSet &Dst,
46582c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski                     bool FstArgAsLValue = false);
466b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu
4676a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  /// Evaluate method call itself. Used for CXXMethodCallExpr and
4686a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski  /// CXXOperatorCallExpr.
4699c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalMethodCall(const CallExpr *MCE, const CXXMethodDecl *MD,
4706a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski                      const Expr *ThisExpr, ExplodedNode *Pred,
4716a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski                      ExplodedNodeSet &Src, ExplodedNodeSet &Dst);
4726a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski
4739c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  /// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
47448af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek  ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
47548af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek  ///  with those assumptions.
4769c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalEagerlyAssume(ExplodedNodeSet& Dst, ExplodedNodeSet& Src,
47703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                         const Expr *Ex);
4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4799c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  SVal evalMinus(SVal X) {
4809c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    return X.isValid() ? svalBuilder.evalMinus(cast<NonLoc>(X)) : X;
481b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek  }
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4839c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  SVal evalComplement(SVal X) {
4849c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    return X.isValid() ? svalBuilder.evalComplement(cast<NonLoc>(X)) : X;
48590e420321f60860f4c4e7a68ca9f7567824b46ecTed Kremenek  }
486248072a8b9cd956c4ac63172fc2af09790f7c6a9Zhongxing Xu
4871670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic:
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4899c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
490cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek                 NonLoc L, NonLoc R, QualType T) {
4919c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    return svalBuilder.evalBinOpNN(state, op, L, R, T);
4926297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek  }
49310c16657eec144def180ee53d1e0249c9ed2b3b5Ted Kremenek
4949c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  SVal evalBinOp(const GRState *state, BinaryOperator::Opcode op,
495cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek                 NonLoc L, SVal R, QualType T) {
4969c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    return R.isValid() ? svalBuilder.evalBinOpNN(state,op,L, cast<NonLoc>(R), T) : R;
497b640b3b5dfccaf259967cb2cb6755c9aa20d4423Ted Kremenek  }
4981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4999c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  SVal evalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
500ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek                 SVal LHS, SVal RHS, QualType T) {
5019c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek    return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T);
502ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek  }
5035b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek
5041670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekprotected:
505432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis  void evalObjCMessage(ExplodedNodeSet& Dst, const ObjCMessage &msg,
506432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis                       ExplodedNode* Pred, const GRState *state) {
507d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis    assert (Builder && "StmtNodeBuilder must be defined.");
508432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis    getTF().evalObjCMessage(Dst, *this, *Builder, msg, Pred, state);
509de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek  }
5101670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek
51103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu  const GRState* MarkBranch(const GRState* St, const Stmt* Terminator,
5121670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek                            bool branchTaken);
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5149c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  /// evalBind - Handle the semantics of binding a value to a specific location.
5159c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  ///  This method is used by evalStore, VisitDeclStmt, and others.
5169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred,
517f6f56d4fc8ebce17e7b83eb2c35f57a055c22283Ted Kremenek                const GRState* St, SVal location, SVal Val,
518f6f56d4fc8ebce17e7b83eb2c35f57a055c22283Ted Kremenek                bool atDeclInit = false);
5191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5201670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenekpublic:
521b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  // FIXME: 'tag' should be removed, and a LocationContext should be used
522b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  // instead.
523834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  // FIXME: Comment on the meaning of the arguments, when 'St' may not
524834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  // be the same as Pred->state, and when 'location' may not be the
525834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  // same as state->getLValue(Ex).
526834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan  /// Simulate a read of the result of Ex.
5279c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalLoad(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
528652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu                const GRState* St, SVal location, const void *tag = 0,
529652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu                QualType LoadTy = QualType());
5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
531b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  // FIXME: 'tag' should be removed, and a LocationContext should be used
532b4b817d704287836b52b34369009e682f208aa2bTed Kremenek  // instead.
5339c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalStore(ExplodedNodeSet& Dst, const Expr* AssignE, const Expr* StoreE,
534b4b817d704287836b52b34369009e682f208aa2bTed Kremenek                 ExplodedNode* Pred, const GRState* St, SVal TargetLV, SVal Val,
5351670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek                 const void *tag = 0);
536834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wanprivate:
5379c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalLoadCommon(ExplodedNodeSet& Dst, const Expr* Ex, ExplodedNode* Pred,
538852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                      const GRState* St, SVal location, const void *tag,
539852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                      QualType LoadTy);
540852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
541852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  // FIXME: 'tag' should be removed, and a LocationContext should be used
542852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek  // instead.
5439c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek  void evalLocation(ExplodedNodeSet &Dst, const Stmt *S, ExplodedNode* Pred,
544852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                    const GRState* St, SVal location,
545852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek                    const void *tag, bool isLoad);
5461c625f25055331bf76ab5479a8060d2b0f61e8b8Zhongxing Xu
5471c625f25055331bf76ab5479a8060d2b0f61e8b8Zhongxing Xu  bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred);
548b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek};
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55065423aeb996a296cf2964f136ce4a4a937bd1687Zhongxing Xu} // end ento namespace
5515a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis
552c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek} // end clang namespace
553c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek
554d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek#endif
555