CheckerManager.h revision 3682f1ea9c7fddc7dcbc590891158ba40f7fca16
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//                     The LLVM Compiler Infrastructure
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// License. See LICENSE.TXT for details.
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===//
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Defines the Static Analyzer Checker Manager.
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===//
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "clang/Basic/LangOptions.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/ADT/SmallVector.h"
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "llvm/ADT/DenseMap.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "llvm/ADT/FoldingSet.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "clang/Analysis/ProgramPoint.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <vector>
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace clang {
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class Decl;
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class Stmt;
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class CallExpr;
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace ento {
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class CheckerBase;
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class ExprEngine;
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class AnalysisManager;
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class BugReporter;
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class CheckerContext;
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class SimpleCall;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class ObjCMethodCall;
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class SVal;
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class ExplodedNode;
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class ExplodedNodeSet;
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  class ExplodedGraph;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  class ProgramState;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  class NodeBuilder;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct NodeBuilderContext;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  class MemRegion;
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  class SymbolReaper;
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename T> class CheckerFn;
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3, typename P4,
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          typename P5>
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass CheckerFn<RET(P1, P2, P3, P4, P5)> {
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Func Fn;
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdochpublic:
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CheckerBase *Checker;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return Fn(Checker, p1, p2, p3, p4, p5);
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3, typename P4>
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CheckerFn<RET(P1, P2, P3, P4)> {
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef RET (*Func)(void *, P1, P2, P3, P4);
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Func Fn;
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public:
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckerBase *Checker;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return Fn(Checker, p1, p2, p3, p4);
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2, typename P3>
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CheckerFn<RET(P1, P2, P3)> {
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef RET (*Func)(void *, P1, P2, P3);
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Func Fn;
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public:
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckerBase *Checker;
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET, typename P1, typename P2>
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerFn<RET(P1, P2)> {
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef RET (*Func)(void *, P1, P2);
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Func Fn;
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)public:
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckerBase *Checker;
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <typename RET, typename P1>
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerFn<RET(P1)> {
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef RET (*Func)(void *, P1);
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Func Fn;
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public:
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckerBase *Checker;
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  RET operator()(P1 p1) const { return Fn(Checker, p1); }
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template <typename RET>
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerFn<RET()> {
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef RET (*Func)(void *);
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Func Fn;
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public:
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckerBase *Checker;
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RET operator()() const { return Fn(Checker); }
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class CheckerManager {
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const LangOptions LangOpts;
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)public:
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ~CheckerManager();
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool hasPathSensitiveCheckers() const;
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void finishedCheckerRegistration();
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const LangOptions &getLangOpts() const { return LangOpts; }
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef CheckerBase *CheckerRef;
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef const void *CheckerTag;
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef CheckerFn<void ()> CheckerDtor;
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===//
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// registerChecker
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//===----------------------------------------------------------------------===//
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Used to register checkers.
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ///
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \returns a pointer to the checker object.
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  template <typename CHECKER>
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CHECKER *registerChecker() {
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CheckerTag tag = getTag<CHECKER>();
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CheckerRef &ref = CheckerTags[tag];
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (ref)
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return static_cast<CHECKER *>(ref); // already registered.
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CHECKER *checker = new CHECKER();
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CHECKER::_register(checker, *this);
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ref = checker;
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return checker;
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===//
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Functions for running checkers for AST traversing..
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===//
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Run checkers handling Decls.
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            BugReporter &BR);
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Run checkers handling Decls containing a Stmt body.
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            BugReporter &BR);
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===//
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Functions for running checkers for path-sensitive checking.
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//===----------------------------------------------------------------------===//
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Run checkers for pre-visiting Stmts.
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ///
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// The notification is performed for every explored CFGElement, which does
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// not include the control flow statements such as IfStmt.
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ///
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             const ExplodedNodeSet &Src,
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             const Stmt *S,
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             ExprEngine &Eng) {
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Run checkers for post-visiting Stmts.
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ///
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// The notification is performed for every explored CFGElement, which does
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// not include the control flow statements such as IfStmt.
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ///
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              const ExplodedNodeSet &Src,
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              const Stmt *S,
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              ExprEngine &Eng,
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              bool wasInlined = false) {
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Run checkers for visiting Stmts.
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void runCheckersForStmt(bool isPreVisit,
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          const Stmt *S, ExprEngine &Eng,
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          bool wasInlined = false);
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Run checkers for pre-visiting obj-c messages.
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    const ExplodedNodeSet &Src,
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    const ObjCMethodCall &msg,
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                    ExprEngine &Eng) {
207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  /// \brief Run checkers for post-visiting obj-c messages.
211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     const ExplodedNodeSet &Src,
213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     const ObjCMethodCall &msg,
214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     ExprEngine &Eng,
215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     bool wasInlined = false) {
216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                              wasInlined);
218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// \brief Run checkers for visiting obj-c messages.
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void runCheckersForObjCMessage(bool isPreVisit,
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 ExplodedNodeSet &Dst,
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 const ExplodedNodeSet &Src,
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 const ObjCMethodCall &msg, ExprEngine &Eng,
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 bool wasInlined = false);
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// \brief Run checkers for pre-visiting obj-c messages.
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             const CallEvent &Call, ExprEngine &Eng) {
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// \brief Run checkers for post-visiting obj-c messages.
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              const CallEvent &Call, ExprEngine &Eng,
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              bool wasInlined = false) {
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            wasInlined);
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \brief Run checkers for visiting obj-c messages.
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const ExplodedNodeSet &Src,
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               const CallEvent &Call, ExprEngine &Eng,
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                               bool wasInlined = false);
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \brief Run checkers for load/store of a location.
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void runCheckersForLocation(ExplodedNodeSet &Dst,
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              const ExplodedNodeSet &Src,
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                              SVal location,
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              bool isLoad,
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const Stmt *NodeEx,
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                              const Stmt *BoundEx,
254e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch                              ExprEngine &Eng);
255e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
256e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  /// \brief Run checkers for binding of a value to a location.
257e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  void runCheckersForBind(ExplodedNodeSet &Dst,
258e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch                          const ExplodedNodeSet &Src,
259ab8f6f0bd665d3c1ff476eb06c58c42630e462d4Ben Murdoch                          SVal location, SVal val,
260e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch                          const Stmt *S, ExprEngine &Eng,
261e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch                          const ProgramPoint &PP);
262e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// \brief Run checkers for end of analysis.
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 ExprEngine &Eng);
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  /// \brief Run checkers for end of path.
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void runCheckersForEndPath(NodeBuilderContext &BC,
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             ExplodedNodeSet &Dst,
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             ExprEngine &Eng);
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// \brief Run checkers for branch condition.
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void runCheckersForBranchCondition(const Stmt *condition,
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     ExprEngine &Eng);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// \brief Run checkers for live symbols.
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ///
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  /// register symbols of interest as live. These symbols will not be marked
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// dead and removed.
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void runCheckersForLiveSymbols(ProgramStateRef state,
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 SymbolReaper &SymReaper);
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \brief Run checkers for dead symbols.
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ///
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// Notifies checkers when symbols become dead. For example, this allows
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// checkers to aggressively clean up/reduce the checker state and produce
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// precise diagnostics.
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 const ExplodedNodeSet &Src,
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 SymbolReaper &SymReaper, const Stmt *S,
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 ExprEngine &Eng,
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 ProgramPoint::Kind K);
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
296a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \brief True if at least one checker wants to check region changes.
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool wantsRegionChangeUpdate(ProgramStateRef state);
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \brief Run checkers for region changes.
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ///
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// This corresponds to the check::RegionChanges callback.
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \param state The current program state.
303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \param invalidated A set of all symbols potentially touched by the change.
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \param ExplicitRegions The regions explicitly requested for invalidation.
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ///   For example, in the case of a function call, these would be arguments.
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \param Regions The transitive closure of accessible regions,
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ///   i.e. all regions that may have been touched by this change.
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \param Call The call expression wrapper if the regions are invalidated
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ///   by a call.
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ProgramStateRef
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  runCheckersForRegionChanges(ProgramStateRef state,
312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            const StoreManager::InvalidatedSymbols *invalidated,
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              ArrayRef<const MemRegion *> ExplicitRegions,
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              ArrayRef<const MemRegion *> Regions,
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              const CallEvent *Call);
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  /// \brief Run checkers for handling assumptions on symbolic values.
318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                               SVal Cond, bool Assumption);
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
321  /// \brief Run checkers for evaluating a call.
322  ///
323  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
324  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
325                              const ExplodedNodeSet &Src,
326                              const CallEvent &CE, ExprEngine &Eng);
327
328  /// \brief Run checkers for the entire Translation Unit.
329  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
330                                         AnalysisManager &mgr,
331                                         BugReporter &BR);
332
333  /// \brief Run checkers for debug-printing a ProgramState.
334  ///
335  /// Unlike most other callbacks, any checker can simply implement the virtual
336  /// method CheckerBase::printState if it has custom data to print.
337  /// \param Out The output stream
338  /// \param State The state being printed
339  /// \param NL The preferred representation of a newline.
340  /// \param Sep The preferred separator between different kinds of data.
341  void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
342                                const char *NL, const char *Sep);
343
344//===----------------------------------------------------------------------===//
345// Internal registration functions for AST traversing.
346//===----------------------------------------------------------------------===//
347
348  // Functions used by the registration mechanism, checkers should not touch
349  // these directly.
350
351  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
352      CheckDeclFunc;
353
354  typedef bool (*HandlesDeclFunc)(const Decl *D);
355  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
356
357  void _registerForBody(CheckDeclFunc checkfn);
358
359//===----------------------------------------------------------------------===//
360// Internal registration functions for path-sensitive checking.
361//===----------------------------------------------------------------------===//
362
363  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
364
365  typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
366      CheckObjCMessageFunc;
367
368  typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
369      CheckCallFunc;
370
371  typedef CheckerFn<void (const SVal &location, bool isLoad,
372                          const Stmt *S,
373                          CheckerContext &)>
374      CheckLocationFunc;
375
376  typedef CheckerFn<void (const SVal &location, const SVal &val,
377                          const Stmt *S, CheckerContext &)>
378      CheckBindFunc;
379
380  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
381      CheckEndAnalysisFunc;
382
383  typedef CheckerFn<void (CheckerContext &)>
384      CheckEndPathFunc;
385
386  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
387      CheckBranchConditionFunc;
388
389  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
390      CheckDeadSymbolsFunc;
391
392  typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
393
394  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
395                                const StoreManager::InvalidatedSymbols *symbols,
396                                ArrayRef<const MemRegion *> ExplicitRegions,
397                                ArrayRef<const MemRegion *> Regions,
398                                const CallEvent *Call)>
399      CheckRegionChangesFunc;
400
401  typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
402
403  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
404                                          const SVal &cond, bool assumption)>
405      EvalAssumeFunc;
406
407  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
408      EvalCallFunc;
409
410  typedef CheckerFn<bool (const CallExpr *, ExprEngine &Eng,
411                                            ExplodedNode *Pred,
412                                            ExplodedNodeSet &Dst)>
413      InlineCallFunc;
414
415  typedef CheckerFn<void (const TranslationUnitDecl *,
416                          AnalysisManager&, BugReporter &)>
417      CheckEndOfTranslationUnit;
418
419  typedef bool (*HandlesStmtFunc)(const Stmt *D);
420  void _registerForPreStmt(CheckStmtFunc checkfn,
421                           HandlesStmtFunc isForStmtFn);
422  void _registerForPostStmt(CheckStmtFunc checkfn,
423                            HandlesStmtFunc isForStmtFn);
424
425  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
426  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
427
428  void _registerForPreCall(CheckCallFunc checkfn);
429  void _registerForPostCall(CheckCallFunc checkfn);
430
431  void _registerForLocation(CheckLocationFunc checkfn);
432
433  void _registerForBind(CheckBindFunc checkfn);
434
435  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
436
437  void _registerForEndPath(CheckEndPathFunc checkfn);
438
439  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
440
441  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
442
443  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
444
445  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
446                                 WantsRegionChangeUpdateFunc wantUpdateFn);
447
448  void _registerForEvalAssume(EvalAssumeFunc checkfn);
449
450  void _registerForEvalCall(EvalCallFunc checkfn);
451
452  void _registerForInlineCall(InlineCallFunc checkfn);
453
454  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
455
456//===----------------------------------------------------------------------===//
457// Internal registration functions for events.
458//===----------------------------------------------------------------------===//
459
460  typedef void *EventTag;
461  typedef CheckerFn<void (const void *event)> CheckEventFunc;
462
463  template <typename EVENT>
464  void _registerListenerForEvent(CheckEventFunc checkfn) {
465    EventInfo &info = Events[getTag<EVENT>()];
466    info.Checkers.push_back(checkfn);
467  }
468
469  template <typename EVENT>
470  void _registerDispatcherForEvent() {
471    EventInfo &info = Events[getTag<EVENT>()];
472    info.HasDispatcher = true;
473  }
474
475  template <typename EVENT>
476  void _dispatchEvent(const EVENT &event) const {
477    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
478    if (I == Events.end())
479      return;
480    const EventInfo &info = I->second;
481    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
482      info.Checkers[i](&event);
483  }
484
485//===----------------------------------------------------------------------===//
486// Implementation details.
487//===----------------------------------------------------------------------===//
488
489private:
490  template <typename CHECKER>
491  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
492
493  template <typename T>
494  static void *getTag() { static int tag; return &tag; }
495
496  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
497
498  std::vector<CheckerDtor> CheckerDtors;
499
500  struct DeclCheckerInfo {
501    CheckDeclFunc CheckFn;
502    HandlesDeclFunc IsForDeclFn;
503  };
504  std::vector<DeclCheckerInfo> DeclCheckers;
505
506  std::vector<CheckDeclFunc> BodyCheckers;
507
508  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
509  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
510  CachedDeclCheckersMapTy CachedDeclCheckersMap;
511
512  struct StmtCheckerInfo {
513    CheckStmtFunc CheckFn;
514    HandlesStmtFunc IsForStmtFn;
515    bool IsPreVisit;
516  };
517  std::vector<StmtCheckerInfo> StmtCheckers;
518
519  struct CachedStmtCheckersKey {
520    unsigned StmtKind;
521    bool IsPreVisit;
522
523    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
524    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
525      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
526
527    static CachedStmtCheckersKey getSentinel() {
528      return CachedStmtCheckersKey(~0U, 0);
529    }
530    unsigned getHashValue() const {
531      llvm::FoldingSetNodeID ID;
532      ID.AddInteger(StmtKind);
533      ID.AddBoolean(IsPreVisit);
534      return ID.ComputeHash();
535    }
536    bool operator==(const CachedStmtCheckersKey &RHS) const {
537      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
538    }
539  };
540  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
541
542  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
543  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
544      CachedStmtCheckersMapTy;
545  CachedStmtCheckersMapTy CachedStmtCheckersMap;
546
547  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
548
549  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
550  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
551
552  std::vector<CheckCallFunc> PreCallCheckers;
553  std::vector<CheckCallFunc> PostCallCheckers;
554
555  std::vector<CheckLocationFunc> LocationCheckers;
556
557  std::vector<CheckBindFunc> BindCheckers;
558
559  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
560
561  std::vector<CheckEndPathFunc> EndPathCheckers;
562
563  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
564
565  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
566
567  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
568
569  struct RegionChangesCheckerInfo {
570    CheckRegionChangesFunc CheckFn;
571    WantsRegionChangeUpdateFunc WantUpdateFn;
572  };
573  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
574
575  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
576
577  std::vector<EvalCallFunc> EvalCallCheckers;
578
579  std::vector<InlineCallFunc> InlineCallCheckers;
580
581  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
582
583  struct EventInfo {
584    SmallVector<CheckEventFunc, 4> Checkers;
585    bool HasDispatcher;
586    EventInfo() : HasDispatcher(false) { }
587  };
588
589  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
590  EventsTy Events;
591};
592
593} // end ento namespace
594
595} // end clang namespace
596
597namespace llvm {
598  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
599  /// in DenseMap and DenseSets.
600  template <>
601  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
602    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
603        getEmptyKey() {
604      return clang::ento::CheckerManager::CachedStmtCheckersKey();
605    }
606    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
607        getTombstoneKey() {
608      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
609    }
610
611    static unsigned
612        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
613      return S.getHashValue();
614    }
615
616    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
617                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
618      return LHS == RHS;
619    }
620  };
621} // end namespace llvm
622
623#endif
624