143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
1043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Defines the Static Analyzer Checker Manager.
1143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
1243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
1343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1730a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Analysis/ProgramPoint.h"
182e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h"
198dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "llvm/ADT/DenseMap.h"
2230a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/SmallVector.h"
239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include <vector>
2443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
2543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace clang {
269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class Decl;
27769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class Stmt;
28e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class CallExpr;
2943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
3043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace ento {
31ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  class CheckerBase;
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class CheckerRegistry;
3343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  class ExprEngine;
349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class AnalysisManager;
359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class BugReporter;
36769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class CheckerContext;
37de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  class ObjCMethodCall;
38769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class SVal;
39e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  class ExplodedNode;
40769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ExplodedNodeSet;
4130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  class ExplodedGraph;
4218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  class ProgramState;
43cd656cab3fa3dd4b0c974c6ae1c0e60880b18c22Anna Zaks  class NodeBuilder;
44af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  struct NodeBuilderContext;
45183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class MemRegion;
46183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  class SymbolReaper;
47769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
484d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename T> class CheckerFn;
494d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
5066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zakstemplate <typename RET, typename P1, typename P2, typename P3, typename P4,
5166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks          typename P5>
5266c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaksclass CheckerFn<RET(P1, P2, P3, P4, P5)> {
5366c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  typedef RET (*Func)(void *, P1, P2, P3, P4, P5);
5466c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  Func Fn;
5566c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zakspublic:
5666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  CheckerBase *Checker;
5766c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
5866c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const {
5966c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks    return Fn(Checker, p1, p2, p3, p4, p5);
6066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks  }
6166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks};
6266c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks
6335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenektemplate <typename RET, typename P1, typename P2, typename P3, typename P4>
6435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekclass CheckerFn<RET(P1, P2, P3, P4)> {
6535bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  typedef RET (*Func)(void *, P1, P2, P3, P4);
6635bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  Func Fn;
6735bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenekpublic:
68ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
69ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
7035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const {
7135bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek    return Fn(Checker, p1, p2, p3, p4);
7235bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek  }
7335bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek};
7435bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek
754d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2, typename P3>
764d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2, P3)> {
774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2, P3);
78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
79769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
80ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
81ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
824d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); }
83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
854d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1, typename P2>
864d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1, P2)> {
874d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1, P2);
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
90ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
91ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
924d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); }
93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
954d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET, typename P1>
964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET(P1)> {
974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *, P1);
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
100ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
101ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1024d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()(P1 p1) const { return Fn(Checker, p1); }
103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
1054d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidistemplate <typename RET>
1064d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidisclass CheckerFn<RET()> {
1074d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef RET (*Func)(void *);
108769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
110ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerBase *Checker;
111ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { }
1124d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  RET operator()() const { return Fn(Checker); }
113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
11443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
115233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks/// \brief Describes the different reasons a pointer escapes
116233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks/// during analysis.
117233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaksenum PointerEscapeKind {
118233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// A pointer escapes due to binding its value to a location
119233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// that the analyzer cannot track.
120233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_EscapeOnBind,
121233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
122233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// The pointer has been passed to a function call directly.
123233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_DirectEscapeOnCall,
124233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
125233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// The pointer has been passed to a function indirectly.
126233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// For example, the pointer is accessible through an
127233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// argument to a function.
128233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_IndirectEscapeOnCall,
129233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
130233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// The reason for pointer escape is unknown. For example,
131233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  /// a region containing this pointer is invalidated.
132233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks  PSK_EscapeOther
133233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks};
134233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// This wrapper is used to ensure that only StringRefs originating from the
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CheckerRegistry are used as check names. We want to make sure all check
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// name strings have a lifetime that keeps them alive at least until the path
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// diagnostics have been processed.
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesclass CheckName {
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StringRef Name;
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  friend class ::clang::ento::CheckerRegistry;
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  explicit CheckName(StringRef Name) : Name(Name) {}
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinespublic:
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName() {}
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName(const CheckName &Other) : Name(Other.Name) {}
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StringRef getName() const { return Name; }
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
15043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager {
1512e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions LangOpts;
1528dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek  AnalyzerOptionsRef AOptions;
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName CurrentCheckName;
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
15543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic:
1568dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek  CheckerManager(const LangOptions &langOpts,
1578dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek                 AnalyzerOptionsRef AOptions)
1588dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    : LangOpts(langOpts),
1598dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek      AOptions(AOptions) {}
1608dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek
1619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  ~CheckerManager();
1629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CheckName getCurrentCheckName() const { return CurrentCheckName; }
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
166d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis  bool hasPathSensitiveCheckers() const;
167d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis
168deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void finishedCheckerRegistration();
169deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
1704e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  const LangOptions &getLangOpts() const { return LangOpts; }
1718dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek  AnalyzerOptions &getAnalyzerOptions() { return *AOptions; }
1722e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
173ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef CheckerBase *CheckerRef;
174ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek  typedef const void *CheckerTag;
1754d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void ()> CheckerDtor;
1769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker
1799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Used to register checkers.
1823fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  ///
1833fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  /// \returns a pointer to the checker object.
1849fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
1853fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  CHECKER *registerChecker() {
186deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    CheckerTag tag = getTag<CHECKER>();
1873fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    CheckerRef &ref = CheckerTags[tag];
1883fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    if (ref)
1893fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis      return static_cast<CHECKER *>(ref); // already registered.
1903fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
1919fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER *checker = new CHECKER();
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    checker->Name = CurrentCheckName;
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
1949fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER::_register(checker, *this);
1953fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    ref = checker;
1963fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis    return checker;
1979fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
19843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1998dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek  template <typename CHECKER>
2008dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek  CHECKER *registerChecker(AnalyzerOptions &AOpts) {
2018dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    CheckerTag tag = getTag<CHECKER>();
2028dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    CheckerRef &ref = CheckerTags[tag];
2038dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    if (ref)
2048dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek      return static_cast<CHECKER *>(ref); // already registered.
2058dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek
2068dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    CHECKER *checker = new CHECKER(AOpts);
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    checker->Name = CurrentCheckName;
2088dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
2098dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    CHECKER::_register(checker, *this);
2108dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    ref = checker;
2118dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek    return checker;
2128dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek  }
2138dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek
2149fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
2169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
2179fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls.
2199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
2209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
2219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls containing a Stmt body.
2239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
2249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
2259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
227769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
228769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
229769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
230769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting Stmts.
231c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
232c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// The notification is performed for every explored CFGElement, which does
233c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// not include the control flow statements such as IfStmt.
234c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
235c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// \sa runCheckersForBranchCondition, runCheckersForPostStmt
236769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
237cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                             const ExplodedNodeSet &Src,
238769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             const Stmt *S,
239769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             ExprEngine &Eng) {
240769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
241769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
242769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
243769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting Stmts.
244c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
245c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// The notification is performed for every explored CFGElement, which does
246c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// not include the control flow statements such as IfStmt.
247c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
248c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// \sa runCheckersForBranchCondition, runCheckersForPreStmt
249769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
250cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
251769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
252514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                              ExprEngine &Eng,
253514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                              bool wasInlined = false) {
254514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng, wasInlined);
255769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
256769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
257769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting Stmts.
258769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForStmt(bool isPreVisit,
259cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                          ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
260514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                          const Stmt *S, ExprEngine &Eng,
261514f2c9dcb9e04b52929c5b141a6fe88bd68b33fTed Kremenek                          bool wasInlined = false);
262769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
263769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting obj-c messages.
264769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
265cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                    const ExplodedNodeSet &Src,
266de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose                                    const ObjCMethodCall &msg,
267769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ExprEngine &Eng) {
268769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
269769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
270769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
271769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting obj-c messages.
272769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
273cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                     const ExplodedNodeSet &Src,
274de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose                                     const ObjCMethodCall &msg,
27557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                     ExprEngine &Eng,
27657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                     bool wasInlined = false) {
27757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
27857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                              wasInlined);
279769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
280769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
281769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting obj-c messages.
282769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForObjCMessage(bool isPreVisit,
283cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 ExplodedNodeSet &Dst,
284cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
28557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                 const ObjCMethodCall &msg, ExprEngine &Eng,
28657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                                 bool wasInlined = false);
287769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
28896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  /// \brief Run checkers for pre-visiting obj-c messages.
28996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
29096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                             const CallEvent &Call, ExprEngine &Eng) {
29196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose    runCheckersForCallEvent(/*isPreVisit=*/true, Dst, Src, Call, Eng);
29296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
29396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
29496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  /// \brief Run checkers for post-visiting obj-c messages.
29596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
29657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                              const CallEvent &Call, ExprEngine &Eng,
29757c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                              bool wasInlined = false) {
29857c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
29957c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                            wasInlined);
30096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  }
30196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
30296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  /// \brief Run checkers for visiting obj-c messages.
30396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
30496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose                               const ExplodedNodeSet &Src,
30557c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                               const CallEvent &Call, ExprEngine &Eng,
30657c033621dacd8720ac9ff65a09025f14f70e22fJordan Rose                               bool wasInlined = false);
30796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
308769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for load/store of a location.
309769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForLocation(ExplodedNodeSet &Dst,
310cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
311bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              SVal location,
312bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              bool isLoad,
313bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *NodeEx,
314bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                              const Stmt *BoundEx,
315769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng);
316769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
317312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for binding of a value to a location.
318312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void runCheckersForBind(ExplodedNodeSet &Dst,
319312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          const ExplodedNodeSet &Src,
320312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                          SVal location, SVal val,
321ebae6d0209e1ec3d5ea14f9e63bd0d740218ed14Anna Zaks                          const Stmt *S, ExprEngine &Eng,
3223682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose                          const ProgramPoint &PP);
323312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
32430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  /// \brief Run checkers for end of analysis.
32530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR,
32630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                 ExprEngine &Eng);
32730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
328344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  /// \brief Run checkers on end of function.
329344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  void runCheckersForEndFunction(NodeBuilderContext &BC,
330344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                 ExplodedNodeSet &Dst,
331344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                 ExplodedNode *Pred,
332344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks                                 ExprEngine &Eng);
333af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
334cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  /// \brief Run checkers for branch condition.
335cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void runCheckersForBranchCondition(const Stmt *condition,
336f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks                                     ExplodedNodeSet &Dst, ExplodedNode *Pred,
3374e82d3cf6fd4c907265e3fa3aac0a835c35dc759Anna Zaks                                     ExprEngine &Eng);
338cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
339183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for live symbols.
340c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
341c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// Allows modifying SymbolReaper object. For example, checkers can explicitly
342c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// register symbols of interest as live. These symbols will not be marked
343c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// dead and removed.
34423111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  void runCheckersForLiveSymbols(ProgramStateRef state,
345183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper);
346183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
347183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for dead symbols.
348c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  ///
349c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// Notifies checkers when symbols become dead. For example, this allows
350c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// checkers to aggressively clean up/reduce the checker state and produce
351c41f3652f4e836cff988320bad2d6c5f416ebe1fAnna Zaks  /// precise diagnostics.
352183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
353183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 const ExplodedNodeSet &Src,
354183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 SymbolReaper &SymReaper, const Stmt *S,
3550b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                 ExprEngine &Eng,
3560b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks                                 ProgramPoint::Kind K);
357183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
358183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief True if at least one checker wants to check region changes.
35923111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  bool wantsRegionChangeUpdate(ProgramStateRef state);
360183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
361183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  /// \brief Run checkers for region changes.
362537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///
363537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// This corresponds to the check::RegionChanges callback.
364537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param state The current program state.
365537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param invalidated A set of all symbols potentially touched by the change.
366537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param ExplicitRegions The regions explicitly requested for invalidation.
367537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   For example, in the case of a function call, these would be arguments.
368537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  /// \param Regions The transitive closure of accessible regions,
369537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose  ///   i.e. all regions that may have been touched by this change.
3707c0d2a366d2810e711f9c6ced8cbd923b9fc823aJames Dennett  /// \param Call The call expression wrapper if the regions are invalidated
3717c0d2a366d2810e711f9c6ced8cbd923b9fc823aJames Dennett  ///   by a call.
3727c0d2a366d2810e711f9c6ced8cbd923b9fc823aJames Dennett  ProgramStateRef
37323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  runCheckersForRegionChanges(ProgramStateRef state,
374bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                              const InvalidatedSymbols *invalidated,
375537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                              ArrayRef<const MemRegion *> ExplicitRegions,
37666c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                              ArrayRef<const MemRegion *> Regions,
377740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                              const CallEvent *Call);
378183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
379bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \brief Run checkers when pointers escape.
380bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  ///
381bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// This notifies the checkers about pointer escape, which occurs whenever
3821655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  /// the analyzer cannot track the symbol any more. For example, as a
383bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// result of assigning a pointer into a global or when it's passed to a
384bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// function call the analyzer cannot model.
385bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  ///
386bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \param State The state at the point of escape.
387bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \param Escaped The list of escaped symbols.
388bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \param Call The corresponding CallEvent, if the symbols escape as
3891655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  ///        parameters to the given call.
390da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev  /// \param Kind The reason of pointer escape.
391da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev  /// \param ITraits Information about invalidation for a particular
392da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev  ///        region/symbol.
393bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  /// \returns Checkers can modify the state by returning a new one.
3941655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  ProgramStateRef
3951655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks  runCheckersForPointerEscape(ProgramStateRef State,
3961655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks                              const InvalidatedSymbols &Escaped,
397233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                              const CallEvent *Call,
39841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                              PointerEscapeKind Kind,
399da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                             RegionAndSymbolInvalidationTraits *ITraits);
400bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
401312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  /// \brief Run checkers for handling assumptions on symbolic values.
40223111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  ProgramStateRef runCheckersForEvalAssume(ProgramStateRef state,
4031655bcd052a67a3050fc55df8ecce57342352e68Anna Zaks                                           SVal Cond, bool Assumption);
404312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
405e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  /// \brief Run checkers for evaluating a call.
406645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose  ///
407645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
408e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void runCheckersForEvalCall(ExplodedNodeSet &Dst,
409e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                              const ExplodedNodeSet &Src,
410645baeed6800f952e9ad1d5666e01080385531a2Jordan Rose                              const CallEvent &CE, ExprEngine &Eng);
4119be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
4129be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  /// \brief Run checkers for the entire Translation Unit.
4139c378f705405d37f49795d5e915989de774fe11fTed Kremenek  void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
4149be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         AnalysisManager &mgr,
4159be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                         BugReporter &BR);
416e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
417dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \brief Run checkers for debug-printing a ProgramState.
418dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  ///
419dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// Unlike most other callbacks, any checker can simply implement the virtual
420dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// method CheckerBase::printState if it has custom data to print.
421dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param Out The output stream
422dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param State The state being printed
423dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param NL The preferred representation of a newline.
424dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  /// \param Sep The preferred separator between different kinds of data.
42523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  void runCheckersForPrintState(raw_ostream &Out, ProgramStateRef State,
426dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                                const char *NL, const char *Sep);
427dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
428769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
429769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
4309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
4319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
4329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Functions used by the registration mechanism, checkers should not touch
4339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // these directly.
4349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
4354d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Decl *, AnalysisManager&, BugReporter &)>
436769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckDeclFunc;
437769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
4389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef bool (*HandlesDeclFunc)(const Decl *D);
439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
4409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
441769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForBody(CheckDeclFunc checkfn);
442769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
443769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
444769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
445769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
446769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
4474d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const Stmt *, CheckerContext &)> CheckStmtFunc;
4484d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
449de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose  typedef CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>
4504d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckObjCMessageFunc;
45196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
45296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  typedef CheckerFn<void (const CallEvent &, CheckerContext &)>
45396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose      CheckCallFunc;
4544d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
455bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek  typedef CheckerFn<void (const SVal &location, bool isLoad,
456bd613137499b1d4c3b63dccd0aa21f6add243f4fTed Kremenek                          const Stmt *S,
457390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                          CheckerContext &)>
458769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckLocationFunc;
4594d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
460390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks  typedef CheckerFn<void (const SVal &location, const SVal &val,
461390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks                          const Stmt *S, CheckerContext &)>
462390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks      CheckBindFunc;
4634d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
4644d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>
46530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis      CheckEndAnalysisFunc;
4664d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
467af498a28797c075c48d7e943df5f5a8e78ed8eb0Anna Zaks  typedef CheckerFn<void (CheckerContext &)>
468344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks      CheckEndFunctionFunc;
4694d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
470f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks  typedef CheckerFn<void (const Stmt *, CheckerContext &)>
471cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis      CheckBranchConditionFunc;
4724d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
4734d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (SymbolReaper &, CheckerContext &)>
4744d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckDeadSymbolsFunc;
4754d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
47623111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
4774d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
47823111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
479bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                                const InvalidatedSymbols *symbols,
48066c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                ArrayRef<const MemRegion *> ExplicitRegions,
48166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks                                ArrayRef<const MemRegion *> Regions,
482740d490593e0de8732a697c9f77b90ddd463863bJordan Rose                                const CallEvent *Call)>
4834d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      CheckRegionChangesFunc;
4844d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
48523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<bool (ProgramStateRef)> WantsRegionChangeUpdateFunc;
486bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
487bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
488bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks                                     const InvalidatedSymbols &Escaped,
489233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks                                     const CallEvent *Call,
49041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks                                     PointerEscapeKind Kind,
491da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev                                     RegionAndSymbolInvalidationTraits *ITraits)>
492bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks      CheckPointerEscapeFunc;
4934d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
49423111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek  typedef CheckerFn<ProgramStateRef (ProgramStateRef,
49518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                          const SVal &cond, bool assumption)>
4964d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalAssumeFunc;
4974d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis
4984d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<bool (const CallExpr *, CheckerContext &)>
4994d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis      EvalCallFunc;
500769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
5019be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  typedef CheckerFn<void (const TranslationUnitDecl *,
5029be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                          AnalysisManager&, BugReporter &)>
5039be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek      CheckEndOfTranslationUnit;
5049be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
505769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef bool (*HandlesStmtFunc)(const Stmt *D);
506769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreStmt(CheckStmtFunc checkfn,
507769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                           HandlesStmtFunc isForStmtFn);
508769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostStmt(CheckStmtFunc checkfn,
509769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            HandlesStmtFunc isForStmtFn);
510769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
511769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
512769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
513769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
51496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void _registerForPreCall(CheckCallFunc checkfn);
51596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  void _registerForPostCall(CheckCallFunc checkfn);
51696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
517769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForLocation(CheckLocationFunc checkfn);
518769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
519312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForBind(CheckBindFunc checkfn);
520312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
52130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn);
52230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
523344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  void _registerForEndFunction(CheckEndFunctionFunc checkfn);
524af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
525cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  void _registerForBranchCondition(CheckBranchConditionFunc checkfn);
526cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
527183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn);
528183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
529183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn);
530183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
531183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  void _registerForRegionChanges(CheckRegionChangesFunc checkfn,
532183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                 WantsRegionChangeUpdateFunc wantUpdateFn);
533183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
534bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  void _registerForPointerEscape(CheckPointerEscapeFunc checkfn);
535bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
53641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks  void _registerForConstPointerEscape(CheckPointerEscapeFunc checkfn);
53741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks
538312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  void _registerForEvalAssume(EvalAssumeFunc checkfn);
539312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
540e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  void _registerForEvalCall(EvalCallFunc checkfn);
541e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
5429be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn);
5439be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
544769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
545deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis// Internal registration functions for events.
546deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
547deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
548deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef void *EventTag;
5494d840e9ac4d8e9baa9459ca3dd7ab14ae884a80fArgyrios Kyrtzidis  typedef CheckerFn<void (const void *event)> CheckEventFunc;
550deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
551deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
552deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerListenerForEvent(CheckEventFunc checkfn) {
553deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
554deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.Checkers.push_back(checkfn);
555deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
556deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
557deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
558deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _registerDispatcherForEvent() {
559deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo &info = Events[getTag<EVENT>()];
560deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    info.HasDispatcher = true;
561deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
562deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
563deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename EVENT>
564deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  void _dispatchEvent(const EVENT &event) const {
565deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventsTy::const_iterator I = Events.find(getTag<EVENT>());
566deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    if (I == Events.end())
567deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      return;
568deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    const EventInfo &info = I->second;
569deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i)
570deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis      info.Checkers[i](&event);
571deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  }
572deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
573deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
574769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
575769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
57643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
57743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate:
5789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
5799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
5809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
581deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  template <typename T>
582deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  static void *getTag() { static int tag; return &tag; }
5833fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
5843fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis  llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags;
5853fe71f445f76003649b5da24209e80225a7ee74fArgyrios Kyrtzidis
586769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckerDtor> CheckerDtors;
587769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
5889fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  struct DeclCheckerInfo {
5899fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc CheckFn;
5909fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    HandlesDeclFunc IsForDeclFn;
5919fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  };
5929fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  std::vector<DeclCheckerInfo> DeclCheckers;
5939fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
594769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckDeclFunc> BodyCheckers;
5959fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
596686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
5979fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
5989fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy CachedDeclCheckersMap;
599769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
600769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct StmtCheckerInfo {
601769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtFunc CheckFn;
602769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    HandlesStmtFunc IsForStmtFn;
603769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
604769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
605769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<StmtCheckerInfo> StmtCheckers;
606769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
607686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
608e9a906b99286b44dcf5eb896f17df74d588e4ce9Benjamin Kramer  typedef llvm::DenseMap<unsigned, CachedStmtCheckers> CachedStmtCheckersMapTy;
609769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy CachedStmtCheckersMap;
610769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
611e9a906b99286b44dcf5eb896f17df74d588e4ce9Benjamin Kramer  const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S,
612e9a906b99286b44dcf5eb896f17df74d588e4ce9Benjamin Kramer                                                     bool isPreVisit);
613769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
614769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
615769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
616769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
61796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  std::vector<CheckCallFunc> PreCallCheckers;
61896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose  std::vector<CheckCallFunc> PostCallCheckers;
61996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose
620769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckLocationFunc> LocationCheckers;
62130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
622312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<CheckBindFunc> BindCheckers;
623312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
62430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers;
625e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
626344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks  std::vector<CheckEndFunctionFunc> EndFunctionCheckers;
627af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
628cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  std::vector<CheckBranchConditionFunc> BranchConditionCheckers;
629cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
630183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers;
631183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
632183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers;
633183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
634183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  struct RegionChangesCheckerInfo {
635183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckRegionChangesFunc CheckFn;
636183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    WantsRegionChangeUpdateFunc WantUpdateFn;
637183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  };
638183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  std::vector<RegionChangesCheckerInfo> RegionChangesCheckers;
639183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
640bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks  std::vector<CheckPointerEscapeFunc> PointerEscapeCheckers;
641bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks
642312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  std::vector<EvalAssumeFunc> EvalAssumeCheckers;
643312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
644e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  std::vector<EvalCallFunc> EvalCallCheckers;
645deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
6469be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers;
6479be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
648deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  struct EventInfo {
649686775deca8b8685eb90801495880e3abdd844c2Chris Lattner    SmallVector<CheckEventFunc, 4> Checkers;
650deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    bool HasDispatcher;
651deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    EventInfo() : HasDispatcher(false) { }
652deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  };
653deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
654deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  typedef llvm::DenseMap<EventTag, EventInfo> EventsTy;
655deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  EventsTy Events;
65643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis};
65743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
65843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace
65943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
66043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace
66143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
66243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif
663