diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-02-17 21:39:24 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-02-17 21:39:24 +0000 |
commit | 9fb9474c5b267400d4abfbff63c8b39f378235d4 (patch) | |
tree | aedb0a92a4d8d3410af2d57ab21ba224d807f102 /lib/StaticAnalyzer/Core/CheckerManager.cpp | |
parent | 695fb502825a53ccd178ec1c85c77929d88acb71 (diff) |
[analyzer]
-Introduce CheckerV2, a set of templates for convenient declaration & registration of checkers.
Currently useful just for checkers working on the AST not the path-sensitive ones.
-Enhance CheckerManager to actually collect the checkers and turn it into the entry point for
running the checkers.
-Use the new mechanism for the LLVMConventionsChecker.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125778 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/CheckerManager.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/CheckerManager.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp index 0dd56e6c19..1989b822ae 100644 --- a/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -13,14 +13,73 @@ #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/CheckerProvider.h" +#include "clang/AST/DeclBase.h" using namespace clang; using namespace ento; +void CheckerManager::runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, + BugReporter &BR) { + assert(D); + + unsigned DeclKind = D->getKind(); + CachedDeclCheckers *checkers = 0; + CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind); + if (CCI != CachedDeclCheckersMap.end()) { + checkers = &(CCI->second); + } else { + // Find the checkers that should run for this Decl and cache them. + checkers = &CachedDeclCheckersMap[DeclKind]; + for (unsigned i = 0, e = DeclCheckers.size(); i != e; ++i) { + DeclCheckerInfo &info = DeclCheckers[i]; + if (info.IsForDeclFn(D)) + checkers->push_back(std::make_pair(info.Checker, info.CheckFn)); + } + } + + assert(checkers); + for (CachedDeclCheckers::iterator + I = checkers->begin(), E = checkers->end(); I != E; ++I) { + CheckerRef checker = I->first; + CheckDeclFunc fn = I->second; + fn(checker, D, mgr, BR); + } +} + +void CheckerManager::runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, + BugReporter &BR) { + assert(D && D->hasBody()); + + for (unsigned i = 0, e = BodyCheckers.size(); i != e; ++i) { + CheckerRef checker = BodyCheckers[i].first; + CheckDeclFunc fn = BodyCheckers[i].second; + fn(checker, D, mgr, BR); + } +} + +void CheckerManager::_registerForDecl(CheckerRef checker, CheckDeclFunc checkfn, + HandlesDeclFunc isForDeclFn) { + DeclCheckerInfo info = { checker, checkfn, isForDeclFn }; + DeclCheckers.push_back(info); +} + +void CheckerManager::_registerForBody(CheckerRef checker, + CheckDeclFunc checkfn) { + BodyCheckers.push_back(std::make_pair(checker, checkfn)); +} + void CheckerManager::registerCheckersToEngine(ExprEngine &eng) { for (unsigned i = 0, e = Funcs.size(); i != e; ++i) Funcs[i](eng); } +CheckerManager::~CheckerManager() { + for (unsigned i = 0, e = Checkers.size(); i != e; ++i) { + CheckerRef checker = Checkers[i].first; + Dtor dtor = Checkers[i].second; + dtor(checker); + } +} + // Anchor for the vtable. CheckerProvider::~CheckerProvider() { } |