CheckerManager.h revision 686775deca8b8685eb90801495880e3abdd844c2
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 {
3043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  class ExprEngine;
319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class AnalysisManager;
329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class BugReporter;
33769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class CheckerContext;
34769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ObjCMessage;
35769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class SVal;
36e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class ExplodedNode;
37769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ExplodedNodeSet;
3830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  class ExplodedGraph;
39769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class GRState;
40af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  class EndOfFunctionNodeBuilder;
41cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  class BranchNodeBuilder;
42183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class MemRegion;
43183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class SymbolReaper;
44769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
45e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass GraphExpander {
46e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic:
47e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  virtual ~GraphExpander();
48e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0;
49e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis};
50e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
514d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename T> class CheckerFn;
524d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
5335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenektemplate <typename RET, typename P1, typename P2, typename P3, typename P4>
5435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekclass CheckerFn<RET(P1, P2, P3, P4)> {
5535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  typedef RET (*Func)(void *, P1, P2, P3, P4);
5635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  Func Fn;
5735bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekpublic:
5835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  void *Checker;
5935bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
6035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
6135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    return Fn(Checker, p1, p2, p3, p4);
6235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  }
6335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek};
6435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek
654d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2, typename P3>
664d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2, P3)> {
674d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2, P3);
68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
69769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
71769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
724d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
73769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
754d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2>
764d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2)> {
774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2);
78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
79769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1>
864d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1)> {
874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1);
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
924d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1) const { return Fn(Checker, p1); }
93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
954d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET>
964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET()> {
974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *);
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
1024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()() const { return Fn(Checker); }
103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
10443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
10543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager {
1062e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions LangOpts;
1072e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
10843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic:
1092e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
1109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  ~CheckerManager();
1119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
112d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis  bool hasPathSensitiveCheckers() const;
113d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis
114deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void finishedCheckerRegistration();
115deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
1162e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions &getLangOptions() const { return LangOpts; }
1172e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
1189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef void *CheckerRef;
1193fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  typedef void *CheckerTag;
1204d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void ()> CheckerDtor;
1219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker
1249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Used to register checkers.
1273fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  ///
1283fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  /// \returns a pointer to the checker object.
1299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
1303fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  CHECKER *registerChecker() {
131deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    CheckerTag tag = getTag<CHECKER>();
1323fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    CheckerRef &ref = CheckerTags[tag];
1333fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    if (ref)
1343fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      return static_cast<CHECKER *>(ref); // already registered.
1353fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
1369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER *checker = new CHECKER();
137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
1389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER::_register(checker, *this);
1393fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    ref = checker;
1403fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    return checker;
1419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
14243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
1459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls.
1489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
1499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls containing a Stmt body.
1529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
1539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting Stmts.
160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
161cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                             const ExplodedNodeSet &Src,
162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             const Stmt *S,
163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             ExprEngine &Eng) {
164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting Stmts.
168769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
169cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
170769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng) {
172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng);
173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting Stmts.
176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForStmt(bool isPreVisit,
177cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                          const Stmt *S, ExprEngine &Eng);
179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting obj-c messages.
181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
182cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                    const ExplodedNodeSet &Src,
183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    const ObjCMessage &msg,
184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ExprEngine &Eng) {
185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting obj-c messages.
189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
190cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                     const ExplodedNodeSet &Src,
191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     const ObjCMessage &msg,
192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     ExprEngine &Eng) {
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
196769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting obj-c messages.
197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForObjCMessage(bool isPreVisit,
198cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 ExplodedNodeSet &Dst,
199cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                 const ObjCMessage &msg, ExprEngine &Eng);
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for load/store of a location.
203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForLocation(ExplodedNodeSet &Dst,
204cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              SVal location, bool isLoad,
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng);
208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
209312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for binding of a value to a location.
210312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void runCheckersForBind(ExplodedNodeSet &Dst,
211312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          const ExplodedNodeSet &Src,
212312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          SVal location, SVal val,
213312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          const Stmt *S, ExprEngine &Eng);
214312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
21530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  /// \brief Run checkers for end of analysis.
21630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
21730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                 ExprEngine &Eng);
21830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
219af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  /// \brief Run checkers for end of path.
220af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng);
221af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
222cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  /// \brief Run checkers for branch condition.
223cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void runCheckersForBranchCondition(const Stmt *condition,
224cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                     BranchNodeBuilder &B, ExprEngine &Eng);
225cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
226183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for live symbols.
227183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void runCheckersForLiveSymbols(const GRState *state,
228183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper);
229183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
230183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for dead symbols.
231183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
232183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
233183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper, const Stmt *S,
234183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 ExprEngine &Eng);
235183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
236183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief True if at least one checker wants to check region changes.
237183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  bool wantsRegionChangeUpdate(const GRState *state);
238183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
239183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for region changes.
24035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  const GRState *
24135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  runCheckersForRegionChanges(const GRState *state,
24235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                            const StoreManager::InvalidatedSymbols *invalidated,
24335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                              const MemRegion * const *Begin,
24435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                              const MemRegion * const *End);
245183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
246312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for handling assumptions on symbolic values.
247312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  const GRState *runCheckersForEvalAssume(const GRState *state,
248312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                                          SVal Cond, bool Assumption);
249312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
250e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  /// \brief Run checkers for evaluating a call.
251e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
252e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
253e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const CallExpr *CE, ExprEngine &Eng,
254e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              GraphExpander *defaultEval = 0);
2559be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
2569be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  /// \brief Run checkers for the entire Translation Unit.
2579be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl* TU,
2589be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         AnalysisManager &mgr,
2599be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         BugReporter &BR);
260e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
261769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
262769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
2639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
2649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Functions used by the registration mechanism, checkers should not touch
2669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // these directly.
2679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2684d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
269769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckDeclFunc;
270769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
2719fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef bool (*HandlesDeclFunc)(const Decl *D);
272769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
2739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
274769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForBody(CheckDeclFunc checkfn);
275769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
276769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
277769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
278769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
279769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
2804d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
2814d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)>
2834d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckObjCMessageFunc;
2844d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const SVal &location, bool isLoad, CheckerContext &)>
286769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckLocationFunc;
2874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2884d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const SVal &location, const SVal &val,
2894d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis                          CheckerContext &)> CheckBindFunc;
2904d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2914d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
29230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis      CheckEndAnalysisFunc;
2934d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2944d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (EndOfFunctionNodeBuilder &, ExprEngine &)>
2954d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckEndPathFunc;
2964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
2974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Stmt *, BranchNodeBuilder &, ExprEngine &)>
298cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis      CheckBranchConditionFunc;
2994d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3004d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
3014d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckDeadSymbolsFunc;
3024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3034d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc;
3044d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3054d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<const GRState * (const GRState *,
30635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                                const StoreManager::InvalidatedSymbols *symbols,
3074d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis                                     const MemRegion * const *begin,
3084d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis                                     const MemRegion * const *end)>
3094d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckRegionChangesFunc;
3104d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3114d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<bool (const GRState *)> WantsRegionChangeUpdateFunc;
3124d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3134d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<const GRState * (const GRState *,
3144d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis                                     const SVal &cond, bool assumption)>
3154d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalAssumeFunc;
3164d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3174d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
3184d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalCallFunc;
319769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
3209be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  typedef CheckerFn<void (const TranslationUnitDecl *,
3219be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                          AnalysisManager&, BugReporter &)>
3229be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek      CheckEndOfTranslationUnit;
3239be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
324769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef bool (*HandlesStmtFunc)(const Stmt *D);
325769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreStmt(CheckStmtFunc checkfn,
326769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                           HandlesStmtFunc isForStmtFn);
327769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostStmt(CheckStmtFunc checkfn,
328769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            HandlesStmtFunc isForStmtFn);
329769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
330769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
331769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
332769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
333769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForLocation(CheckLocationFunc checkfn);
334769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
335312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForBind(CheckBindFunc checkfn);
336312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
33730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
33830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
339af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  void _registerForEndPath(CheckEndPathFunc checkfn);
340af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
341cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
342cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
343183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
344183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
345183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
346183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
347183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
348183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 WantsRegionChangeUpdateFunc wantUpdateFn);
349183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
350312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForEvalAssume(EvalAssumeFunc checkfn);
351312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
352e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void _registerForEvalCall(EvalCallFunc checkfn);
353e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
3549be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
3559be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
356769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
357deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events.
358deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
359deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
360deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef void *EventTag;
3614d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const void *event)> CheckEventFunc;
362deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
363deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
364deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerListenerForEvent(CheckEventFunc checkfn) {
365deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
366deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.Checkers.push_back(checkfn);
367deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
368deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
369deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
370deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerDispatcherForEvent() {
371deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
372deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.HasDispatcher = true;
373deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
374deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
375deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
376deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _dispatchEvent(const EVENT &event) const {
377deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
378deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    if (I == Events.end())
379deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      return;
380deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    const EventInfo &info = I->second;
381deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
382deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      info.Checkers[i](&event);
383deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
384deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
385deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
386769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
387769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
38843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
38943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate:
3909fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
3919fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
3929fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
393deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename T>
394deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void *getTag() { static int tag; return &tag; }
3953fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
3963fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
3973fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
398769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckerDtor> CheckerDtors;
399769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
4009fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  struct DeclCheckerInfo {
4019fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc CheckFn;
4029fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    HandlesDeclFunc IsForDeclFn;
4039fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  };
4049fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  std::vector<DeclCheckerInfo> DeclCheckers;
4059fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
406769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckDeclFunc> BodyCheckers;
4079fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
408686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
4099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
4109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy CachedDeclCheckersMap;
411769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
412769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct StmtCheckerInfo {
413769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtFunc CheckFn;
414769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    HandlesStmtFunc IsForStmtFn;
415769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
416769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
417769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<StmtCheckerInfo> StmtCheckers;
418769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
419769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CachedStmtCheckersKey {
420769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned StmtKind;
421769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
422769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
423769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
424769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
425769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
426769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
427769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static CachedStmtCheckersKey getSentinel() {
428fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis      return CachedStmtCheckersKey(~0U, 0);
429769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
430769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned getHashValue() const {
431769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      llvm::FoldingSetNodeID ID;
432769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddInteger(StmtKind);
433769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddBoolean(IsPreVisit);
434769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return ID.ComputeHash();
435769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
436769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool operator==(const CachedStmtCheckersKey &RHS) const {
437769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
438769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
440769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
441769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
442686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
443769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
444769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CachedStmtCheckersMapTy;
445769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy CachedStmtCheckersMap;
446769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
447769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
448769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
449769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
450769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
451769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
452769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckLocationFunc> LocationCheckers;
45330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
454312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<CheckBindFunc> BindCheckers;
455312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
45630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
457e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
458af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  std::vector<CheckEndPathFunc> EndPathCheckers;
459af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
460cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
461cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
462183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
463183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
464183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
465183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
466183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  struct RegionChangesCheckerInfo {
467183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckRegionChangesFunc CheckFn;
468183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    WantsRegionChangeUpdateFunc WantUpdateFn;
469183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  };
470183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
471183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
472312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
473312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
474e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  std::vector<EvalCallFunc> EvalCallCheckers;
475deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
4769be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
4779be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
478deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  struct EventInfo {
479686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    SmallVector<CheckEventFunc, 4> Checkers;
480deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    bool HasDispatcher;
481deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo() : HasDispatcher(false) { }
482deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  };
483deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
484deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
485deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  EventsTy Events;
48643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis};
48743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
48843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace
48943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
49043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace
49143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
492769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm {
493769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
494769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// in DenseMap and DenseSets.
495769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <>
496769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
497769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
498769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getEmptyKey() {
499769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey();
500769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
501769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
502769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getTombstoneKey() {
503769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
504769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
505769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
506769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static unsigned
507769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
508769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return S.getHashValue();
509769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
510769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
511769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
512769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
513769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return LHS == RHS;
514769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
515769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
516769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm
517769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
51843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif
519