CheckerManager.h revision 8dae128d16bf98759b7a678ce3eebb613bd17109
137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//
337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//                     The LLVM Compiler Infrastructure
437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//
537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang// This file is distributed under the University of Illinois Open Source
637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang// License. See LICENSE.TXT for details.
737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//
837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//===----------------------------------------------------------------------===//
937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//
1037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang// Defines the Static Analyzer Checker Manager.
1137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//
1237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//===----------------------------------------------------------------------===//
1337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
1437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
1737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include "clang/Analysis/ProgramPoint.h"
1837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include "clang/Basic/LangOptions.h"
1937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
2037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
2137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include "llvm/ADT/DenseMap.h"
2237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include "llvm/ADT/FoldingSet.h"
2337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include "llvm/ADT/SmallVector.h"
2437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang#include <vector>
2537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
2637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangnamespace clang {
2737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class Decl;
2837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class Stmt;
2937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class CallExpr;
3037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
3137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangnamespace ento {
3237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class CheckerBase;
3337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class ExprEngine;
3437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class AnalysisManager;
3537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class BugReporter;
3637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class CheckerContext;
3737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class SimpleCall;
387d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris  class ObjCMethodCall;
397d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris  class SVal;
407d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris  class ExplodedNode;
411fdb08e5fc427b54b54214e3b3fbdda73d369f4dDavid Mosberger-Tang  class ExplodedNodeSet;
4237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class ExplodedGraph;
4337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  class ProgramState;
445f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  class NodeBuilder;
455f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  struct NodeBuilderContext;
465f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  class MemRegion;
475f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  class SymbolReaper;
485f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura
495f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuuratemplate <typename T> class CheckerFn;
505f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura
515f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuuratemplate <typename RET, typename P1, typename P2, typename P3, typename P4,
525f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura          typename P5>
535f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuuraclass CheckerFn<RET(P1, P2, P3, P4, P5)> {
545f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
555f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  Func Fn;
565f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuurapublic:
575f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  CheckerBase *Checker;
585f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
595f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
605f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura    return Fn(Checker, p1, p2, p3, p4, p5);
615f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  }
625f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura};
635f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura
645f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuuratemplate <typename RET, typename P1, typename P2, typename P3, typename P4>
6537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangclass CheckerFn<RET(P1, P2, P3, P4)> {
6637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  typedef RET (*Func)(void *, P1, P2, P3, P4);
6737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  Func Fn;
6837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangpublic:
6937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerBase *Checker;
7037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
7137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
7237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    return Fn(Checker, p1, p2, p3, p4);
7337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  }
7437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang};
7537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
7600db7f752ac26c5aab6b4ca03531a2c3e212b135Arun Sharmatemplate <typename RET, typename P1, typename P2, typename P3>
773842dac7333e42aa44531eda34ba55200b99ccf8Daniel Jacobowitzclass CheckerFn<RET(P1, P2, P3)> {
787d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris  typedef RET (*Func)(void *, P1, P2, P3);
797d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferris  Func Fn;
807d46a21e0a2cb561e4cad57b101a7137e01023dcChristopher Ferrispublic:
8137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerBase *Checker;
8237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
8337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
8437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang};
8537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
8637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangtemplate <typename RET, typename P1, typename P2>
879e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuuraclass CheckerFn<RET(P1, P2)> {
889e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura  typedef RET (*Func)(void *, P1, P2);
8937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  Func Fn;
9037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangpublic:
9137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerBase *Checker;
9237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
9337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
94c64723835c0c855fde5bec3d7528db64fe539015Konstantin Belousov};
95752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousov
96752ce15c4fbe0e08c2d19df18caa86887732b3c8Konstantin Belousovtemplate <typename RET, typename P1>
9737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangclass CheckerFn<RET(P1)> {
9837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  typedef RET (*Func)(void *, P1);
9937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  Func Fn;
100649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharmapublic:
101649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharma  CheckerBase *Checker;
10237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
10337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  RET operator()(P1 p1) const { return Fn(Checker, p1); }
104649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharma};
105649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharma
106649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharmatemplate <typename RET>
107649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharmaclass CheckerFn<RET()> {
108649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharma  typedef RET (*Func)(void *);
109649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharma  Func Fn;
110649f1fb3449a65dd0626a709432d8b02a7c56bbcArun Sharmapublic:
11137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerBase *Checker;
11237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
11337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  RET operator()() const { return Fn(Checker); }
11437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang};
11537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
11637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang/// \brief Describes the different reasons a pointer escapes
11737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang/// during analysis.
11837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangenum PointerEscapeKind {
119ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura  /// A pointer escapes due to binding its value to a location
12037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// that the analyzer cannot track.
12137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  PSK_EscapeOnBind,
122ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura
12337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// The pointer has been passed to a function call directly.
1248cdd8bfed8f21bb632faf69cca023c9762d78ab1Arun Sharma  PSK_DirectEscapeOnCall,
12537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
12637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// The pointer has been passed to a function indirectly.
12737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// For example, the pointer is accessible through an
12837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// argument to a function.
12937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  PSK_IndirectEscapeOnCall,
13037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
13137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// The reason for pointer escape is unknown. For example,
13237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// a region containing this pointer is invalidated.
13337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  PSK_EscapeOther
13437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang};
13537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
13637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tangclass CheckerManager {
13737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  const LangOptions LangOpts;
1388cdd8bfed8f21bb632faf69cca023c9762d78ab1Arun Sharma  AnalyzerOptionsRef AOptions;
1398cdd8bfed8f21bb632faf69cca023c9762d78ab1Arun Sharmapublic:
14037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CheckerManager(const LangOptions &langOpts,
14137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                 AnalyzerOptionsRef AOptions)
14237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    : LangOpts(langOpts),
14337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang      AOptions(AOptions) {}
14437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
14537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  ~CheckerManager();
14637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
14737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  bool hasPathSensitiveCheckers() const;
14837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
14937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  void finishedCheckerRegistration();
15037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
15137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  const LangOptions &getLangOpts() const { return LangOpts; }
15237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
15337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
15437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  typedef CheckerBase *CheckerRef;
15537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  typedef const void *CheckerTag;
15637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  typedef CheckerFn<void ()> CheckerDtor;
15737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
15837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//===----------------------------------------------------------------------===//
15937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang// registerChecker
16037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//===----------------------------------------------------------------------===//
16137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
16237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// \brief Used to register checkers.
16337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  ///
16437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// \returns a pointer to the checker object.
16537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  template <typename CHECKER>
16637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CHECKER *registerChecker() {
16737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    CheckerTag tag = getTag<CHECKER>();
16837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    CheckerRef &ref = CheckerTags[tag];
16937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    if (ref)
17037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang      return static_cast<CHECKER *>(ref); // already registered.
17137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
17237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    CHECKER *checker = new CHECKER();
17337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
17437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    CHECKER::_register(checker, *this);
17537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    ref = checker;
17637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    return checker;
17737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  }
17837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
17937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  template <typename CHECKER>
18037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  CHECKER *registerChecker(AnalyzerOptions &AOpts) {
18137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    CheckerTag tag = getTag<CHECKER>();
18237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    CheckerRef &ref = CheckerTags[tag];
18337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    if (ref)
18437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang      return static_cast<CHECKER *>(ref); // already registered.
18537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
186e2962af9d31266761700b431da894421c0d757ecArun Sharma    CHECKER *checker = new CHECKER(AOpts);
1875d0f376b08126b51a001d7cdfba1ec4e0d644f54Tommi Rantala    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
18828f33c8ce0b654cf31d6beda9a612870662f3c56Lassi Tuura    CHECKER::_register(checker, *this);
18937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    ref = checker;
19037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    return checker;
19137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  }
19237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
193d93d96ad833390519ea68a2df22dd55dd26a3214Martin Milata//===----------------------------------------------------------------------===//
19437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang// Functions for running checkers for AST traversing..
19537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang//===----------------------------------------------------------------------===//
19637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
197dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura  /// \brief Run checkers handling Decls.
198dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
199dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura                            BugReporter &BR);
200dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura
201dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura  /// \brief Run checkers handling Decls containing a Stmt body.
202dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
203dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura                            BugReporter &BR);
204dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura
205dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura//===----------------------------------------------------------------------===//
2069e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura// Functions for running checkers for path-sensitive checking.
2075f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura//===----------------------------------------------------------------------===//
208ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura
20937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// \brief Run checkers for pre-visiting Stmts.
21037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  ///
21137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// The notification is performed for every explored CFGElement, which does
21237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// not include the control flow statements such as IfStmt.
21337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  ///
21437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
21537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
21637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                             const ExplodedNodeSet &Src,
21737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                             const Stmt *S,
21837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                             ExprEngine &Eng) {
21937be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
22037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  }
22137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
22237be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// \brief Run checkers for post-visiting Stmts.
22337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  ///
22437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// The notification is performed for every explored CFGElement, which does
22537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// not include the control flow statements such as IfStmt.
22637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  ///
22737be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
22837be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
2295d0f376b08126b51a001d7cdfba1ec4e0d644f54Tommi Rantala                              const ExplodedNodeSet &Src,
23037be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                              const Stmt *S,
23137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                              ExprEngine &Eng,
23228f33c8ce0b654cf31d6beda9a612870662f3c56Lassi Tuura                              bool wasInlined = false) {
23337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
23437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  }
23537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang
236ae5c1f2adf4da04235d87d024d4d942c01b2b447Lassi Tuura  /// \brief Run checkers for visiting Stmts.
23716b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  void runCheckersForStmt(bool isPreVisit,
238f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
239f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris                          const Stmt *S, ExprEngine &Eng,
240f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris                          bool wasInlined = false);
241f4a8df5f4f338f1a12c25213227e98b34b42447fChristopher Ferris
24216b95a68caaa7e021209e2cd6a877ae1e558f740Christopher Ferris  /// \brief Run checkers for pre-visiting obj-c messages.
24337be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
24437be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                                    const ExplodedNodeSet &Src,
24537be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                                    const ObjCMethodCall &msg,
24637be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang                                    ExprEngine &Eng) {
247dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
248dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura  }
249dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura
250dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura  /// \brief Run checkers for post-visiting obj-c messages.
251dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
252dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura                                     const ExplodedNodeSet &Src,
253dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura                                     const ObjCMethodCall &msg,
2549e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura                                     ExprEngine &Eng,
2559e98f15e9aee12e67cd5956d06ccb559f6a06213Lassi Tuura                                     bool wasInlined = false) {
256dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
257dac2d001afb1fa7040ca7d8ae57032f684d7023eLassi Tuura                              wasInlined);
258e2962af9d31266761700b431da894421c0d757ecArun Sharma  }
2595f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura
2605f38f35d5d6c78aafa6da20845d9ceff74af00f8Lassi Tuura  /// \brief Run checkers for visiting obj-c messages.
26137be21c01ebe23402d4b5f1391e7a83da34e8c32David Mosberger-Tang  void runCheckersForObjCMessage(bool isPreVisit,
262                                 ExplodedNodeSet &Dst,
263                                 const ExplodedNodeSet &Src,
264                                 const ObjCMethodCall &msg, ExprEngine &Eng,
265                                 bool wasInlined = false);
266
267  /// \brief Run checkers for pre-visiting obj-c messages.
268  void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
269                             const CallEvent &Call, ExprEngine &Eng) {
270    runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
271  }
272
273  /// \brief Run checkers for post-visiting obj-c messages.
274  void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
275                              const CallEvent &Call, ExprEngine &Eng,
276                              bool wasInlined = false) {
277    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
278                            wasInlined);
279  }
280
281  /// \brief Run checkers for visiting obj-c messages.
282  void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
283                               const ExplodedNodeSet &Src,
284                               const CallEvent &Call, ExprEngine &Eng,
285                               bool wasInlined = false);
286
287  /// \brief Run checkers for load/store of a location.
288  void runCheckersForLocation(ExplodedNodeSet &Dst,
289                              const ExplodedNodeSet &Src,
290                              SVal location,
291                              bool isLoad,
292                              const Stmt *NodeEx,
293                              const Stmt *BoundEx,
294                              ExprEngine &Eng);
295
296  /// \brief Run checkers for binding of a value to a location.
297  void runCheckersForBind(ExplodedNodeSet &Dst,
298                          const ExplodedNodeSet &Src,
299                          SVal location, SVal val,
300                          const Stmt *S, ExprEngine &Eng,
301                          const ProgramPoint &PP);
302
303  /// \brief Run checkers for end of analysis.
304  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
305                                 ExprEngine &Eng);
306
307  /// \brief Run checkers on end of function.
308  void runCheckersForEndFunction(NodeBuilderContext &BC,
309                                 ExplodedNodeSet &Dst,
310                                 ExplodedNode *Pred,
311                                 ExprEngine &Eng);
312
313  /// \brief Run checkers for branch condition.
314  void runCheckersForBranchCondition(const Stmt *condition,
315                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
316                                     ExprEngine &Eng);
317
318  /// \brief Run checkers for live symbols.
319  ///
320  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
321  /// register symbols of interest as live. These symbols will not be marked
322  /// dead and removed.
323  void runCheckersForLiveSymbols(ProgramStateRef state,
324                                 SymbolReaper &SymReaper);
325
326  /// \brief Run checkers for dead symbols.
327  ///
328  /// Notifies checkers when symbols become dead. For example, this allows
329  /// checkers to aggressively clean up/reduce the checker state and produce
330  /// precise diagnostics.
331  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
332                                 const ExplodedNodeSet &Src,
333                                 SymbolReaper &SymReaper, const Stmt *S,
334                                 ExprEngine &Eng,
335                                 ProgramPoint::Kind K);
336
337  /// \brief True if at least one checker wants to check region changes.
338  bool wantsRegionChangeUpdate(ProgramStateRef state);
339
340  /// \brief Run checkers for region changes.
341  ///
342  /// This corresponds to the check::RegionChanges callback.
343  /// \param state The current program state.
344  /// \param invalidated A set of all symbols potentially touched by the change.
345  /// \param ExplicitRegions The regions explicitly requested for invalidation.
346  ///   For example, in the case of a function call, these would be arguments.
347  /// \param Regions The transitive closure of accessible regions,
348  ///   i.e. all regions that may have been touched by this change.
349  /// \param Call The call expression wrapper if the regions are invalidated
350  ///   by a call.
351  ProgramStateRef
352  runCheckersForRegionChanges(ProgramStateRef state,
353                              const InvalidatedSymbols *invalidated,
354                              ArrayRef<const MemRegion *> ExplicitRegions,
355                              ArrayRef<const MemRegion *> Regions,
356                              const CallEvent *Call);
357
358  /// \brief Run checkers when pointers escape.
359  ///
360  /// This notifies the checkers about pointer escape, which occurs whenever
361  /// the analyzer cannot track the symbol any more. For example, as a
362  /// result of assigning a pointer into a global or when it's passed to a
363  /// function call the analyzer cannot model.
364  ///
365  /// \param State The state at the point of escape.
366  /// \param Escaped The list of escaped symbols.
367  /// \param Call The corresponding CallEvent, if the symbols escape as
368  ///        parameters to the given call.
369  /// \param IsConst Specifies if the pointer is const.
370  /// \returns Checkers can modify the state by returning a new one.
371  ProgramStateRef
372  runCheckersForPointerEscape(ProgramStateRef State,
373                              const InvalidatedSymbols &Escaped,
374                              const CallEvent *Call,
375                              PointerEscapeKind Kind,
376                              bool IsConst = false);
377
378  /// \brief Run checkers for handling assumptions on symbolic values.
379  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
380                                           SVal Cond, bool Assumption);
381
382  /// \brief Run checkers for evaluating a call.
383  ///
384  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
385  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
386                              const ExplodedNodeSet &Src,
387                              const CallEvent &CE, ExprEngine &Eng);
388
389  /// \brief Run checkers for the entire Translation Unit.
390  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
391                                         AnalysisManager &mgr,
392                                         BugReporter &BR);
393
394  /// \brief Run checkers for debug-printing a ProgramState.
395  ///
396  /// Unlike most other callbacks, any checker can simply implement the virtual
397  /// method CheckerBase::printState if it has custom data to print.
398  /// \param Out The output stream
399  /// \param State The state being printed
400  /// \param NL The preferred representation of a newline.
401  /// \param Sep The preferred separator between different kinds of data.
402  void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
403                                const char *NL, const char *Sep);
404
405//===----------------------------------------------------------------------===//
406// Internal registration functions for AST traversing.
407//===----------------------------------------------------------------------===//
408
409  // Functions used by the registration mechanism, checkers should not touch
410  // these directly.
411
412  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
413      CheckDeclFunc;
414
415  typedef bool (*HandlesDeclFunc)(const Decl *D);
416  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
417
418  void _registerForBody(CheckDeclFunc checkfn);
419
420//===----------------------------------------------------------------------===//
421// Internal registration functions for path-sensitive checking.
422//===----------------------------------------------------------------------===//
423
424  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
425
426  typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
427      CheckObjCMessageFunc;
428
429  typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
430      CheckCallFunc;
431
432  typedef CheckerFn<void (const SVal &location, bool isLoad,
433                          const Stmt *S,
434                          CheckerContext &)>
435      CheckLocationFunc;
436
437  typedef CheckerFn<void (const SVal &location, const SVal &val,
438                          const Stmt *S, CheckerContext &)>
439      CheckBindFunc;
440
441  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
442      CheckEndAnalysisFunc;
443
444  typedef CheckerFn<void (CheckerContext &)>
445      CheckEndFunctionFunc;
446
447  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
448      CheckBranchConditionFunc;
449
450  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
451      CheckDeadSymbolsFunc;
452
453  typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
454
455  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
456                                const InvalidatedSymbols *symbols,
457                                ArrayRef<const MemRegion *> ExplicitRegions,
458                                ArrayRef<const MemRegion *> Regions,
459                                const CallEvent *Call)>
460      CheckRegionChangesFunc;
461
462  typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
463
464  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
465                                     const InvalidatedSymbols &Escaped,
466                                     const CallEvent *Call,
467                                     PointerEscapeKind Kind,
468                                     bool IsConst)>
469      CheckPointerEscapeFunc;
470
471  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
472                                          const SVal &cond, bool assumption)>
473      EvalAssumeFunc;
474
475  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
476      EvalCallFunc;
477
478  typedef CheckerFn<void (const TranslationUnitDecl *,
479                          AnalysisManager&, BugReporter &)>
480      CheckEndOfTranslationUnit;
481
482  typedef bool (*HandlesStmtFunc)(const Stmt *D);
483  void _registerForPreStmt(CheckStmtFunc checkfn,
484                           HandlesStmtFunc isForStmtFn);
485  void _registerForPostStmt(CheckStmtFunc checkfn,
486                            HandlesStmtFunc isForStmtFn);
487
488  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
489  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
490
491  void _registerForPreCall(CheckCallFunc checkfn);
492  void _registerForPostCall(CheckCallFunc checkfn);
493
494  void _registerForLocation(CheckLocationFunc checkfn);
495
496  void _registerForBind(CheckBindFunc checkfn);
497
498  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
499
500  void _registerForEndFunction(CheckEndFunctionFunc checkfn);
501
502  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
503
504  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
505
506  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
507
508  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
509                                 WantsRegionChangeUpdateFunc wantUpdateFn);
510
511  void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
512
513  void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
514
515  void _registerForEvalAssume(EvalAssumeFunc checkfn);
516
517  void _registerForEvalCall(EvalCallFunc checkfn);
518
519  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
520
521//===----------------------------------------------------------------------===//
522// Internal registration functions for events.
523//===----------------------------------------------------------------------===//
524
525  typedef void *EventTag;
526  typedef CheckerFn<void (const void *event)> CheckEventFunc;
527
528  template <typename EVENT>
529  void _registerListenerForEvent(CheckEventFunc checkfn) {
530    EventInfo &info = Events[getTag<EVENT>()];
531    info.Checkers.push_back(checkfn);
532  }
533
534  template <typename EVENT>
535  void _registerDispatcherForEvent() {
536    EventInfo &info = Events[getTag<EVENT>()];
537    info.HasDispatcher = true;
538  }
539
540  template <typename EVENT>
541  void _dispatchEvent(const EVENT &event) const {
542    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
543    if (I == Events.end())
544      return;
545    const EventInfo &info = I->second;
546    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
547      info.Checkers[i](&event);
548  }
549
550//===----------------------------------------------------------------------===//
551// Implementation details.
552//===----------------------------------------------------------------------===//
553
554private:
555  template <typename CHECKER>
556  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
557
558  template <typename T>
559  static void *getTag() { static int tag; return &tag; }
560
561  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
562
563  std::vector<CheckerDtor> CheckerDtors;
564
565  struct DeclCheckerInfo {
566    CheckDeclFunc CheckFn;
567    HandlesDeclFunc IsForDeclFn;
568  };
569  std::vector<DeclCheckerInfo> DeclCheckers;
570
571  std::vector<CheckDeclFunc> BodyCheckers;
572
573  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
574  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
575  CachedDeclCheckersMapTy CachedDeclCheckersMap;
576
577  struct StmtCheckerInfo {
578    CheckStmtFunc CheckFn;
579    HandlesStmtFunc IsForStmtFn;
580    bool IsPreVisit;
581  };
582  std::vector<StmtCheckerInfo> StmtCheckers;
583
584  struct CachedStmtCheckersKey {
585    unsigned StmtKind;
586    bool IsPreVisit;
587
588    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
589    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
590      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
591
592    static CachedStmtCheckersKey getSentinel() {
593      return CachedStmtCheckersKey(~0U, 0);
594    }
595    unsigned getHashValue() const {
596      llvm::FoldingSetNodeID ID;
597      ID.AddInteger(StmtKind);
598      ID.AddBoolean(IsPreVisit);
599      return ID.ComputeHash();
600    }
601    bool operator==(const CachedStmtCheckersKey &RHS) const {
602      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
603    }
604  };
605  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
606
607  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
608  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
609      CachedStmtCheckersMapTy;
610  CachedStmtCheckersMapTy CachedStmtCheckersMap;
611
612  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
613
614  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
615  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
616
617  std::vector<CheckCallFunc> PreCallCheckers;
618  std::vector<CheckCallFunc> PostCallCheckers;
619
620  std::vector<CheckLocationFunc> LocationCheckers;
621
622  std::vector<CheckBindFunc> BindCheckers;
623
624  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
625
626  std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
627
628  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
629
630  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
631
632  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
633
634  struct RegionChangesCheckerInfo {
635    CheckRegionChangesFunc CheckFn;
636    WantsRegionChangeUpdateFunc WantUpdateFn;
637  };
638  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
639
640  std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
641
642  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
643
644  std::vector<EvalCallFunc> EvalCallCheckers;
645
646  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
647
648  struct EventInfo {
649    SmallVector<CheckEventFunc, 4> Checkers;
650    bool HasDispatcher;
651    EventInfo() : HasDispatcher(false) { }
652  };
653
654  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
655  EventsTy Events;
656};
657
658} // end ento namespace
659
660} // end clang namespace
661
662namespace llvm {
663  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
664  /// in DenseMap and DenseSets.
665  template <>
666  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
667    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
668        getEmptyKey() {
669      return clang::ento::CheckerManager::CachedStmtCheckersKey();
670    }
671    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
672        getTombstoneKey() {
673      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
674    }
675
676    static unsigned
677        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
678      return S.getHashValue();
679    }
680
681    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
682                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
683      return LHS == RHS;
684    }
685  };
686} // end namespace llvm
687
688#endif
689