CheckerManager.h revision 740d490593e0de8732a697c9f77b90ddd463863b
10a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//                     The LLVM Compiler Infrastructure
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// This file is distributed under the University of Illinois Open Source
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// License. See LICENSE.TXT for details.
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Defines the Static Analyzer Checker Manager.
11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/Basic/LangOptions.h"
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "llvm/ADT/SmallVector.h"
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "llvm/ADT/DenseMap.h"
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "llvm/ADT/FoldingSet.h"
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/Analysis/ProgramPoint.h"
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include <vector>
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace clang {
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class Decl;
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class Stmt;
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class CallExpr;
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace ento {
31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class CheckerBase;
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class ExprEngine;
33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class AnalysisManager;
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class BugReporter;
35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class CheckerContext;
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class ObjCMessage;
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class SVal;
38a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class ExplodedNode;
39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class ExplodedNodeSet;
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class ExplodedGraph;
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class ProgramState;
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class NodeBuilder;
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  struct NodeBuilderContext;
44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class MemRegion;
45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  class SymbolReaper;
46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
47a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass GraphExpander {
48a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual ~GraphExpander();
50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0;
51496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org};
52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
53a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename T> class CheckerFn;
54a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
55a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2, typename P3, typename P4,
56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org          typename P5>
57496c03a64f12710e837204e261ef155601247895sgjesse@chromium.orgclass CheckerFn<RET(P1, P2, P3, P4, P5)> {
58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Func Fn;
60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerBase *Checker;
62a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
6431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    return Fn(Checker, p1, p2, p3, p4, p5);
65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2, typename P3, typename P4>
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1, P2, P3, P4)> {
70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef RET (*Func)(void *, P1, P2, P3, P4);
71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Func Fn;
72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerBase *Checker;
74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
76a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return Fn(Checker, p1, p2, p3, p4);
77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
78a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
80a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2, typename P3>
81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1, P2, P3)> {
82a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef RET (*Func)(void *, P1, P2, P3);
83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Func Fn;
84a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
85a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerBase *Checker;
86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
88a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
89a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1, typename P2>
91a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1, P2)> {
92a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef RET (*Func)(void *, P1, P2);
93a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Func Fn;
94a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
95a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerBase *Checker;
960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
97a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
9883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org};
99a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgtemplate <typename RET, typename P1>
101a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET(P1)> {
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef RET (*Func)(void *, P1);
1039e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  Func Fn;
104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
10549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  CheckerBase *Checker;
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
107a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  RET operator()(P1 p1) const { return Fn(Checker, p1); }
108a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
110d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.orgtemplate <typename RET>
111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CheckerFn<RET()> {
1125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  typedef RET (*Func)(void *);
113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Func Fn;
114d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.compublic:
115a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerBase *Checker;
116a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1179e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org  RET operator()() const { return Fn(Checker); }
118a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
119a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
120c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.orgclass CheckerManager {
121a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const LangOptions LangOpts;
122378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
123a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
124a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ~CheckerManager();
126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool hasPathSensitiveCheckers() const;
128496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
129496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  void finishedCheckerRegistration();
130a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
131a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const LangOptions &getLangOpts() const { return LangOpts; }
132a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
133a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerBase *CheckerRef;
13483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  typedef const void *CheckerTag;
135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void ()> CheckerDtor;
136496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
1375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org//===----------------------------------------------------------------------===//
138a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// registerChecker
139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Used to register checkers.
142a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \returns a pointer to the checker object.
144a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  template <typename CHECKER>
145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CHECKER *registerChecker() {
14683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    CheckerTag tag = getTag<CHECKER>();
147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CheckerRef &ref = CheckerTags[tag];
148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (ref)
1493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      return static_cast<CHECKER *>(ref); // already registered.
150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CHECKER *checker = new CHECKER();
152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
1530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    CHECKER::_register(checker, *this);
1540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    ref = checker;
155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return checker;
1560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
157a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
158a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
159a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Functions for running checkers for AST traversing..
160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
162a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers handling Decls.
163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                            BugReporter &BR);
165a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
166a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers handling Decls containing a Stmt body.
167a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
168a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                            BugReporter &BR);
169496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
170a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Functions for running checkers for path-sensitive checking.
172a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
17383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for pre-visiting Stmts.
175a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// The notification is performed for every explored CFGElement, which does
177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// not include the control flow statements such as IfStmt.
178a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                             const ExplodedNodeSet &Src,
182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                             const Stmt *S,
183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                             ExprEngine &Eng) {
184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
186a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
187a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for post-visiting Stmts.
188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// The notification is performed for every explored CFGElement, which does
190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// not include the control flow statements such as IfStmt.
191a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
1938f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
1948f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                              const ExplodedNodeSet &Src,
1958f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                              const Stmt *S,
1968f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                              ExprEngine &Eng,
1978f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                              bool wasInlined = false) {
198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2008f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2018f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  /// \brief Run checkers for visiting Stmts.
2028f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void runCheckersForStmt(bool isPreVisit,
2038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
204a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          const Stmt *S, ExprEngine &Eng,
205a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          bool wasInlined = false);
206a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
207a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for pre-visiting obj-c messages.
208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                    const ExplodedNodeSet &Src,
210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                    const ObjCMessage &msg,
211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                    ExprEngine &Eng) {
212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
215a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for post-visiting obj-c messages.
2168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
2178f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                     const ExplodedNodeSet &Src,
2188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                     const ObjCMessage &msg,
2198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                                     ExprEngine &Eng) {
220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
2218f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
2228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
2235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  /// \brief Run checkers for visiting obj-c messages.
224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForObjCMessage(bool isPreVisit,
225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 ExplodedNodeSet &Dst,
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 const ExplodedNodeSet &Src,
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 const ObjCMessage &msg, ExprEngine &Eng);
228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2298f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  /// \brief Run checkers for load/store of a location.
2308f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void runCheckersForLocation(ExplodedNodeSet &Dst,
231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              const ExplodedNodeSet &Src,
2328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                              SVal location,
2338f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                              bool isLoad,
2348f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                              const Stmt *NodeEx,
235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              const Stmt *BoundEx,
236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              ExprEngine &Eng);
237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for binding of a value to a location.
239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForBind(ExplodedNodeSet &Dst,
240a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          const ExplodedNodeSet &Src,
241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          SVal location, SVal val,
242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          const Stmt *S, ExprEngine &Eng,
243a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          ProgramPoint::Kind PointKind);
244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for end of analysis.
246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 ExprEngine &Eng);
248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
249a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for end of path.
250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForEndPath(NodeBuilderContext &BC,
251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                             ExplodedNodeSet &Dst,
252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                             ExprEngine &Eng);
253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
254496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  /// \brief Run checkers for branch condition.
255a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForBranchCondition(const Stmt *condition,
256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                     ExprEngine &Eng);
258a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
259a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for live symbols.
260a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// register symbols of interest as live. These symbols will not be marked
263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// dead and removed.
264496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  void runCheckersForLiveSymbols(ProgramStateRef state,
265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 SymbolReaper &SymReaper);
2663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for dead symbols.
268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// Notifies checkers when symbols become dead. For example, this allows
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// checkers to aggressively clean up/reduce the checker state and produce
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// precise diagnostics.
272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 const ExplodedNodeSet &Src,
274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 SymbolReaper &SymReaper, const Stmt *S,
275496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org                                 ExprEngine &Eng,
276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 ProgramPoint::Kind K);
277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief True if at least one checker wants to check region changes.
279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool wantsRegionChangeUpdate(ProgramStateRef state);
280a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for region changes.
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// This corresponds to the check::RegionChanges callback.
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param state The current program state.
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param invalidated A set of all symbols potentially touched by the change.
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param ExplicitRegions The regions explicitly requested for invalidation.
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///   For example, in the case of a function call, these would be arguments.
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param Regions The transitive closure of accessible regions,
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///   i.e. all regions that may have been touched by this change.
290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param Call The call expression wrapper if the regions are invalidated
291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///   by a call.
292a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ProgramStateRef
293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  runCheckersForRegionChanges(ProgramStateRef state,
294a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                            const StoreManager::InvalidatedSymbols *invalidated,
295a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              ArrayRef<const MemRegion *> ExplicitRegions,
296a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              ArrayRef<const MemRegion *> Regions,
297a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              const CallEvent *Call);
298a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
299a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for handling assumptions on symbolic values.
300a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
301a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                               SVal Cond, bool Assumption);
302a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
303a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for evaluating a call.
304a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
305a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              const ExplodedNodeSet &Src,
306a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              const CallExpr *CE, ExprEngine &Eng,
307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                              GraphExpander *defaultEval = 0);
308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for the entire Translation Unit.
310a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
311a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                         AnalysisManager &mgr,
312a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                         BugReporter &BR);
313a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
314a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Run checkers for debug-printing a ProgramState.
315a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ///
316a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// Unlike most other callbacks, any checker can simply implement the virtual
317a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// method CheckerBase::printState if it has custom data to print.
318a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param Out The output stream
319a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param State The state being printed
320a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param NL The preferred representation of a newline.
321a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \param Sep The preferred separator between different kinds of data.
322a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
323a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                const char *NL, const char *Sep);
324a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
325a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Internal registration functions for AST traversing.
327a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
329a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Functions used by the registration mechanism, checkers should not touch
330a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // these directly.
331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckDeclFunc;
334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
335a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef bool (*HandlesDeclFunc)(const Decl *D);
336a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
337a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForBody(CheckDeclFunc checkfn);
339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
340a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
341a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Internal registration functions for path-sensitive checking.
342a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
343a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
345a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const ObjCMessage &, CheckerContext &)>
347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckObjCMessageFunc;
348a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const SVal &location, bool isLoad,
350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          const Stmt *S,
351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          CheckerContext &)>
352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckLocationFunc;
353a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
354a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const SVal &location, const SVal &val,
355a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          const Stmt *S, CheckerContext &)>
356a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckBindFunc;
357a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
358a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
359a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckEndAnalysisFunc;
360a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
361a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (CheckerContext &)>
362a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckEndPathFunc;
363a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
364a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
365a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckBranchConditionFunc;
366a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
367a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
368a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckDeadSymbolsFunc;
369a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
370a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                const StoreManager::InvalidatedSymbols *symbols,
374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                ArrayRef<const MemRegion *> ExplicitRegions,
375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                ArrayRef<const MemRegion *> Regions,
376a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                const CallEvent *Call)>
377a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckRegionChangesFunc;
378a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
379a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
380a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
381a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                          const SVal &cond, bool assumption)>
383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      EvalAssumeFunc;
384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
385a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
386a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      EvalCallFunc;
387a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<bool (const CallExpr *, ExprEngine &Eng,
389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                            ExplodedNode *Pred,
390a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                            ExplodedNodeSet &Dst)>
391a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      InlineCallFunc;
392a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
393a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const TranslationUnitDecl *,
394a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                          AnalysisManager&, BugReporter &)>
395a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      CheckEndOfTranslationUnit;
396a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
397a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef bool (*HandlesStmtFunc)(const Stmt *D);
398a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForPreStmt(CheckStmtFunc checkfn,
399a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                           HandlesStmtFunc isForStmtFn);
400a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForPostStmt(CheckStmtFunc checkfn,
401a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                            HandlesStmtFunc isForStmtFn);
402a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
403a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
404a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
405a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
406a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForLocation(CheckLocationFunc checkfn);
407a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
408a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForBind(CheckBindFunc checkfn);
409a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
410a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
411a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
412a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForEndPath(CheckEndPathFunc checkfn);
413a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
414a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
415a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
416a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
417a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
418a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
419a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
420a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
421a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                                 WantsRegionChangeUpdateFunc wantUpdateFn);
422a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
423a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForEvalAssume(EvalAssumeFunc checkfn);
424a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
425a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForEvalCall(EvalCallFunc checkfn);
426a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
427a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForInlineCall(InlineCallFunc checkfn);
428a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
430a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
431a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
432a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Internal registration functions for events.
433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
434a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
435a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef void *EventTag;
436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef CheckerFn<void (const void *event)> CheckEventFunc;
437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
438a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  template <typename EVENT>
439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerListenerForEvent(CheckEventFunc checkfn) {
440a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    EventInfo &info = Events[getTag<EVENT>()];
441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    info.Checkers.push_back(checkfn);
442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
444a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  template <typename EVENT>
445a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _registerDispatcherForEvent() {
446a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    EventInfo &info = Events[getTag<EVENT>()];
447a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    info.HasDispatcher = true;
448a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
449a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
450a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  template <typename EVENT>
451a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void _dispatchEvent(const EVENT &event) const {
452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
453a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    if (I == Events.end())
454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return;
455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    const EventInfo &info = I->second;
456a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      info.Checkers[i](&event);
458a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
460a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
461a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Implementation details.
462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
464a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgprivate:
465a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  template <typename CHECKER>
466a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
467a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
468a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  template <typename T>
469a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static void *getTag() { static int tag; return &tag; }
470a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
471a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
472a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
473a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckerDtor> CheckerDtors;
474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  struct DeclCheckerInfo {
476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CheckDeclFunc CheckFn;
477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HandlesDeclFunc IsForDeclFn;
478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<DeclCheckerInfo> DeclCheckers;
480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckDeclFunc> BodyCheckers;
482a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
485a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CachedDeclCheckersMapTy CachedDeclCheckersMap;
486a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  struct StmtCheckerInfo {
488a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CheckStmtFunc CheckFn;
489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    HandlesStmtFunc IsForStmtFn;
490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    bool IsPreVisit;
491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
492a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<StmtCheckerInfo> StmtCheckers;
493a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
494a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  struct CachedStmtCheckersKey {
495a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    unsigned StmtKind;
496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    bool IsPreVisit;
497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
500a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
5013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
5023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    static CachedStmtCheckersKey getSentinel() {
503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return CachedStmtCheckersKey(~0U, 0);
504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
5053a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    unsigned getHashValue() const {
5063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      llvm::FoldingSetNodeID ID;
507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ID.AddInteger(StmtKind);
508a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      ID.AddBoolean(IsPreVisit);
509a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return ID.ComputeHash();
510a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    bool operator==(const CachedStmtCheckersKey &RHS) const {
512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
514a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
517378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
518378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
519378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      CachedStmtCheckersMapTy;
520378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CachedStmtCheckersMapTy CachedStmtCheckersMap;
521378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
522378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
523378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckLocationFunc> LocationCheckers;
528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckBindFunc> BindCheckers;
530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
5323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
5333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  std::vector<CheckEndPathFunc> EndPathCheckers;
5343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
535a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
537a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
538a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
539a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
540a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
541a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  struct RegionChangesCheckerInfo {
542a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    CheckRegionChangesFunc CheckFn;
543a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    WantsRegionChangeUpdateFunc WantUpdateFn;
544a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
545a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
546a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
547a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
548a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  std::vector<EvalCallFunc> EvalCallCheckers;
5503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  std::vector<InlineCallFunc> InlineCallCheckers;
552a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
554a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
555a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  struct EventInfo {
556a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SmallVector<CheckEventFunc, 4> Checkers;
557a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    bool HasDispatcher;
558a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    EventInfo() : HasDispatcher(false) { }
559a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
560a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
562a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  EventsTy Events;
563a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
5643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
565a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} // end ento namespace
566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
567378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} // end clang namespace
568a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
569a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace llvm {
570a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
571378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  /// in DenseMap and DenseSets.
572378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  template <>
5733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
574378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
575378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org        getEmptyKey() {
576378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return clang::ento::CheckerManager::CachedStmtCheckersKey();
577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
578a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
579a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        getTombstoneKey() {
5803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    static unsigned
584a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return S.getHashValue();
586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
590a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      return LHS == RHS;
591a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    }
592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
593378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} // end namespace llvm
594378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
595378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org#endif
596378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org