CheckerManager.h revision f236b6503a4dbc44c1fccb8756bd57c9d0efdf05
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"
22ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks#include "clang/Analysis/ProgramPoint.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;
36769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ObjCMessage;
37769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class SVal;
38e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class ExplodedNode;
39769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ExplodedNodeSet;
4030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  class ExplodedGraph;
4118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  class ProgramState;
42cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks  class NodeBuilder;
43af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  struct NodeBuilderContext;
44183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class MemRegion;
45183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class SymbolReaper;
46769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
47e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisclass GraphExpander {
48e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidispublic:
49e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  virtual ~GraphExpander();
50e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0;
51e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis};
52e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
534d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename T> class CheckerFn;
544d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
5535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenektemplate <typename RET, typename P1, typename P2, typename P3, typename P4>
5635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekclass CheckerFn<RET(P1, P2, P3, P4)> {
5735bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  typedef RET (*Func)(void *, P1, P2, P3, P4);
5835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  Func Fn;
5935bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekpublic:
60ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
61ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
6235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
6335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    return Fn(Checker, p1, p2, p3, p4);
6435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  }
6535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek};
6635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek
674d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2, typename P3>
684d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2, P3)> {
694d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2, P3);
70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
71769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
72ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
73ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
744d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
76769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2>
784d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2)> {
794d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2);
80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
82ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
83ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
844d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1>
884d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1)> {
894d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1);
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
92ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
93ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
944d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1) const { return Fn(Checker, p1); }
95769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
96769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET>
984d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET()> {
994d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *);
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
102ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
103ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1044d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()() const { return Fn(Checker); }
105769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
10643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
10743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager {
1082e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions LangOpts;
1092e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
11043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic:
1112e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
1129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  ~CheckerManager();
1139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
114d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis  bool hasPathSensitiveCheckers() const;
115d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis
116deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void finishedCheckerRegistration();
117deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
1182e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions &getLangOptions() const { return LangOpts; }
1192e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
120ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef CheckerBase *CheckerRef;
121ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef const void *CheckerTag;
1224d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void ()> CheckerDtor;
1239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker
1269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Used to register checkers.
1293fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  ///
1303fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  /// \returns a pointer to the checker object.
1319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
1323fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  CHECKER *registerChecker() {
133deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    CheckerTag tag = getTag<CHECKER>();
1343fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    CheckerRef &ref = CheckerTags[tag];
1353fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    if (ref)
1363fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      return static_cast<CHECKER *>(ref); // already registered.
1373fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
1389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER *checker = new CHECKER();
139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
1409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER::_register(checker, *this);
1413fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    ref = checker;
1423fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    return checker;
1439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
14443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
1479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls.
1509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
1519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls containing a Stmt body.
1549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
1559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting Stmts.
162c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
163c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// The notification is performed for every explored CFGElement, which does
164c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// not include the control flow statements such as IfStmt.
165c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
166c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
168cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                             const ExplodedNodeSet &Src,
169769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             const Stmt *S,
170769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             ExprEngine &Eng) {
171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting Stmts.
175c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
176c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// The notification is performed for every explored CFGElement, which does
177c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// not include the control flow statements such as IfStmt.
178c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
179c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
181cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng) {
184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng);
185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting Stmts.
188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForStmt(bool isPreVisit,
189cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                          const Stmt *S, ExprEngine &Eng);
191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting obj-c messages.
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
194cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                    const ExplodedNodeSet &Src,
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    const ObjCMessage &msg,
196769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ExprEngine &Eng) {
197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting obj-c messages.
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
202cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                     const ExplodedNodeSet &Src,
203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     const ObjCMessage &msg,
204769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     ExprEngine &Eng) {
205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting obj-c messages.
209769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForObjCMessage(bool isPreVisit,
210cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 ExplodedNodeSet &Dst,
211cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
212769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                 const ObjCMessage &msg, ExprEngine &Eng);
213769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
214769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for load/store of a location.
215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForLocation(ExplodedNodeSet &Dst,
216cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
217769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              SVal location, bool isLoad,
218769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
219769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng);
220769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
221312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for binding of a value to a location.
222312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void runCheckersForBind(ExplodedNodeSet &Dst,
223312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          const ExplodedNodeSet &Src,
224312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          SVal location, SVal val,
225ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                          const Stmt *S, ExprEngine &Eng,
226ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                          ProgramPoint::Kind PointKind);
227312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
22830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  /// \brief Run checkers for end of analysis.
22930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
23030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                 ExprEngine &Eng);
23130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
232af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  /// \brief Run checkers for end of path.
233af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  void runCheckersForEndPath(NodeBuilderContext &BC,
234af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks                             ExplodedNodeSet &Dst,
235af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks                             ExprEngine &Eng);
236af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
237cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  /// \brief Run checkers for branch condition.
238cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void runCheckersForBranchCondition(const Stmt *condition,
239f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
2404e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks                                     ExprEngine &Eng);
241cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
242183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for live symbols.
243c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
244c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
245c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// register symbols of interest as live. These symbols will not be marked
246c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// dead and removed.
24718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  void runCheckersForLiveSymbols(const ProgramState *state,
248183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper);
249183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
250183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for dead symbols.
251c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
252c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// Notifies checkers when symbols become dead. For example, this allows
253c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// checkers to aggressively clean up/reduce the checker state and produce
254c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// precise diagnostics.
255183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
256183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
257183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper, const Stmt *S,
258183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 ExprEngine &Eng);
259183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
260183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief True if at least one checker wants to check region changes.
26118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  bool wantsRegionChangeUpdate(const ProgramState *state);
262183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
263183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for region changes.
264537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///
265537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// This corresponds to the check::RegionChanges callback.
266537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param state The current program state.
267537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param invalidated A set of all symbols potentially touched by the change.
268537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param ExplicitRegions The regions explicitly requested for invalidation.
269537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   For example, in the case of a function call, these would be arguments.
270537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param Regions The transitive closure of accessible regions,
271537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   i.e. all regions that may have been touched by this change.
27218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *
27318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  runCheckersForRegionChanges(const ProgramState *state,
27435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                            const StoreManager::InvalidatedSymbols *invalidated,
275537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                              ArrayRef<const MemRegion *> ExplicitRegions,
276537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                              ArrayRef<const MemRegion *> Regions);
277183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
278312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for handling assumptions on symbolic values.
27918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  const ProgramState *runCheckersForEvalAssume(const ProgramState *state,
280312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                                          SVal Cond, bool Assumption);
281312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
282e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  /// \brief Run checkers for evaluating a call.
283e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
284e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
285e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const CallExpr *CE, ExprEngine &Eng,
286e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              GraphExpander *defaultEval = 0);
2879be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
2889be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  /// \brief Run checkers for the entire Translation Unit.
2899c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
2909be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         AnalysisManager &mgr,
2919be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         BugReporter &BR);
292e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
293dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \brief Run checkers for debug-printing a ProgramState.
294dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  ///
295dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// Unlike most other callbacks, any checker can simply implement the virtual
296dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// method CheckerBase::printState if it has custom data to print.
297dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param Out The output stream
298dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param State The state being printed
299dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param NL The preferred representation of a newline.
300dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param Sep The preferred separator between different kinds of data.
301dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  void runCheckersForPrintState(raw_ostream &Out, const ProgramState *State,
302dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                                const char *NL, const char *Sep);
303dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
304769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
305769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
3069fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
3079fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
3089fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Functions used by the registration mechanism, checkers should not touch
3099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // these directly.
3109fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
3114d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
312769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckDeclFunc;
313769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
3149fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef bool (*HandlesDeclFunc)(const Decl *D);
315769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
3169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
317769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForBody(CheckDeclFunc checkfn);
318769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
319769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
320769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
321769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
322769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
3234d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
3244d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3254d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)>
3264d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckObjCMessageFunc;
3274d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
328390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  typedef CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S,
329390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                          CheckerContext &)>
330769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckLocationFunc;
3314d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
332390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  typedef CheckerFn<void (const SVal &location, const SVal &val,
333390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                          const Stmt *S, CheckerContext &)>
334390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks      CheckBindFunc;
3354d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3364d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
33730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis      CheckEndAnalysisFunc;
3384d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
339af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  typedef CheckerFn<void (CheckerContext &)>
3404d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckEndPathFunc;
3414d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
342f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
343cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis      CheckBranchConditionFunc;
3444d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3454d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
3464d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckDeadSymbolsFunc;
3474d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
34818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<void (const ProgramState *,SymbolReaper &)> CheckLiveSymbolsFunc;
3494d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
35018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<const ProgramState * (const ProgramState *,
35135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                                const StoreManager::InvalidatedSymbols *symbols,
352537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                    ArrayRef<const MemRegion *> ExplicitRegions,
353537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                          ArrayRef<const MemRegion *> Regions)>
3544d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckRegionChangesFunc;
3554d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
35618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<bool (const ProgramState *)> WantsRegionChangeUpdateFunc;
3574d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
35818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  typedef CheckerFn<const ProgramState * (const ProgramState *,
35918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                          const SVal &cond, bool assumption)>
3604d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalAssumeFunc;
3614d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
3624d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
3634d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalCallFunc;
364769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
365dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks  typedef CheckerFn<bool (const CallExpr *, ExprEngine &Eng,
366dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks                                            ExplodedNode *Pred,
367dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks                                            ExplodedNodeSet &Dst)>
368dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks      InlineCallFunc;
369dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks
3709be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  typedef CheckerFn<void (const TranslationUnitDecl *,
3719be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                          AnalysisManager&, BugReporter &)>
3729be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek      CheckEndOfTranslationUnit;
3739be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
374769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef bool (*HandlesStmtFunc)(const Stmt *D);
375769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreStmt(CheckStmtFunc checkfn,
376769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                           HandlesStmtFunc isForStmtFn);
377769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostStmt(CheckStmtFunc checkfn,
378769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            HandlesStmtFunc isForStmtFn);
379769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
380769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
381769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
382769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
383769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForLocation(CheckLocationFunc checkfn);
384769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
385312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForBind(CheckBindFunc checkfn);
386312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
38730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
38830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
389af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  void _registerForEndPath(CheckEndPathFunc checkfn);
390af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
391cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
392cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
393183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
394183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
395183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
396183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
397183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
398183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 WantsRegionChangeUpdateFunc wantUpdateFn);
399183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
400312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForEvalAssume(EvalAssumeFunc checkfn);
401312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
402e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void _registerForEvalCall(EvalCallFunc checkfn);
403e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
404dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks  void _registerForInlineCall(InlineCallFunc checkfn);
405dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks
4069be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
4079be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
408769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
409deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events.
410deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
411deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
412deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef void *EventTag;
4134d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const void *event)> CheckEventFunc;
414deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
415deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
416deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerListenerForEvent(CheckEventFunc checkfn) {
417deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
418deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.Checkers.push_back(checkfn);
419deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
420deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
421deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
422deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerDispatcherForEvent() {
423deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
424deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.HasDispatcher = true;
425deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
426deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
427deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
428deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _dispatchEvent(const EVENT &event) const {
429deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
430deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    if (I == Events.end())
431deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      return;
432deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    const EventInfo &info = I->second;
433deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
434deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      info.Checkers[i](&event);
435deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
436deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
437deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
438769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
44043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
44143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate:
4429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
4439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
4449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
445deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename T>
446deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void *getTag() { static int tag; return &tag; }
4473fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
4483fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
4493fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
450769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckerDtor> CheckerDtors;
451769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
4529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  struct DeclCheckerInfo {
4539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc CheckFn;
4549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    HandlesDeclFunc IsForDeclFn;
4559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  };
4569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  std::vector<DeclCheckerInfo> DeclCheckers;
4579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
458769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckDeclFunc> BodyCheckers;
4599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
460686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
4619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
4629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy CachedDeclCheckersMap;
463769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
464769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct StmtCheckerInfo {
465769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtFunc CheckFn;
466769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    HandlesStmtFunc IsForStmtFn;
467769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
468769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
469769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<StmtCheckerInfo> StmtCheckers;
470769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
471769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CachedStmtCheckersKey {
472769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned StmtKind;
473769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
474769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
475769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
476769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
477769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
478769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
479769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static CachedStmtCheckersKey getSentinel() {
480fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis      return CachedStmtCheckersKey(~0U, 0);
481769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
482769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned getHashValue() const {
483769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      llvm::FoldingSetNodeID ID;
484769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddInteger(StmtKind);
485769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddBoolean(IsPreVisit);
486769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return ID.ComputeHash();
487769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
488769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool operator==(const CachedStmtCheckersKey &RHS) const {
489769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
490769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
491769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
492769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
493769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
494686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
495769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
496769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CachedStmtCheckersMapTy;
497769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy CachedStmtCheckersMap;
498769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
499769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
500769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
501769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
502769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
503769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
504769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckLocationFunc> LocationCheckers;
50530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
506312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<CheckBindFunc> BindCheckers;
507312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
50830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
509e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
510af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  std::vector<CheckEndPathFunc> EndPathCheckers;
511af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
512cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
513cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
514183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
515183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
516183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
517183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
518183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  struct RegionChangesCheckerInfo {
519183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckRegionChangesFunc CheckFn;
520183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    WantsRegionChangeUpdateFunc WantUpdateFn;
521183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  };
522183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
523183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
524312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
525312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
526e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  std::vector<EvalCallFunc> EvalCallCheckers;
527deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
528dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks  std::vector<InlineCallFunc> InlineCallCheckers;
529dff6ef903ff4fcb43b5ea292ecd772e381393b5dAnna Zaks
5309be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
5319be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
532deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  struct EventInfo {
533686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    SmallVector<CheckEventFunc, 4> Checkers;
534deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    bool HasDispatcher;
535deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo() : HasDispatcher(false) { }
536deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  };
537deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
538deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
539deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  EventsTy Events;
54043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis};
54143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
54243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace
54343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
54443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace
54543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
546769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm {
547769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
548769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// in DenseMap and DenseSets.
549769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <>
550769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
551769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
552769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getEmptyKey() {
553769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey();
554769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
555769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
556769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getTombstoneKey() {
557769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
558769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
559769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
560769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static unsigned
561769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
562769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return S.getHashValue();
563769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
564769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
565769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
566769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
567769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return LHS == RHS;
568769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
569769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
570769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm
571769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
57243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif
573