CheckerManager.h revision 537716ad8dd10f984b6cfe6985afade1185c5e3c
143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
1043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Defines the Static Analyzer Checker Manager.
1143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
1243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
1343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
172e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h"
1843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "llvm/ADT/SmallVector.h"
199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "llvm/ADT/DenseMap.h"
20769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "llvm/ADT/FoldingSet.h"
2135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include <vector>
2343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
2443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace clang {
259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class Decl;
26769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class Stmt;
27e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class CallExpr;
2843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
2943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace ento {
30ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  class CheckerBase;
3143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  class ExprEngine;
329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class AnalysisManager;
339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class BugReporter;
34769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class CheckerContext;
35769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ObjCMessage;
36769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class SVal;
37e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class ExplodedNode;
38769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ExplodedNodeSet;
3930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  class ExplodedGraph;
4018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  class ProgramState;
41af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  class EndOfFunctionNodeBuilder;
42cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  class BranchNodeBuilder;
43183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class MemRegion;
44183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class SymbolReaper;
45769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
46e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass GraphExpander {
47e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic:
48e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  virtual ~GraphExpander();
49e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0;
50e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis};
51e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
524d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename T> class CheckerFn;
534d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
5435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenektemplate <typename RET, typename P1, typename P2, typename P3, typename P4>
5535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekclass CheckerFn<RET(P1, P2, P3, P4)> {
5635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  typedef RET (*Func)(void *, P1, P2, P3, P4);
5735bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  Func Fn;
5835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekpublic:
59ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
60ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
6135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
6235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    return Fn(Checker, p1, p2, p3, p4);
6335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  }
6435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek};
6535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek
664d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2, typename P3>
674d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2, P3)> {
684d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2, P3);
69769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
71ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
72ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
734d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
764d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2>
774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2)> {
784d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2);
79769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
81ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
82ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
834d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
864d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1>
874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1)> {
884d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1);
89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
91ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
92ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
934d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1) const { return Fn(Checker, p1); }
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
95769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET>
974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET()> {
984d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *);
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
101ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
102ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1034d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()() const { return Fn(Checker); }
104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
10543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
10643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager {
1072e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions LangOpts;
1082e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
10943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic:
1102e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
1119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  ~CheckerManager();
1129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
113d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis  bool hasPathSensitiveCheckers() const;
114d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis
115deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void finishedCheckerRegistration();
116deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
1172e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions &getLangOptions() const { return LangOpts; }
1182e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
119ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef CheckerBase *CheckerRef;
120ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef const void *CheckerTag;
1214d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void ()> CheckerDtor;
1229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker
1259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Used to register checkers.
1283fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  ///
1293fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  /// \returns a pointer to the checker object.
1309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
1313fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  CHECKER *registerChecker() {
132deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    CheckerTag tag = getTag<CHECKER>();
1333fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    CheckerRef &ref = CheckerTags[tag];
1343fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    if (ref)
1353fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      return static_cast<CHECKER *>(ref); // already registered.
1363fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
1379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER *checker = new CHECKER();
138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
1399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER::_register(checker, *this);
1403fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    ref = checker;
1413fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    return checker;
1429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
14343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
1469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls.
1499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
1509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls containing a Stmt body.
1539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
1549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting Stmts.
161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
162cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                             const ExplodedNodeSet &Src,
163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             const Stmt *S,
164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             ExprEngine &Eng) {
165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
168769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting Stmts.
169769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
170cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng) {
173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng);
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting Stmts.
177769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForStmt(bool isPreVisit,
178cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                          const Stmt *S, ExprEngine &Eng);
180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting obj-c messages.
182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
183cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                    const ExplodedNodeSet &Src,
184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    const ObjCMessage &msg,
185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ExprEngine &Eng) {
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting obj-c messages.
190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
191cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                     const ExplodedNodeSet &Src,
192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     const ObjCMessage &msg,
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     ExprEngine &Eng) {
194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
196769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting obj-c messages.
198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForObjCMessage(bool isPreVisit,
199cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 ExplodedNodeSet &Dst,
200cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                 const ObjCMessage &msg, ExprEngine &Eng);
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for load/store of a location.
204769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForLocation(ExplodedNodeSet &Dst,
205cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              SVal location, bool isLoad,
207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng);
209769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
210312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for binding of a value to a location.
211312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void runCheckersForBind(ExplodedNodeSet &Dst,
212312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          const ExplodedNodeSet &Src,
213312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          SVal location, SVal val,
214312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          const Stmt *S, ExprEngine &Eng);
215312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
21630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  /// \brief Run checkers for end of analysis.
21730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
21830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                 ExprEngine &Eng);
21930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
220af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  /// \brief Run checkers for end of path.
221af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng);
222af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
223cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  /// \brief Run checkers for branch condition.
224cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void runCheckersForBranchCondition(const Stmt *condition,
225cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                     BranchNodeBuilder &B, ExprEngine &Eng);
226cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
227183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for live symbols.
22818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  void runCheckersForLiveSymbols(const ProgramState *state,
229183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper);
230183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
231183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for dead symbols.
232183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
233183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
234183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper, const Stmt *S,
235183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 ExprEngine &Eng);
236183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
237183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief True if at least one checker wants to check region changes.
23818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  bool wantsRegionChangeUpdate(const ProgramState *state);
239183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
240183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for region changes.
241537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///
242537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// This corresponds to the check::RegionChanges callback.
243537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param state The current program state.
244537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param invalidated A set of all symbols potentially touched by the change.
245537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param ExplicitRegions The regions explicitly requested for invalidation.
246537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   For example, in the case of a function call, these would be arguments.
247537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param Regions The transitive closure of accessible regions,
248537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   i.e. all regions that may have been touched by this change.
24918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *
25018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  runCheckersForRegionChanges(const ProgramState *state,
25135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                            const StoreManager::InvalidatedSymbols *invalidated,
252537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                              ArrayRef<const MemRegion *> ExplicitRegions,
253537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                              ArrayRef<const MemRegion *> Regions);
254183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
255312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for handling assumptions on symbolic values.
25618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *runCheckersForEvalAssume(const ProgramState *state,
257312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                                          SVal Cond, bool Assumption);
258312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
259e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  /// \brief Run checkers for evaluating a call.
260e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
261e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
262e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const CallExpr *CE, ExprEngine &Eng,
263e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              GraphExpander *defaultEval = 0);
2649be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
2659be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  /// \brief Run checkers for the entire Translation Unit.
2669c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
2679be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         AnalysisManager &mgr,
2689be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         BugReporter &BR);
269e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
270769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
271769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
2729fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
2739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2749fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Functions used by the registration mechanism, checkers should not touch
2759fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // these directly.
2769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
278769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckDeclFunc;
279769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
2809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef bool (*HandlesDeclFunc)(const Decl *D);
281769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
2829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
283769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForBody(CheckDeclFunc checkfn);
284769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
285769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
286769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
287769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
288769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
2894d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
2904d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2914d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)>
2924d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckObjCMessageFunc;
2934d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2944d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const SVal &location, bool isLoad, CheckerContext &)>
295769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckLocationFunc;
2964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const SVal &location, const SVal &val,
2984d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis                          CheckerContext &)> CheckBindFunc;
2994d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3004d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
30130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis      CheckEndAnalysisFunc;
3024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3034d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)>
3044d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckEndPathFunc;
3054d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3064d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Stmt *, BranchNodeBuilder &, ExprEngine &)>
307cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis      CheckBranchConditionFunc;
3084d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3094d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
3104d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckDeadSymbolsFunc;
3114d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
31218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<void (const ProgramState *,SymbolReaper &)> CheckLiveSymbolsFunc;
3134d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
31418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<const ProgramState * (const ProgramState *,
31535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                                const StoreManager::InvalidatedSymbols *symbols,
316537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                    ArrayRef<const MemRegion *> ExplicitRegions,
317537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                          ArrayRef<const MemRegion *> Regions)>
3184d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckRegionChangesFunc;
3194d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
32018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<bool (const ProgramState *)> WantsRegionChangeUpdateFunc;
3214d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
32218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<const ProgramState * (const ProgramState *,
32318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                          const SVal &cond, bool assumption)>
3244d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalAssumeFunc;
3254d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3264d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
3274d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalCallFunc;
328769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
3299be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  typedef CheckerFn<void (const TranslationUnitDecl *,
3309be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                          AnalysisManager&, BugReporter &)>
3319be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek      CheckEndOfTranslationUnit;
3329be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
333769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef bool (*HandlesStmtFunc)(const Stmt *D);
334769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreStmt(CheckStmtFunc checkfn,
335769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                           HandlesStmtFunc isForStmtFn);
336769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostStmt(CheckStmtFunc checkfn,
337769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            HandlesStmtFunc isForStmtFn);
338769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
339769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
340769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
341769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
342769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForLocation(CheckLocationFunc checkfn);
343769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
344312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForBind(CheckBindFunc checkfn);
345312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
34630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
34730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
348af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  void _registerForEndPath(CheckEndPathFunc checkfn);
349af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
350cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
351cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
352183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
353183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
354183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
355183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
356183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
357183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 WantsRegionChangeUpdateFunc wantUpdateFn);
358183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
359312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForEvalAssume(EvalAssumeFunc checkfn);
360312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
361e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void _registerForEvalCall(EvalCallFunc checkfn);
362e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
3639be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
3649be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
365769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
366deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events.
367deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
368deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
369deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef void *EventTag;
3704d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const void *event)> CheckEventFunc;
371deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
372deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
373deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerListenerForEvent(CheckEventFunc checkfn) {
374deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
375deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.Checkers.push_back(checkfn);
376deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
377deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
378deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
379deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerDispatcherForEvent() {
380deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
381deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.HasDispatcher = true;
382deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
383deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
384deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
385deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _dispatchEvent(const EVENT &event) const {
386deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
387deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    if (I == Events.end())
388deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      return;
389deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    const EventInfo &info = I->second;
390deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
391deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      info.Checkers[i](&event);
392deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
393deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
394deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
395769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
396769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
39743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
39843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate:
3999fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
4009fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
4019fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
402deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename T>
403deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void *getTag() { static int tag; return &tag; }
4043fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
4053fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
4063fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
407769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckerDtor> CheckerDtors;
408769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
4099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  struct DeclCheckerInfo {
4109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc CheckFn;
4119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    HandlesDeclFunc IsForDeclFn;
4129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  };
4139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  std::vector<DeclCheckerInfo> DeclCheckers;
4149fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
415769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckDeclFunc> BodyCheckers;
4169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
417686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
4189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
4199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy CachedDeclCheckersMap;
420769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
421769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct StmtCheckerInfo {
422769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtFunc CheckFn;
423769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    HandlesStmtFunc IsForStmtFn;
424769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
425769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
426769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<StmtCheckerInfo> StmtCheckers;
427769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
428769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CachedStmtCheckersKey {
429769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned StmtKind;
430769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
431769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
432769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
433769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
434769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
435769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
436769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static CachedStmtCheckersKey getSentinel() {
437fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis      return CachedStmtCheckersKey(~0U, 0);
438769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned getHashValue() const {
440769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      llvm::FoldingSetNodeID ID;
441769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddInteger(StmtKind);
442769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddBoolean(IsPreVisit);
443769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return ID.ComputeHash();
444769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
445769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool operator==(const CachedStmtCheckersKey &RHS) const {
446769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
447769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
448769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
449769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
450769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
451686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
452769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
453769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CachedStmtCheckersMapTy;
454769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy CachedStmtCheckersMap;
455769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
456769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
457769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
458769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
459769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
460769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
461769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckLocationFunc> LocationCheckers;
46230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
463312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<CheckBindFunc> BindCheckers;
464312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
46530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
466e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
467af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  std::vector<CheckEndPathFunc> EndPathCheckers;
468af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
469cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
470cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
471183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
472183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
473183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
474183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
475183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  struct RegionChangesCheckerInfo {
476183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckRegionChangesFunc CheckFn;
477183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    WantsRegionChangeUpdateFunc WantUpdateFn;
478183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  };
479183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
480183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
481312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
482312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
483e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  std::vector<EvalCallFunc> EvalCallCheckers;
484deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
4859be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
4869be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
487deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  struct EventInfo {
488686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    SmallVector<CheckEventFunc, 4> Checkers;
489deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    bool HasDispatcher;
490deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo() : HasDispatcher(false) { }
491deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  };
492deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
493deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
494deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  EventsTy Events;
49543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis};
49643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
49743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace
49843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
49943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace
50043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
501769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm {
502769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
503769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// in DenseMap and DenseSets.
504769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <>
505769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
506769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
507769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getEmptyKey() {
508769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey();
509769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
510769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
511769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getTombstoneKey() {
512769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
513769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
514769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
515769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static unsigned
516769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
517769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return S.getHashValue();
518769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
519769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
520769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
521769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
522769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return LHS == RHS;
523769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
524769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
525769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm
526769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
52743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif
528