CheckerManager.cpp revision cd50e136ad7dc721822f5e6350769a37c216612d
143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis//===--- CheckerManager.cpp - Static Analyzer Checker Manager -------------===//
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#include "clang/StaticAnalyzer/Core/CheckerManager.h"
1543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
16769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
17769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis#include "clang/Analysis/ProgramPoint.h"
189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "clang/AST/DeclBase.h"
1943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
2043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace clang;
2143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace ento;
2243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
23769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
24769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
25769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
26769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                          BugReporter &BR) {
299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(D);
309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  unsigned DeclKind = D->getKind();
329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckers *checkers = 0;
339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind);
349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  if (CCI != CachedDeclCheckersMap.end()) {
359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    checkers = &(CCI->second);
369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  } else {
379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    // Find the checkers that should run for this Decl and cache them.
389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    checkers = &CachedDeclCheckersMap[DeclKind];
399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    for (unsigned i = 0, e = DeclCheckers.size(); i != e; ++i) {
409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      DeclCheckerInfo &info = DeclCheckers[i];
419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      if (info.IsForDeclFn(D))
42769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        checkers->push_back(info.CheckFn);
439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    }
449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(checkers);
479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  for (CachedDeclCheckers::iterator
48769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis         I = checkers->begin(), E = checkers->end(); I != E; ++I)
49769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    (*I)(D, mgr, BR);
509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                          BugReporter &BR) {
549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(D && D->hasBody());
559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
56769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  for (unsigned i = 0, e = BodyCheckers.size(); i != e; ++i)
57769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    BodyCheckers[i](D, mgr, BR);
58769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
59769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
60769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
61769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
62769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
63769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
64769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename CHECK_CTX>
65c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidisstatic void expandGraphWithCheckers(CHECK_CTX checkCtx,
66c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis                                    ExplodedNodeSet &Dst,
67cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                    const ExplodedNodeSet &Src) {
68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
69e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  typename CHECK_CTX::CheckersTy::const_iterator
70e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
71e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  if (I == E) {
72769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    Dst.insert(Src);
73769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    return;
74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
76cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis  ExplodedNodeSet Tmp1, Tmp2;
77cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis  const ExplodedNodeSet *PrevSet = &Src;
78769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
79e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  for (; I != E; ++I) {
80769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExplodedNodeSet *CurrSet = 0;
81769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    if (I+1 == E)
82769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CurrSet = &Dst;
83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    else {
84cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis      CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1;
85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CurrSet->clear();
86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis         NI != NE; ++NI)
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkCtx.runChecker(*I, *CurrSet, *NI);
91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
92769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    // Update which NodeSet is the current one.
93769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    PrevSet = CurrSet;
949fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
959fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
969fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
97769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace {
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CheckStmtContext {
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    typedef llvm::SmallVectorImpl<CheckerManager::CheckStmtFunc> CheckersTy;
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const CheckersTy &Checkers;
102769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const Stmt *S;
103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExprEngine &Eng;
104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
105e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
106e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
107e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
108769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtContext(bool isPreVisit, const CheckersTy &checkers,
109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                     const Stmt *s, ExprEngine &eng)
110769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng) { }
111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
112769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckStmtFunc checkFn,
113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      // FIXME: Remove respondsToCallback from CheckerContext;
115769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       IsPreVisit ? ProgramPoint::PreStmtKind :
117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ProgramPoint::PostStmtKind, 0, S);
118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkFn(S, C);
119769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
120769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
121769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
122769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting Stmts.
124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForStmt(bool isPreVisit,
125769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                        ExplodedNodeSet &Dst,
126cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                        const ExplodedNodeSet &Src,
127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                        const Stmt *S,
128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                        ExprEngine &Eng) {
129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckStmtContext C(isPreVisit, *getCachedStmtCheckersFor(S, isPreVisit),
130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                     S, Eng);
131c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
132769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
133769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace {
135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CheckObjCMessageContext {
136769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy;
137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const CheckersTy &Checkers;
139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const ObjCMessage &Msg;
140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExprEngine &Eng;
141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
142e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
143e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
144e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers,
146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            const ObjCMessage &msg, ExprEngine &eng)
147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       IsPreVisit ? ProgramPoint::PreStmtKind :
153769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ProgramPoint::PostStmtKind, 0,
154769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       Msg.getOriginExpr());
155769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkFn(Msg, C);
156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
157769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting obj-c messages.
161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForObjCMessage(bool isPreVisit,
162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                               ExplodedNodeSet &Dst,
163cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                               const ExplodedNodeSet &Src,
164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                               const ObjCMessage &msg,
165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                               ExprEngine &Eng) {
1663f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis  CheckObjCMessageContext C(isPreVisit,
1673f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis                            isPreVisit ? PreObjCMessageCheckers
1683f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis                                       : PostObjCMessageCheckers,
1693f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis                            msg, Eng);
170c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace {
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CheckLocationContext {
175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    typedef std::vector<CheckerManager::CheckLocationFunc> CheckersTy;
176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const CheckersTy &Checkers;
177769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    SVal Loc;
178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsLoad;
179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const Stmt *S;
180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const GRState *State;
181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExprEngine &Eng;
182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
183e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
184e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
185e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckLocationContext(const CheckersTy &checkers,
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                         SVal loc, bool isLoad, const Stmt *s,
188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                         const GRState *state, ExprEngine &eng)
189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : Checkers(checkers), Loc(loc), IsLoad(isLoad), S(s),
190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        State(state), Eng(eng) { }
191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckLocationFunc checkFn,
193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       IsLoad ? ProgramPoint::PreLoadKind :
196769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       ProgramPoint::PreStoreKind, 0, S, State);
197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkFn(Loc, IsLoad, C);
198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
2009fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
2019fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for load/store of a location.
203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst,
204cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                            const ExplodedNodeSet &Src,
205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                            SVal location, bool isLoad,
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                            const Stmt *S,
207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                            const GRState *state,
208769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                            ExprEngine &Eng) {
209769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckLocationContext C(LocationCheckers, location, isLoad, S, state, Eng);
210c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
2119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
2129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
21330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G,
21430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                               BugReporter &BR,
21530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                               ExprEngine &Eng) {
21630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  for (unsigned i = 0, e = EndAnalysisCheckers.size(); i != e; ++i)
21730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    EndAnalysisCheckers[i](G, BR, Eng);
21830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis}
21930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
220e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// \brief Run checkers for evaluating a call.
221e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// Only one checker will evaluate the call.
222e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
223e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            const ExplodedNodeSet &Src,
224e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            const CallExpr *CE,
225e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            ExprEngine &Eng,
226e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            GraphExpander *defaultEval) {
227e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  if (EvalCallCheckers.empty() && defaultEval == 0) {
228e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    Dst.insert(Src);
229e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    return;
230e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
231e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
232e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  for (ExplodedNodeSet::iterator
233e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis         NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) {
234e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
235e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    ExplodedNode *Pred = *NI;
236e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    bool anyEvaluated = false;
237e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    for (std::vector<EvalCallFunc>::iterator
238e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis           EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end();
239e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis         EI != EE; ++EI) {
240e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      ExplodedNodeSet checkDst;
241e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      CheckerContext C(checkDst, Eng.getBuilder(), Eng, Pred, EI->Checker,
242e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                       ProgramPoint::PostStmtKind, 0, CE);
243e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      bool evaluated = (*EI)(CE, C);
244e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      assert(!(evaluated && anyEvaluated)
245e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis             && "There are more than one checkers evaluating the call");
246e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      if (evaluated) {
247e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        anyEvaluated = true;
248e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        Dst.insert(checkDst);
249e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#ifdef NDEBUG
250e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        break; // on release don't check that no other checker also evals.
251e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#endif
252e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      }
253e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    }
254e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
255e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    if (!anyEvaluated) {
256e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      if (defaultEval)
257e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        defaultEval->expandGraph(Dst, Pred);
258e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      else
259e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        Dst.insert(Pred);
260e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    }
261e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
262e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}
263e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
26443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisvoid CheckerManager::registerCheckersToEngine(ExprEngine &eng) {
26543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
26643dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis    Funcs[i](eng);
26743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}
26843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
269769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
270769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
271769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
272769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
273769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForDecl(CheckDeclFunc checkfn,
274769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                      HandlesDeclFunc isForDeclFn) {
275769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  DeclCheckerInfo info = { checkfn, isForDeclFn };
276769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  DeclCheckers.push_back(info);
277769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
278769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
279769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForBody(CheckDeclFunc checkfn) {
280769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  BodyCheckers.push_back(checkfn);
281769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
282769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
283769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
284769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
285769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
286769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
287769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreStmt(CheckStmtFunc checkfn,
288769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                         HandlesStmtFunc isForStmtFn) {
289769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/true };
290769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckers.push_back(info);
291769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
292769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostStmt(CheckStmtFunc checkfn,
293769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                          HandlesStmtFunc isForStmtFn) {
294769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/false };
295769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckers.push_back(info);
296769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
297769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
298769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreObjCMessage(CheckObjCMessageFunc checkfn) {
299769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  PreObjCMessageCheckers.push_back(checkfn);
300769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
301769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostObjCMessage(CheckObjCMessageFunc checkfn) {
302769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  PostObjCMessageCheckers.push_back(checkfn);
303769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
304769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
305769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForLocation(CheckLocationFunc checkfn) {
306769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  LocationCheckers.push_back(checkfn);
307769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
308769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
30930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) {
31030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  EndAnalysisCheckers.push_back(checkfn);
31130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis}
31230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
313e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) {
314e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  EvalCallCheckers.push_back(checkfn);
315e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}
316e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
317769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
318769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
319769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
320769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
321769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::CachedStmtCheckers *
322769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit) {
323769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  assert(S);
324769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
325769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersKey key(S->getStmtClass(), isPreVisit);
326769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckers *checkers = 0;
327769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy::iterator CCI = CachedStmtCheckersMap.find(key);
328769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (CCI != CachedStmtCheckersMap.end()) {
329769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    checkers = &(CCI->second);
330769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  } else {
331769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    // Find the checkers that should run for this Stmt and cache them.
332769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    checkers = &CachedStmtCheckersMap[key];
333769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    for (unsigned i = 0, e = StmtCheckers.size(); i != e; ++i) {
334769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      StmtCheckerInfo &info = StmtCheckers[i];
335769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      if (info.IsPreVisit == isPreVisit && info.IsForStmtFn(S))
336769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        checkers->push_back(info.CheckFn);
337769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
3389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
339769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
340769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  assert(checkers);
341769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return checkers;
342769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
343769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
344769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::~CheckerManager() {
345769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  for (unsigned i = 0, e = CheckerDtors.size(); i != e; ++i)
346769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors[i]();
3479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
3489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
34943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Anchor for the vtable.
35043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios KyrtzidisCheckerProvider::~CheckerProvider() { }
351e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
352e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis// Anchor for the vtable.
353e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisGraphExpander::~GraphExpander() { }
354