CheckerManager.h revision 2e471a3e476396be1ddca4ab8b9df721bcfc9437
143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- C++ -*-===//
243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
1043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Defines the Static Analyzer Checker Manager.
1143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//
1243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
1343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H
1643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
172e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h"
1843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "llvm/ADT/SmallVector.h"
199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "llvm/ADT/DenseMap.h"
20769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "llvm/ADT/FoldingSet.h"
219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include <vector>
2243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
2343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace clang {
249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class Decl;
25769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class Stmt;
2643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
2743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisnamespace ento {
2843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  class ExprEngine;
299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class AnalysisManager;
309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  class BugReporter;
31769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class CheckerContext;
32769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ObjCMessage;
33769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class SVal;
34769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class ExplodedNodeSet;
35769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  class GRState;
36769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
37769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisstruct VoidCheckerFnParm {};
38769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename P1=VoidCheckerFnParm, typename P2=VoidCheckerFnParm,
39769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis          typename P3=VoidCheckerFnParm, typename P4=VoidCheckerFnParm>
40769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn {
41769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef void (*Func)(void *, P1, P2, P3, P4);
42769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
43769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
44769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
45769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
46769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void operator()(P1 p1, P2 p2, P3 p3, P4 p4) { Fn(Checker, p1, p2, p3, p4); }
47769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
48769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
49769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename P1, typename P2, typename P3>
50769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn<P1, P2, P3, VoidCheckerFnParm> {
51769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef void (*Func)(void *, P1, P2, P3);
52769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
53769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
54769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
55769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
56769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void operator()(P1 p1, P2 p2, P3 p3) { Fn(Checker, p1, p2, p3); }
57769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
58769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
59769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename P1, typename P2>
60769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn<P1, P2, VoidCheckerFnParm, VoidCheckerFnParm> {
61769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef void (*Func)(void *, P1, P2);
62769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
63769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
64769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
65769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
66769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void operator()(P1 p1, P2 p2) { Fn(Checker, p1, p2); }
67769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
69769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <>
70769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisclass CheckerFn<VoidCheckerFnParm, VoidCheckerFnParm, VoidCheckerFnParm,
71769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                VoidCheckerFnParm> {
72769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef void (*Func)(void *);
73769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  Func Fn;
74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidispublic:
75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void *Checker;
76769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { }
77769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void operator()() { Fn(Checker); }
78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis};
7943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
8043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisclass CheckerManager {
812e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions LangOpts;
822e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
8343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidispublic:
842e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { }
859fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  ~CheckerManager();
869fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
872e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis  const LangOptions &getLangOptions() const { return LangOpts; }
882e471a3e476396be1ddca4ab8b9df721bcfc9437Argyrios Kyrtzidis
899fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef void *CheckerRef;
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef CheckerFn<> CheckerDtor;
919fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
929fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
939fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// registerChecker
949fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
959fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
969fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Used to register checkers.
979fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
989fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void registerChecker() {
999fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER *checker = new CHECKER();
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
1019fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CHECKER::_register(checker, *this);
1029fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
10343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1049fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef void (*RegisterToEngFunc)(ExprEngine &Eng);
105695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis  void addCheckerRegisterFunction(RegisterToEngFunc fn) {
10643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis    Funcs.push_back(fn);
10743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  }
1089fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1099fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
110769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
1119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls.
1149fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
1159fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1179fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  /// \brief Run checkers handling Decls containing a Stmt body.
1189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
1199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                            BugReporter &BR);
1209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
122769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
125769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting Stmts.
126769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreStmt(ExplodedNodeSet &Dst,
127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             ExplodedNodeSet &Src,
128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             const Stmt *S,
129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                             ExprEngine &Eng) {
130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng);
131769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
132769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
133769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting Stmts.
134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostStmt(ExplodedNodeSet &Dst,
135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExplodedNodeSet &Src,
136769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng) {
138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng);
139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting Stmts.
142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForStmt(bool isPreVisit,
143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                          ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                          const Stmt *S, ExprEngine &Eng);
145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for pre-visiting obj-c messages.
147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst,
148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ExplodedNodeSet &Src,
149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    const ObjCMessage &msg,
150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ExprEngine &Eng) {
151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng);
152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
153769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
154769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for post-visiting obj-c messages.
155769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     ExplodedNodeSet &Src,
157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     const ObjCMessage &msg,
158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                     ExprEngine &Eng) {
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for visiting obj-c messages.
163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForObjCMessage(bool isPreVisit,
164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                 ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                 const ObjCMessage &msg, ExprEngine &Eng);
166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// \brief Run checkers for load/store of a location.
168769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void runCheckersForLocation(ExplodedNodeSet &Dst,
169769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExplodedNodeSet &Src,
170769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              SVal location, bool isLoad,
171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const Stmt *S,
172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              const GRState *state,
173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                              ExprEngine &Eng);
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // FIXME: Temporary until checker running is moved completely into
176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  // CheckerManager.
177769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void registerCheckersToEngine(ExprEngine &eng);
178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
1819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
1829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
1839fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // Functions used by the registration mechanism, checkers should not touch
1849fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  // these directly.
1859fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef CheckerFn<const Decl *, AnalysisManager&, BugReporter &>
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckDeclFunc;
188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc;
189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
1909fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef bool (*HandlesDeclFunc)(const Decl *D);
191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn);
1929fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForBody(CheckDeclFunc checkfn);
194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
196769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef CheckerFn<const ObjCMessage &, CheckerContext &> CheckObjCMessageFunc;
200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef CheckerFn<const SVal &/*location*/, bool/*isLoad*/, CheckerContext &>
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckLocationFunc;
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef bool (*HandlesStmtFunc)(const Stmt *D);
204769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreStmt(CheckStmtFunc checkfn,
205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                           HandlesStmtFunc isForStmtFn);
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostStmt(CheckStmtFunc checkfn,
207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            HandlesStmtFunc isForStmtFn);
208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
209769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn);
210769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn);
211769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
212769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  void _registerForLocation(CheckLocationFunc checkfn);
213769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
214769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
216769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
21743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
21843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisprivate:
2199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  template <typename CHECKER>
2209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); }
2219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
222769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckerDtor> CheckerDtors;
223769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
2249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  std::vector<RegisterToEngFunc> Funcs;
2259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
2269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  struct DeclCheckerInfo {
2279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc CheckFn;
2289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    HandlesDeclFunc IsForDeclFn;
2299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  };
2309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  std::vector<DeclCheckerInfo> DeclCheckers;
2319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
232769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckDeclFunc> BodyCheckers;
2339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
234769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef llvm::SmallVector<CheckDeclFunc, 4> CachedDeclCheckers;
2359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy;
2369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy CachedDeclCheckersMap;
237769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
238769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct StmtCheckerInfo {
239769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtFunc CheckFn;
240769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    HandlesStmtFunc IsForStmtFn;
241769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
242769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
243769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<StmtCheckerInfo> StmtCheckers;
244769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
245769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CachedStmtCheckersKey {
246769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned StmtKind;
247769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
248769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
249769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { }
250769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit)
251769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : StmtKind(stmtKind), IsPreVisit(isPreVisit) { }
252769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
253769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static CachedStmtCheckersKey getSentinel() {
254fc26107870e0e450d863541179234bf9063a4da7Argyrios Kyrtzidis      return CachedStmtCheckersKey(~0U, 0);
255769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
256769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    unsigned getHashValue() const {
257769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      llvm::FoldingSetNodeID ID;
258769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddInteger(StmtKind);
259769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      ID.AddBoolean(IsPreVisit);
260769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return ID.ComputeHash();
261769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
262769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool operator==(const CachedStmtCheckersKey &RHS) const {
263769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit;
264769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
265769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
266769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>;
267769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
268769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef llvm::SmallVector<CheckStmtFunc, 4> CachedStmtCheckers;
269769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers>
270769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CachedStmtCheckersMapTy;
271769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy CachedStmtCheckersMap;
272769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
273769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit);
274769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
275769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers;
276769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers;
277769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
278769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  std::vector<CheckLocationFunc> LocationCheckers;
27943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis};
28043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
28143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end ento namespace
28243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
28343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis} // end clang namespace
28443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
285769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace llvm {
286769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key
287769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  /// in DenseMap and DenseSets.
288769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  template <>
289769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> {
290769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
291769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getEmptyKey() {
292769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey();
293769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
294769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static inline clang::ento::CheckerManager::CachedStmtCheckersKey
295769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getTombstoneKey() {
296769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel();
297769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
298769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
299769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static unsigned
300769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) {
301769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return S.getHashValue();
302769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
303769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
304769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS,
305769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       clang::ento::CheckerManager::CachedStmtCheckersKey RHS) {
306769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      return LHS == RHS;
307769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
308769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
309769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // end namespace llvm
310769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
31143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#endif
312