CheckerManager.cpp revision dbd658e139b3e0bf084f75feaea8d844af9e319f
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"
15ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "clang/StaticAnalyzer/Core/Checker.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
23d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidisbool CheckerManager::hasPathSensitiveCheckers() const {
24d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis  return !StmtCheckers.empty()              ||
25d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !PreObjCMessageCheckers.empty()    ||
26d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !PostObjCMessageCheckers.empty()   ||
27d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !LocationCheckers.empty()          ||
28d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !BindCheckers.empty()              ||
29d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !EndAnalysisCheckers.empty()       ||
30d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !EndPathCheckers.empty()           ||
31d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !BranchConditionCheckers.empty()   ||
32d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !LiveSymbolsCheckers.empty()       ||
33d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !DeadSymbolsCheckers.empty()       ||
34d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !RegionChangesCheckers.empty()     ||
35d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !EvalAssumeCheckers.empty()        ||
36d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis         !EvalCallCheckers.empty();
37d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis}
38d655ab28fdf7c940d3f79f8f287954d7f76e0977Argyrios Kyrtzidis
39deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisvoid CheckerManager::finishedCheckerRegistration() {
40deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis#ifndef NDEBUG
41deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  // Make sure that for every event that has listeners, there is at least
42deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  // one dispatcher registered for it.
43deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis  for (llvm::DenseMap<EventTag, EventInfo>::iterator
44deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis         I = Events.begin(), E = Events.end(); I != E; ++I)
45deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis    assert(I->second.HasDispatcher && "No dispatcher registered for an event");
46deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis#endif
47deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis}
48deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis
49769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
50769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for AST traversing..
51769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
52769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                          BugReporter &BR) {
559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(D);
569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  unsigned DeclKind = D->getKind();
589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckers *checkers = 0;
599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind);
609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  if (CCI != CachedDeclCheckersMap.end()) {
619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    checkers = &(CCI->second);
629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  } else {
639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    // Find the checkers that should run for this Decl and cache them.
649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    checkers = &CachedDeclCheckersMap[DeclKind];
659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    for (unsigned i = 0, e = DeclCheckers.size(); i != e; ++i) {
669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      DeclCheckerInfo &info = DeclCheckers[i];
679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      if (info.IsForDeclFn(D))
68769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        checkers->push_back(info.CheckFn);
699fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    }
709fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
719fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
729fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(checkers);
739fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  for (CachedDeclCheckers::iterator
74769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis         I = checkers->begin(), E = checkers->end(); I != E; ++I)
75769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    (*I)(D, mgr, BR);
769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                          BugReporter &BR) {
809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(D && D->hasBody());
819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
82769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  for (unsigned i = 0, e = BodyCheckers.size(); i != e; ++i)
83769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    BodyCheckers[i](D, mgr, BR);
84769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Functions for running checkers for path-sensitive checking.
88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
89769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidistemplate <typename CHECK_CTX>
91c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidisstatic void expandGraphWithCheckers(CHECK_CTX checkCtx,
92c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis                                    ExplodedNodeSet &Dst,
93cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                    const ExplodedNodeSet &Src) {
94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
95e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  typename CHECK_CTX::CheckersTy::const_iterator
96e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      I = checkCtx.checkers_begin(), E = checkCtx.checkers_end();
97e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  if (I == E) {
98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    Dst.insert(Src);
99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    return;
100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  }
101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
102cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis  ExplodedNodeSet Tmp1, Tmp2;
103cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis  const ExplodedNodeSet *PrevSet = &Src;
104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
105e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  for (; I != E; ++I) {
106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExplodedNodeSet *CurrSet = 0;
107769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    if (I+1 == E)
108769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CurrSet = &Dst;
109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    else {
110cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis      CurrSet = (PrevSet == &Tmp1) ? &Tmp2 : &Tmp1;
111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CurrSet->clear();
112769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
115769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis         NI != NE; ++NI)
116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkCtx.runChecker(*I, *CurrSet, *NI);
117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    // Update which NodeSet is the current one.
119769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    PrevSet = CurrSet;
1209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
1219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
1229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace {
124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CheckStmtContext {
1255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    typedef SmallVectorImpl<CheckerManager::CheckStmtFunc> CheckersTy;
126769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const CheckersTy &Checkers;
128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const Stmt *S;
129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExprEngine &Eng;
130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
131e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
132e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
133e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckStmtContext(bool isPreVisit, const CheckersTy &checkers,
135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                     const Stmt *s, ExprEngine &eng)
136769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng) { }
137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckStmtFunc checkFn,
139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
140769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      // FIXME: Remove respondsToCallback from CheckerContext;
141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       IsPreVisit ? ProgramPoint::PreStmtKind :
143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ProgramPoint::PostStmtKind, 0, S);
144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkFn(S, C);
145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting Stmts.
150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForStmt(bool isPreVisit,
151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                        ExplodedNodeSet &Dst,
152cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                        const ExplodedNodeSet &Src,
153769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                        const Stmt *S,
154769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                        ExprEngine &Eng) {
155769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CheckStmtContext C(isPreVisit, *getCachedStmtCheckersFor(S, isPreVisit),
156769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                     S, Eng);
157c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
158769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
159769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
160769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace {
161769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CheckObjCMessageContext {
162769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy;
163769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsPreVisit;
164769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const CheckersTy &Checkers;
165769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const ObjCMessage &Msg;
166769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExprEngine &Eng;
167769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
168e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
169e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
170e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
171769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers,
172769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                            const ObjCMessage &msg, ExprEngine &eng)
173769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      : IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
174769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
175769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
176769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
177769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
178769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       IsPreVisit ? ProgramPoint::PreStmtKind :
179769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                    ProgramPoint::PostStmtKind, 0,
180769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       Msg.getOriginExpr());
181769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkFn(Msg, C);
182769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
185769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
186769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for visiting obj-c messages.
187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForObjCMessage(bool isPreVisit,
188769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                               ExplodedNodeSet &Dst,
189cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                               const ExplodedNodeSet &Src,
190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                               const ObjCMessage &msg,
191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                               ExprEngine &Eng) {
1923f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis  CheckObjCMessageContext C(isPreVisit,
1933f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis                            isPreVisit ? PreObjCMessageCheckers
1943f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis                                       : PostObjCMessageCheckers,
1953f8212787d9bd620930817177fbba5f32659377fArgyrios Kyrtzidis                            msg, Eng);
196c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
197769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
198769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
199769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisnamespace {
200769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  struct CheckLocationContext {
201769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    typedef std::vector<CheckerManager::CheckLocationFunc> CheckersTy;
202769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const CheckersTy &Checkers;
203769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    SVal Loc;
204769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    bool IsLoad;
205769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    const Stmt *S;
206769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    ExprEngine &Eng;
207769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
208e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
209e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
210e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
211769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckLocationContext(const CheckersTy &checkers,
2129c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis                         SVal loc, bool isLoad, const Stmt *s, ExprEngine &eng)
2139c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis      : Checkers(checkers), Loc(loc), IsLoad(isLoad), S(s), Eng(eng) { }
214769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
215769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckLocationFunc checkFn,
216769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
217769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
218769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                       IsLoad ? ProgramPoint::PreLoadKind :
2199c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis                       ProgramPoint::PreStoreKind, 0, S);
220769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      checkFn(Loc, IsLoad, C);
221769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
222769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  };
2239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
2249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
225769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis/// \brief Run checkers for load/store of a location.
226769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst,
227cd50e136ad7dc721822f5e6350769a37c216612dArgyrios Kyrtzidis                                            const ExplodedNodeSet &Src,
228769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                            SVal location, bool isLoad,
2299c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis                                            const Stmt *S, ExprEngine &Eng) {
2309c0d6891b3ec4b0d20b8a295946c0dc5426d147cArgyrios Kyrtzidis  CheckLocationContext C(LocationCheckers, location, isLoad, S, Eng);
231c2e0db82139c70c0eac9d5c165b6bf3250af5bedArgyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
2329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
2339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
234312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisnamespace {
235312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  struct CheckBindContext {
236312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    typedef std::vector<CheckerManager::CheckBindFunc> CheckersTy;
237312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    const CheckersTy &Checkers;
238312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    SVal Loc;
239312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    SVal Val;
240312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    const Stmt *S;
241312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    ExprEngine &Eng;
242312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
243312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
244312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
245312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
246312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    CheckBindContext(const CheckersTy &checkers,
247312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                     SVal loc, SVal val, const Stmt *s, ExprEngine &eng)
248312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis      : Checkers(checkers), Loc(loc), Val(val), S(s), Eng(eng) { }
249312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
250312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckBindFunc checkFn,
251312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
252312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
253312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                       ProgramPoint::PreStmtKind, 0, S);
254312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis      checkFn(Loc, Val, C);
255312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    }
256312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  };
257312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}
258312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
259312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis/// \brief Run checkers for binding of a value to a location.
260312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst,
261312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                                        const ExplodedNodeSet &Src,
262312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                                        SVal location, SVal val,
263312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                                        const Stmt *S, ExprEngine &Eng) {
264312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  CheckBindContext C(BindCheckers, location, val, S, Eng);
265312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
266312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}
267312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
26830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::runCheckersForEndAnalysis(ExplodedGraph &G,
26930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                               BugReporter &BR,
27030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis                                               ExprEngine &Eng) {
27130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  for (unsigned i = 0, e = EndAnalysisCheckers.size(); i != e; ++i)
27230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis    EndAnalysisCheckers[i](G, BR, Eng);
27330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis}
27430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
275af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis/// \brief Run checkers for end of path.
276af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidisvoid CheckerManager::runCheckersForEndPath(EndOfFunctionNodeBuilder &B,
277af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis                                           ExprEngine &Eng) {
278af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  for (unsigned i = 0, e = EndPathCheckers.size(); i != e; ++i) {
279af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis    CheckEndPathFunc fn = EndPathCheckers[i];
280af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis    EndOfFunctionNodeBuilder specialB = B.withCheckerTag(fn.Checker);
281af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis    fn(specialB, Eng);
282af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  }
283af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis}
284af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
285cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis/// \brief Run checkers for branch condition.
286cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisvoid CheckerManager::runCheckersForBranchCondition(const Stmt *condition,
287cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                                   BranchNodeBuilder &B,
288cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                                   ExprEngine &Eng) {
289cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  for (unsigned i = 0, e = BranchConditionCheckers.size(); i != e; ++i) {
290cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis    CheckBranchConditionFunc fn = BranchConditionCheckers[i];
291cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis    fn(condition, B, Eng);
292cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  }
293cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis}
294cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
295183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for live symbols.
29618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekvoid CheckerManager::runCheckersForLiveSymbols(const ProgramState *state,
297183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                               SymbolReaper &SymReaper) {
298183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  for (unsigned i = 0, e = LiveSymbolsCheckers.size(); i != e; ++i)
299183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    LiveSymbolsCheckers[i](state, SymReaper);
300183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
301183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
302183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisnamespace {
303183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  struct CheckDeadSymbolsContext {
304183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    typedef std::vector<CheckerManager::CheckDeadSymbolsFunc> CheckersTy;
305183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    const CheckersTy &Checkers;
306183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    SymbolReaper &SR;
307183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    const Stmt *S;
308183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    ExprEngine &Eng;
309183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
310183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
311183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
312183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
313183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    CheckDeadSymbolsContext(const CheckersTy &checkers, SymbolReaper &sr,
314183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                            const Stmt *s, ExprEngine &eng)
315183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis      : Checkers(checkers), SR(sr), S(s), Eng(eng) { }
316183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
317183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn,
318183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                    ExplodedNodeSet &Dst, ExplodedNode *Pred) {
319183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis      CheckerContext C(Dst, Eng.getBuilder(), Eng, Pred, checkFn.Checker,
320183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                       ProgramPoint::PostPurgeDeadSymbolsKind, 0, S);
321183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis      checkFn(SR, C);
322183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    }
323183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  };
324183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
325183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
326183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for dead symbols.
327183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst,
328183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                               const ExplodedNodeSet &Src,
329183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                               SymbolReaper &SymReaper,
330183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                               const Stmt *S,
331183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                               ExprEngine &Eng) {
332183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng);
333183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  expandGraphWithCheckers(C, Dst, Src);
334183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
335183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
336183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief True if at least one checker wants to check region changes.
33718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekbool CheckerManager::wantsRegionChangeUpdate(const ProgramState *state) {
338183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i)
339183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    if (RegionChangesCheckers[i].WantUpdateFn(state))
340183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis      return true;
341183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
342183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  return false;
343183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
344183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
345183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis/// \brief Run checkers for region changes.
34618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *
34718c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCheckerManager::runCheckersForRegionChanges(const ProgramState *state,
34835bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek                            const StoreManager::InvalidatedSymbols *invalidated,
349537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                    ArrayRef<const MemRegion *> ExplicitRegions,
350537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                          ArrayRef<const MemRegion *> Regions) {
351183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
352183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    // If any checker declares the state infeasible (or if it starts that way),
353183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    // bail out.
354183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis    if (!state)
355183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis      return NULL;
356537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose    state = RegionChangesCheckers[i].CheckFn(state, invalidated,
357537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose                                             ExplicitRegions, Regions);
358183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  }
359183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  return state;
360183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
361183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
362312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis/// \brief Run checkers for handling assumptions on symbolic values.
36318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekconst ProgramState *
36418c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekCheckerManager::runCheckersForEvalAssume(const ProgramState *state,
365312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis                                         SVal Cond, bool Assumption) {
366312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  for (unsigned i = 0, e = EvalAssumeCheckers.size(); i != e; ++i) {
367312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    // If any checker declares the state infeasible (or if it starts that way),
368312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    // bail out.
369312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    if (!state)
370312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis      return NULL;
371312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis    state = EvalAssumeCheckers[i](state, Cond, Assumption);
372312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  }
373312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  return state;
374312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}
375312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
376e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// \brief Run checkers for evaluating a call.
377e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis/// Only one checker will evaluate the call.
378e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
379e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            const ExplodedNodeSet &Src,
380e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            const CallExpr *CE,
381e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            ExprEngine &Eng,
382e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                                            GraphExpander *defaultEval) {
383e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  if (EvalCallCheckers.empty() && defaultEval == 0) {
384e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    Dst.insert(Src);
385e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    return;
386e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
387e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
388e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  for (ExplodedNodeSet::iterator
389e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis         NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) {
390e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
391e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    ExplodedNode *Pred = *NI;
392e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    bool anyEvaluated = false;
393e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    for (std::vector<EvalCallFunc>::iterator
394e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis           EI = EvalCallCheckers.begin(), EE = EvalCallCheckers.end();
395e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis         EI != EE; ++EI) {
396e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      ExplodedNodeSet checkDst;
397e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      CheckerContext C(checkDst, Eng.getBuilder(), Eng, Pred, EI->Checker,
398e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis                       ProgramPoint::PostStmtKind, 0, CE);
399e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      bool evaluated = (*EI)(CE, C);
400e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      assert(!(evaluated && anyEvaluated)
401e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis             && "There are more than one checkers evaluating the call");
402e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      if (evaluated) {
403e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        anyEvaluated = true;
404e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        Dst.insert(checkDst);
405e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#ifdef NDEBUG
406e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        break; // on release don't check that no other checker also evals.
407e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis#endif
408e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      }
409e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    }
410e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
411e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    if (!anyEvaluated) {
412e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      if (defaultEval)
413e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        defaultEval->expandGraph(Dst, Pred);
414e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis      else
415e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis        Dst.insert(Pred);
416e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis    }
417e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  }
418e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}
419e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
4209be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek/// \brief Run checkers for the entire Translation Unit.
4219be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid CheckerManager::runCheckersOnEndOfTranslationUnit(
4229be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                                  const TranslationUnitDecl *TU,
4239be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                                  AnalysisManager &mgr,
4249be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                                  BugReporter &BR) {
4259be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  for (unsigned i = 0, e = EndOfTranslationUnitCheckers.size(); i != e; ++i)
4269be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek    EndOfTranslationUnitCheckers[i](TU, mgr, BR);
4279be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek}
4289be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
429dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rosevoid CheckerManager::runCheckersForPrintState(raw_ostream &Out,
430dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                                              const ProgramState *State,
431dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose                                              const char *NL, const char *Sep) {
432dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose  for (llvm::DenseMap<CheckerTag, CheckerRef>::iterator
433dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose        I = CheckerTags.begin(), E = CheckerTags.end(); I != E; ++I)
434dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose    I->second->printState(Out, State, NL, Sep);
435dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose}
436dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose
437769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
438769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for AST traversing.
439769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
440769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
441769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForDecl(CheckDeclFunc checkfn,
442769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                      HandlesDeclFunc isForDeclFn) {
443769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  DeclCheckerInfo info = { checkfn, isForDeclFn };
444769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  DeclCheckers.push_back(info);
445769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
446769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
447769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForBody(CheckDeclFunc checkfn) {
448769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  BodyCheckers.push_back(checkfn);
449769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
450769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
451769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
452769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Internal registration functions for path-sensitive checking.
453769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
454769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
455769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreStmt(CheckStmtFunc checkfn,
456769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                         HandlesStmtFunc isForStmtFn) {
457769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/true };
458769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckers.push_back(info);
459769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
460769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostStmt(CheckStmtFunc checkfn,
461769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis                                          HandlesStmtFunc isForStmtFn) {
462769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckerInfo info = { checkfn, isForStmtFn, /*IsPreVisit*/false };
463769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  StmtCheckers.push_back(info);
464769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
465769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
466769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPreObjCMessage(CheckObjCMessageFunc checkfn) {
467769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  PreObjCMessageCheckers.push_back(checkfn);
468769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
469769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForPostObjCMessage(CheckObjCMessageFunc checkfn) {
470769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  PostObjCMessageCheckers.push_back(checkfn);
471769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
472769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
473769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid CheckerManager::_registerForLocation(CheckLocationFunc checkfn) {
474769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  LocationCheckers.push_back(checkfn);
475769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
476769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
477312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::_registerForBind(CheckBindFunc checkfn) {
478312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  BindCheckers.push_back(checkfn);
479312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}
480312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
48130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid CheckerManager::_registerForEndAnalysis(CheckEndAnalysisFunc checkfn) {
48230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis  EndAnalysisCheckers.push_back(checkfn);
48330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis}
48430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis
485af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidisvoid CheckerManager::_registerForEndPath(CheckEndPathFunc checkfn) {
486af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis  EndPathCheckers.push_back(checkfn);
487af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis}
488af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis
489cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisvoid CheckerManager::_registerForBranchCondition(
490cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis                                             CheckBranchConditionFunc checkfn) {
491cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis  BranchConditionCheckers.push_back(checkfn);
492cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis}
493cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis
494183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForLiveSymbols(CheckLiveSymbolsFunc checkfn) {
495183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  LiveSymbolsCheckers.push_back(checkfn);
496183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
497183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
498183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForDeadSymbols(CheckDeadSymbolsFunc checkfn) {
499183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  DeadSymbolsCheckers.push_back(checkfn);
500183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
501183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
502183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisvoid CheckerManager::_registerForRegionChanges(CheckRegionChangesFunc checkfn,
503183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis                                     WantsRegionChangeUpdateFunc wantUpdateFn) {
504183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  RegionChangesCheckerInfo info = {checkfn, wantUpdateFn};
505183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis  RegionChangesCheckers.push_back(info);
506183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis}
507183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis
508312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid CheckerManager::_registerForEvalAssume(EvalAssumeFunc checkfn) {
509312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis  EvalAssumeCheckers.push_back(checkfn);
510312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis}
511312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis
512e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid CheckerManager::_registerForEvalCall(EvalCallFunc checkfn) {
513e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis  EvalCallCheckers.push_back(checkfn);
514e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis}
515e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis
5169be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid CheckerManager::_registerForEndOfTranslationUnit(
5179be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek                                            CheckEndOfTranslationUnit checkfn) {
5189be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek  EndOfTranslationUnitCheckers.push_back(checkfn);
5199be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek}
5209be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek
521769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
522769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// Implementation details.
523769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
524769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
525769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::CachedStmtCheckers *
526769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit) {
527769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  assert(S);
528769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
529769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersKey key(S->getStmtClass(), isPreVisit);
530769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckers *checkers = 0;
531769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  CachedStmtCheckersMapTy::iterator CCI = CachedStmtCheckersMap.find(key);
532769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  if (CCI != CachedStmtCheckersMap.end()) {
533769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    checkers = &(CCI->second);
534769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  } else {
535769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    // Find the checkers that should run for this Stmt and cache them.
536769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    checkers = &CachedStmtCheckersMap[key];
537769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    for (unsigned i = 0, e = StmtCheckers.size(); i != e; ++i) {
538769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      StmtCheckerInfo &info = StmtCheckers[i];
539769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis      if (info.IsPreVisit == isPreVisit && info.IsForStmtFn(S))
540769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis        checkers->push_back(info.CheckFn);
541769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    }
5429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
543769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
544769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  assert(checkers);
545769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  return checkers;
546769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}
547769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis
548769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisCheckerManager::~CheckerManager() {
549769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis  for (unsigned i = 0, e = CheckerDtors.size(); i != e; ++i)
550769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis    CheckerDtors[i]();
5519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
5529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
55343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Anchor for the vtable.
554e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios KyrtzidisGraphExpander::~GraphExpander() { }
555