CheckerRegistration.cpp revision 6875325b6576ad6fa4fc457f251aaeccb8b3c724
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) (intptr_t) lib.getAddressOfSymbol( 60 "clang_registerCheckers"); 61 if (registerPluginCheckers) 62 registerPluginCheckers(*this); 63 } 64} 65 66bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) { 67 // If the version string is null, it's not an analyzer plugin. 68 if (versionString == 0) 69 return false; 70 71 // For now, none of the static analyzer API is considered stable. 72 // Versions must match exactly. 73 if (strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0) 74 return true; 75 76 // FIXME: Should we emit a diagnostic if the version doesn't match? 77 return false; 78} 79 80 81CheckerManager *ento::createCheckerManager(const AnalyzerOptions &opts, 82 const LangOptions &langOpts, 83 ArrayRef<std::string> plugins, 84 Diagnostic &diags) { 85 llvm::OwningPtr<CheckerManager> checkerMgr(new CheckerManager(langOpts)); 86 87 SmallVector<CheckerOptInfo, 8> checkerOpts; 88 for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) { 89 const std::pair<std::string, bool> &opt = opts.CheckersControlList[i]; 90 checkerOpts.push_back(CheckerOptInfo(opt.first.c_str(), opt.second)); 91 } 92 93 ClangCheckerRegistry(plugins).initializeManager(*checkerMgr, checkerOpts); 94 checkerMgr->finishedCheckerRegistration(); 95 96 for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) { 97 if (checkerOpts[i].isUnclaimed()) 98 diags.Report(diag::warn_unkwown_analyzer_checker) 99 << checkerOpts[i].getName(); 100 } 101 102 return checkerMgr.take(); 103} 104 105void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) { 106 out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; 107 out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n"; 108 109 ClangCheckerRegistry(plugins).printHelp(out); 110} 111