CheckerManager.h revision 233e26acc0ff2a1098f4c813f69286fce840a422
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
1730a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Analysis/ProgramPoint.h"
182e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h"
1930a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "llvm/ADT/DenseMap.h"
21769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "llvm/ADT/FoldingSet.h"
2230a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/SmallVector.h"
239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include <vector>
2443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
2543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace clang {
269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class Decl;
27769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class Stmt;
28e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class CallExpr;
2943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
3043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace ento {
31ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  class CheckerBase;
3243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  class ExprEngine;
339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class AnalysisManager;
349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class BugReporter;
35769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class CheckerContext;
3669f87c956b3ac2b80124fd9604af012e1061473aJordan Rose  class SimpleCall;
37de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  class ObjCMethodCall;
38769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class SVal;
39e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class ExplodedNode;
40769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ExplodedNodeSet;
4130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  class ExplodedGraph;
4218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  class ProgramState;
43cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks  class NodeBuilder;
44af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  struct NodeBuilderContext;
45183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class MemRegion;
46183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class SymbolReaper;
47769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
484d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename T> class CheckerFn;
494d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
5066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zakstemplate <typename RET, typename P1, typename P2, typename P3, typename P4,
5166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks          typename P5>
5266c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaksclass CheckerFn<RET(P1, P2, P3, P4, P5)> {
5366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
5466c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  Func Fn;
5566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zakspublic:
5666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  CheckerBase *Checker;
5766c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
5866c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
5966c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks    return Fn(Checker, p1, p2, p3, p4, p5);
6066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  }
6166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks};
6266c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks
6335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenektemplate <typename RET, typename P1, typename P2, typename P3, typename P4>
6435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekclass CheckerFn<RET(P1, P2, P3, P4)> {
6535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  typedef RET (*Func)(void *, P1, P2, P3, P4);
6635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  Func Fn;
6735bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekpublic:
68ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
69ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
7035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
7135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    return Fn(Checker, p1, p2, p3, p4);
7235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  }
7335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek};
7435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek
754d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2, typename P3>
764d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2, P3)> {
774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2, P3);
78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
79769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
80ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
81ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2>
864d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2)> {
874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2);
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
90ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
91ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
924d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
954d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1>
964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1)> {
974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1);
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
100ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
101ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1) const { return Fn(Checker, p1); }
103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
1054d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET>
1064d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET()> {
1074d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *);
108769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
110ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
111ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1124d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()() const { return Fn(Checker); }
113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
11443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
115233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks/// \brief Describes the different reasons a pointer escapes
116233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks/// during analysis.
117233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaksenum PointerEscapeKind {
118233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// A pointer escapes due to binding its value to a location
119233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// that the analyzer cannot track.
120233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_EscapeOnBind,
121233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
122233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// The pointer has been passed to a function call directly.
123233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_DirectEscapeOnCall,
124233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
125233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// The pointer has been passed to a function indirectly.
126233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// For example, the pointer is accessible through an
127233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// argument to a function.
128233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_IndirectEscapeOnCall,
129233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
130233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// The reason for pointer escape is unknown. For example,
131233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// a region containing this pointer is invalidated.
132233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_EscapeOther
133233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks};
134233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
13543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager {
1362e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions LangOpts;
1372e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
13843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic:
1392e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
1409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  ~CheckerManager();
1419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
142d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis  bool hasPathSensitiveCheckers() const;
143d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis
144deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void finishedCheckerRegistration();
145deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
1464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  const LangOptions &getLangOpts() const { return LangOpts; }
1472e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
148ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef CheckerBase *CheckerRef;
149ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef const void *CheckerTag;
1504d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void ()> CheckerDtor;
1519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker
1549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Used to register checkers.
1573fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  ///
1583fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  /// \returns a pointer to the checker object.
1599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
1603fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  CHECKER *registerChecker() {
161deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    CheckerTag tag = getTag<CHECKER>();
1623fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    CheckerRef &ref = CheckerTags[tag];
1633fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    if (ref)
1643fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      return static_cast<CHECKER *>(ref); // already registered.
1653fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
1669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER *checker = new CHECKER();
167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
1689fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER::_register(checker, *this);
1693fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    ref = checker;
1703fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    return checker;
1719fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
17243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
1759fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls.
1789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
1799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls containing a Stmt body.
1829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
1839fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1849fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1859fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting Stmts.
190c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
191c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// The notification is performed for every explored CFGElement, which does
192c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// not include the control flow statements such as IfStmt.
193c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
194c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
196cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                             const ExplodedNodeSet &Src,
197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             const Stmt *S,
198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             ExprEngine &Eng) {
199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting Stmts.
203c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
204c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// The notification is performed for every explored CFGElement, which does
205c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// not include the control flow statements such as IfStmt.
206c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
207c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
209cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
210769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
211514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                              ExprEngine &Eng,
212514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                              bool wasInlined = false) {
213514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
214769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
216769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting Stmts.
217769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForStmt(bool isPreVisit,
218cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
219514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                          const Stmt *S, ExprEngine &Eng,
220514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                          bool wasInlined = false);
221769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
222769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting obj-c messages.
223769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
224cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                    const ExplodedNodeSet &Src,
225de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose                                    const ObjCMethodCall &msg,
226769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ExprEngine &Eng) {
227769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
228769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
229769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
230769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting obj-c messages.
231769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
232cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                     const ExplodedNodeSet &Src,
233de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose                                     const ObjCMethodCall &msg,
23457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                     ExprEngine &Eng,
23557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                     bool wasInlined = false) {
23657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
23757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                              wasInlined);
238769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
239769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
240769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting obj-c messages.
241769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForObjCMessage(bool isPreVisit,
242cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 ExplodedNodeSet &Dst,
243cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
24457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                 const ObjCMethodCall &msg, ExprEngine &Eng,
24557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                 bool wasInlined = false);
246769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
24796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  /// \brief Run checkers for pre-visiting obj-c messages.
24896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
24996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                             const CallEvent &Call, ExprEngine &Eng) {
25096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
25196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
25296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
25396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  /// \brief Run checkers for post-visiting obj-c messages.
25496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
25557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                              const CallEvent &Call, ExprEngine &Eng,
25657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                              bool wasInlined = false) {
25757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
25857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                            wasInlined);
25996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
26096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
26196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  /// \brief Run checkers for visiting obj-c messages.
26296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
26396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                               const ExplodedNodeSet &Src,
26457c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                               const CallEvent &Call, ExprEngine &Eng,
26557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                               bool wasInlined = false);
26696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
267769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for load/store of a location.
268769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForLocation(ExplodedNodeSet &Dst,
269cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
270bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              SVal location,
271bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              bool isLoad,
272bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *NodeEx,
273bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *BoundEx,
274769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng);
275769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
276312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for binding of a value to a location.
277312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void runCheckersForBind(ExplodedNodeSet &Dst,
278312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          const ExplodedNodeSet &Src,
279312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          SVal location, SVal val,
280ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                          const Stmt *S, ExprEngine &Eng,
2813682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose                          const ProgramPoint &PP);
282312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
28330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  /// \brief Run checkers for end of analysis.
28430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
28530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                 ExprEngine &Eng);
28630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
287344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  /// \brief Run checkers on end of function.
288344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  void runCheckersForEndFunction(NodeBuilderContext &BC,
289344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                 ExplodedNodeSet &Dst,
290344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                 ExplodedNode *Pred,
291344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                 ExprEngine &Eng);
292af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
293cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  /// \brief Run checkers for branch condition.
294cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void runCheckersForBranchCondition(const Stmt *condition,
295f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
2964e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks                                     ExprEngine &Eng);
297cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
298183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for live symbols.
299c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
300c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
301c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// register symbols of interest as live. These symbols will not be marked
302c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// dead and removed.
30323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  void runCheckersForLiveSymbols(ProgramStateRef state,
304183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper);
305183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
306183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for dead symbols.
307c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
308c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// Notifies checkers when symbols become dead. For example, this allows
309c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// checkers to aggressively clean up/reduce the checker state and produce
310c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// precise diagnostics.
311183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
312183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
313183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper, const Stmt *S,
3140b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                 ExprEngine &Eng,
3150b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                 ProgramPoint::Kind K);
316183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
317183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief True if at least one checker wants to check region changes.
31823111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  bool wantsRegionChangeUpdate(ProgramStateRef state);
319183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
320183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for region changes.
321537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///
322537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// This corresponds to the check::RegionChanges callback.
323537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param state The current program state.
324537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param invalidated A set of all symbols potentially touched by the change.
325537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param ExplicitRegions The regions explicitly requested for invalidation.
326537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   For example, in the case of a function call, these would be arguments.
327537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param Regions The transitive closure of accessible regions,
328537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   i.e. all regions that may have been touched by this change.
3297c0d2a366d2810e711f9c6ced8cbd923b9fc823aJames Dennett  /// \param Call The call expression wrapper if the regions are invalidated
3307c0d2a366d2810e711f9c6ced8cbd923b9fc823aJames Dennett  ///   by a call.
3317c0d2a366d2810e711f9c6ced8cbd923b9fc823aJames Dennett  ProgramStateRef
33223111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  runCheckersForRegionChanges(ProgramStateRef state,
333bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                              const InvalidatedSymbols *invalidated,
334537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                              ArrayRef<const MemRegion *> ExplicitRegions,
33566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                              ArrayRef<const MemRegion *> Regions,
336740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                              const CallEvent *Call);
337183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
338bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \brief Run checkers when pointers escape.
339bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  ///
340bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// This notifies the checkers about pointer escape, which occurs whenever
3411655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  /// the analyzer cannot track the symbol any more. For example, as a
342bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// result of assigning a pointer into a global or when it's passed to a
343bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// function call the analyzer cannot model.
344bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  ///
345bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \param State The state at the point of escape.
346bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \param Escaped The list of escaped symbols.
347bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \param Call The corresponding CallEvent, if the symbols escape as
3481655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  ///        parameters to the given call.
349bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \returns Checkers can modify the state by returning a new one.
3501655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  ProgramStateRef
3511655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  runCheckersForPointerEscape(ProgramStateRef State,
3521655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks                              const InvalidatedSymbols &Escaped,
353233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                              const CallEvent *Call,
354233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                              PointerEscapeKind Kind);
355bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
356312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for handling assumptions on symbolic values.
35723111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
3581655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks                                           SVal Cond, bool Assumption);
359312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
360e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  /// \brief Run checkers for evaluating a call.
361645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose  ///
362645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
363e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
364e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
365645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose                              const CallEvent &CE, ExprEngine &Eng);
3669be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
3679be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  /// \brief Run checkers for the entire Translation Unit.
3689c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
3699be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         AnalysisManager &mgr,
3709be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         BugReporter &BR);
371e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
372dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \brief Run checkers for debug-printing a ProgramState.
373dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  ///
374dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// Unlike most other callbacks, any checker can simply implement the virtual
375dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// method CheckerBase::printState if it has custom data to print.
376dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param Out The output stream
377dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param State The state being printed
378dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param NL The preferred representation of a newline.
379dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param Sep The preferred separator between different kinds of data.
38023111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
381dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                                const char *NL, const char *Sep);
382dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
383769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
384769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
3859fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
3869fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
3879fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Functions used by the registration mechanism, checkers should not touch
3889fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // these directly.
3899fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
3904d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
391769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckDeclFunc;
392769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
3939fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef bool (*HandlesDeclFunc)(const Decl *D);
394769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
3959fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
396769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForBody(CheckDeclFunc checkfn);
397769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
398769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
399769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
400769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
401769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
4024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
4034d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
404de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
4054d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckObjCMessageFunc;
40696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
40796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
40896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose      CheckCallFunc;
4094d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
410bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  typedef CheckerFn<void (const SVal &location, bool isLoad,
411bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const Stmt *S,
412390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                          CheckerContext &)>
413769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckLocationFunc;
4144d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
415390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  typedef CheckerFn<void (const SVal &location, const SVal &val,
416390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                          const Stmt *S, CheckerContext &)>
417390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks      CheckBindFunc;
4184d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
4194d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
42030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis      CheckEndAnalysisFunc;
4214d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
422af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  typedef CheckerFn<void (CheckerContext &)>
423344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks      CheckEndFunctionFunc;
4244d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
425f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
426cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis      CheckBranchConditionFunc;
4274d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
4284d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
4294d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckDeadSymbolsFunc;
4304d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
43123111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
4324d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
43323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
434bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                                const InvalidatedSymbols *symbols,
43566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                ArrayRef<const MemRegion *> ExplicitRegions,
43666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                ArrayRef<const MemRegion *> Regions,
437740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                const CallEvent *Call)>
4384d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckRegionChangesFunc;
4394d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
44023111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
441bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
442bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
443bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                                     const InvalidatedSymbols &Escaped,
444233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                                     const CallEvent *Call,
445233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                                     PointerEscapeKind Kind)>
446bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks      CheckPointerEscapeFunc;
4474d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
44823111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
44918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                          const SVal &cond, bool assumption)>
4504d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalAssumeFunc;
4514d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
4524d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
4534d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalCallFunc;
454769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
4559be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  typedef CheckerFn<void (const TranslationUnitDecl *,
4569be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                          AnalysisManager&, BugReporter &)>
4579be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek      CheckEndOfTranslationUnit;
4589be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
459769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef bool (*HandlesStmtFunc)(const Stmt *D);
460769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreStmt(CheckStmtFunc checkfn,
461769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                           HandlesStmtFunc isForStmtFn);
462769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostStmt(CheckStmtFunc checkfn,
463769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            HandlesStmtFunc isForStmtFn);
464769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
465769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
466769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
467769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
46896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void _registerForPreCall(CheckCallFunc checkfn);
46996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void _registerForPostCall(CheckCallFunc checkfn);
47096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
471769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForLocation(CheckLocationFunc checkfn);
472769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
473312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForBind(CheckBindFunc checkfn);
474312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
47530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
47630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
477344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  void _registerForEndFunction(CheckEndFunctionFunc checkfn);
478af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
479cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
480cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
481183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
482183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
483183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
484183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
485183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
486183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 WantsRegionChangeUpdateFunc wantUpdateFn);
487183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
488bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
489bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
490312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForEvalAssume(EvalAssumeFunc checkfn);
491312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
492e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void _registerForEvalCall(EvalCallFunc checkfn);
493e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
4949be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
4959be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
496769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
497deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events.
498deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
499deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
500deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef void *EventTag;
5014d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const void *event)> CheckEventFunc;
502deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
503deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
504deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerListenerForEvent(CheckEventFunc checkfn) {
505deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
506deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.Checkers.push_back(checkfn);
507deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
508deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
509deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
510deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerDispatcherForEvent() {
511deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
512deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.HasDispatcher = true;
513deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
514deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
515deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
516deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _dispatchEvent(const EVENT &event) const {
517deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
518deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    if (I == Events.end())
519deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      return;
520deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    const EventInfo &info = I->second;
521deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
522deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      info.Checkers[i](&event);
523deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
524deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
525deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
526769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
527769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
52843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
52943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate:
5309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
5319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
5329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
533deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename T>
534deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void *getTag() { static int tag; return &tag; }
5353fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
5363fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
5373fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
538769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckerDtor> CheckerDtors;
539769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
5409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  struct DeclCheckerInfo {
5419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc CheckFn;
5429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    HandlesDeclFunc IsForDeclFn;
5439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  };
5449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  std::vector<DeclCheckerInfo> DeclCheckers;
5459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
546769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckDeclFunc> BodyCheckers;
5479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
548686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
5499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
5509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy CachedDeclCheckersMap;
551769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
552769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct StmtCheckerInfo {
553769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtFunc CheckFn;
554769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    HandlesStmtFunc IsForStmtFn;
555769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
556769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
557769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<StmtCheckerInfo> StmtCheckers;
558769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
559769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CachedStmtCheckersKey {
560769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned StmtKind;
561769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
562769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
563769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
564769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
565769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
566769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
567769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static CachedStmtCheckersKey getSentinel() {
568fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis      return CachedStmtCheckersKey(~0U, 0);
569769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
570769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned getHashValue() const {
571769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      llvm::FoldingSetNodeID ID;
572769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddInteger(StmtKind);
573769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddBoolean(IsPreVisit);
574769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return ID.ComputeHash();
575769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
576769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool operator==(const CachedStmtCheckersKey &RHS) const {
577769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
578769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
579769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
580769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
581769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
582686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
583769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
584769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CachedStmtCheckersMapTy;
585769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy CachedStmtCheckersMap;
586769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
587769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
588769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
589769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
590769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
591769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
59296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  std::vector<CheckCallFunc> PreCallCheckers;
59396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  std::vector<CheckCallFunc> PostCallCheckers;
59496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
595769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckLocationFunc> LocationCheckers;
59630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
597312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<CheckBindFunc> BindCheckers;
598312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
59930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
600e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
601344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
602af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
603cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
604cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
605183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
606183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
607183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
608183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
609183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  struct RegionChangesCheckerInfo {
610183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckRegionChangesFunc CheckFn;
611183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    WantsRegionChangeUpdateFunc WantUpdateFn;
612183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  };
613183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
614183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
615bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
616bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
617312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
618312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
619e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  std::vector<EvalCallFunc> EvalCallCheckers;
620deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
6219be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
6229be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
623deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  struct EventInfo {
624686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    SmallVector<CheckEventFunc, 4> Checkers;
625deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    bool HasDispatcher;
626deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo() : HasDispatcher(false) { }
627deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  };
628deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
629deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
630deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  EventsTy Events;
63143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis};
63243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
63343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace
63443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
63543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace
63643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
637769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm {
638769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
639769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// in DenseMap and DenseSets.
640769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <>
641769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
642769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
643769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getEmptyKey() {
644769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey();
645769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
646769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
647769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getTombstoneKey() {
648769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
649769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
650769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
651769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static unsigned
652769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
653769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return S.getHashValue();
654769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
655769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
656769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
657769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
658769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return LHS == RHS;
659769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
660769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
661769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm
662769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
66343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif
664