CheckerManager.cpp revision 9fb9474c5b267400d4abfbff63c8b39f378235d4
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"
169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "clang/AST/DeclBase.h"
1743dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
1843dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace clang;
1943dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisusing namespace ento;
2043dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr,
229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                          BugReporter &BR) {
239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(D);
249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  unsigned DeclKind = D->getKind();
269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckers *checkers = 0;
279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind);
289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  if (CCI != CachedDeclCheckersMap.end()) {
299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    checkers = &(CCI->second);
309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  } else {
319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    // Find the checkers that should run for this Decl and cache them.
329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    checkers = &CachedDeclCheckersMap[DeclKind];
339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    for (unsigned i = 0, e = DeclCheckers.size(); i != e; ++i) {
349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      DeclCheckerInfo &info = DeclCheckers[i];
359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis      if (info.IsForDeclFn(D))
369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis        checkers->push_back(std::make_pair(info.Checker, info.CheckFn));
379fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    }
389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(checkers);
419fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  for (CachedDeclCheckers::iterator
429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis         I = checkers->begin(), E = checkers->end(); I != E; ++I) {
439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckerRef checker = I->first;
449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc fn = I->second;
459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    fn(checker, D, mgr, BR);
469fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
479fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
489fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr,
509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                          BugReporter &BR) {
519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  assert(D && D->hasBody());
529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  for (unsigned i = 0, e = BodyCheckers.size(); i != e; ++i) {
549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckerRef checker = BodyCheckers[i].first;
559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckDeclFunc fn = BodyCheckers[i].second;
569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    fn(checker, D, mgr, BR);
579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::_registerForDecl(CheckerRef checker, CheckDeclFunc checkfn,
619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                      HandlesDeclFunc isForDeclFn) {
629fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  DeclCheckerInfo info = { checker, checkfn, isForDeclFn };
639fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  DeclCheckers.push_back(info);
649fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
659fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
669fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisvoid CheckerManager::_registerForBody(CheckerRef checker,
679fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis                                      CheckDeclFunc checkfn) {
689fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  BodyCheckers.push_back(std::make_pair(checker, checkfn));
699fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
709fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
7143dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidisvoid CheckerManager::registerCheckersToEngine(ExprEngine &eng) {
7243dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  for (unsigned i = 0, e = Funcs.size(); i != e; ++i)
7343dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis    Funcs[i](eng);
7443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis}
7543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis
769fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios KyrtzidisCheckerManager::~CheckerManager() {
779fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  for (unsigned i = 0, e = Checkers.size(); i != e; ++i) {
789fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    CheckerRef checker = Checkers[i].first;
799fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    Dtor dtor = Checkers[i].second;
809fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis    dtor(checker);
819fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis  }
829fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis}
839fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis
8443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis// Anchor for the vtable.
8543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios KyrtzidisCheckerProvider::~CheckerProvider() { }
86