CheckerRegistration.cpp revision 77a33a71701b59affb5337d9e2b57d69bc095c7d
1//===--- CheckerRegistration.cpp - Registration for the Analyzer Checkers -===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Defines the registration function for the analyzer checkers. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h" 15#include "clang/StaticAnalyzer/Frontend/FrontendActions.h" 16#include "clang/StaticAnalyzer/Checkers/ClangCheckers.h" 17#include "clang/StaticAnalyzer/Core/CheckerManager.h" 18#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h" 19#include "clang/StaticAnalyzer/Core/CheckerRegistry.h" 20#include "clang/Frontend/AnalyzerOptions.h" 21#include "clang/Frontend/FrontendDiagnostic.h" 22#include "clang/Basic/Diagnostic.h" 23#include "llvm/Support/DynamicLibrary.h" 24#include "llvm/Support/raw_ostream.h" 25#include "llvm/ADT/OwningPtr.h" 26#include "llvm/ADT/SmallVector.h" 27 28using namespace clang; 29using namespace ento; 30using llvm::sys::DynamicLibrary; 31 32namespace { 33class ClangCheckerRegistry : public CheckerRegistry { 34 typedef void (*RegisterCheckersFn)(CheckerRegistry &); 35public: 36 ClangCheckerRegistry(ArrayRef<std::string> plugins); 37 38 static bool isCompatibleAPIVersion(const char *versionString); 39}; 40 41} // end anonymous namespace 42 43ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef<std::string> plugins) { 44 registerBuiltinCheckers(*this); 45 46 for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end(); 47 i != e; ++i) { 48 // Get access to the plugin. 49 DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str()); 50 51 // See if it's compatible with this build of clang. 52 const char *pluginAPIVersion = 53 (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString"); 54 if (!isCompatibleAPIVersion(pluginAPIVersion)) 55 continue; 56 57 // Register its checkers. 58 RegisterCheckersFn registerPluginCheckers = 59 (RegisterCheckersFn) lib.getAddressOfSymbol("clang_registerCheckers"); 60 if (registerPluginCheckers) 61 registerPluginCheckers(*this); 62 } 63} 64 65bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) { 66 // If the version string is null, it's not an analyzer plugin. 67 if (versionString == 0) 68 return false; 69 70 // For now, none of the static analyzer API is considered stable. 71 // Versions must match exactly. 72 if (strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0) 73 return true; 74 75 // FIXME: Should we emit a diagnostic if the version doesn't match? 76 return false; 77} 78 79 80CheckerManager *ento::createCheckerManager(const AnalyzerOptions &opts, 81 const LangOptions &langOpts, 82 ArrayRef<std::string> plugins, 83 Diagnostic &diags) { 84 llvm::OwningPtr<CheckerManager> checkerMgr(new CheckerManager(langOpts)); 85 86 SmallVector<CheckerOptInfo, 8> checkerOpts; 87 for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) { 88 const std::pair<std::string, bool> &opt = opts.CheckersControlList[i]; 89 checkerOpts.push_back(CheckerOptInfo(opt.first.c_str(), opt.second)); 90 } 91 92 ClangCheckerRegistry(plugins).initializeManager(*checkerMgr, checkerOpts); 93 checkerMgr->finishedCheckerRegistration(); 94 95 for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) { 96 if (checkerOpts[i].isUnclaimed()) 97 diags.Report(diag::warn_unkwown_analyzer_checker) 98 << checkerOpts[i].getName(); 99 } 100 101 return checkerMgr.take(); 102} 103 104void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) { 105 out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; 106 out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n"; 107 108 ClangCheckerRegistry(plugins).printHelp(out); 109} 110