Index: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h @@ -1,44 +0,0 @@ -//===--- CheckerOptInfo.h - Specifies which checkers to use -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H -#define LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H - -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/StringRef.h" - -namespace clang { -namespace ento { - -/// Represents a request to include or exclude a checker or package from a -/// specific analysis run. -/// -/// \sa CheckerRegistry::initializeManager -class CheckerOptInfo { - StringRef Name; - bool Enable; - bool Claimed; - -public: - CheckerOptInfo(StringRef name, bool enable) - : Name(name), Enable(enable), Claimed(false) { } - - StringRef getName() const { return Name; } - bool isEnabled() const { return Enable; } - bool isDisabled() const { return !isEnabled(); } - - bool isClaimed() const { return Claimed; } - bool isUnclaimed() const { return !isClaimed(); } - void claim() { Claimed = true; } -}; - -} // end namespace ento -} // end namespace clang - -#endif Index: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h @@ -73,8 +73,6 @@ namespace ento { -class CheckerOptInfo; - /// Manages a set of available checkers for running a static analysis. /// The checkers are organized into packages by full name, where including /// a package will recursively include all subpackages and checkers within it. @@ -123,8 +121,8 @@ /// all checkers specified by the given CheckerOptInfo list. The order of this /// list is significant; later options can be used to reverse earlier ones. /// This can be used to exclude certain checkers in an included package. - void initializeManager(CheckerManager &mgr, - SmallVectorImpl &opts) const; + void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const; /// Check if every option corresponds to a specific checker or package. void validateCheckerOptions(const AnalyzerOptions &opts, @@ -133,8 +131,7 @@ /// Prints the name and description of all checkers in this registry. /// This output is not intended to be machine-parseable. void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; - void printList(raw_ostream &out, - SmallVectorImpl &opts) const; + void printList(raw_ostream &out, const AnalyzerOptions &opts) const; private: mutable CheckerInfoList Checkers; Index: cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp @@ -12,7 +12,6 @@ #include "clang/Basic/LLVM.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" @@ -30,6 +29,41 @@ using CheckerInfoSet = llvm::SetVector; +namespace { +/// Represents a request to include or exclude a checker or package from a +/// specific analysis run. +/// +/// \sa CheckerRegistry::initializeManager +class CheckerOptInfo { + StringRef Name; + bool Enable; + bool Claimed; + +public: + CheckerOptInfo(StringRef name, bool enable) + : Name(name), Enable(enable), Claimed(false) { } + + StringRef getName() const { return Name; } + bool isEnabled() const { return Enable; } + bool isDisabled() const { return !isEnabled(); } + + bool isClaimed() const { return Claimed; } + bool isUnclaimed() const { return !isClaimed(); } + void claim() { Claimed = true; } +}; + +} // end of anonymous namespace + +static SmallVector +getCheckerOptList(const AnalyzerOptions &opts) { + SmallVector checkerOpts; + for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) { + const std::pair &opt = opts.CheckersControlList[i]; + checkerOpts.push_back(CheckerOptInfo(opt.first, opt.second)); + } + return checkerOpts; +} + static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a, const CheckerRegistry::CheckerInfo &b) { return a.FullName < b.FullName; @@ -52,6 +86,7 @@ return false; } +/// Collects the checkers for the supplied \p opt option into \p collected. static void collectCheckers(const CheckerRegistry::CheckerInfoList &checkers, const llvm::StringMap &packageSizes, CheckerOptInfo &opt, CheckerInfoSet &collected) { @@ -101,13 +136,15 @@ } void CheckerRegistry::initializeManager(CheckerManager &checkerMgr, - SmallVectorImpl &opts) const { + const AnalyzerOptions &Opts, + DiagnosticsEngine &diags) const { // Sort checkers for efficient collection. llvm::sort(Checkers, checkerNameLT); + llvm::SmallVector checkerOpts = getCheckerOptList(Opts); // Collect checkers enabled by the options. CheckerInfoSet enabledCheckers; - for (auto &i : opts) + for (auto &i : checkerOpts) collectCheckers(Checkers, Packages, i, enabledCheckers); // Initialize the CheckerManager with all enabled checkers. @@ -115,6 +152,15 @@ checkerMgr.setCurrentCheckName(CheckName(i->FullName)); i->Initialize(checkerMgr); } + + for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) { + if (checkerOpts[i].isUnclaimed()) { + diags.Report(diag::err_unknown_analyzer_checker) + << checkerOpts[i].getName(); + diags.Report(diag::note_suggest_disabling_all_checkers); + } + + } } void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts, @@ -176,13 +222,14 @@ } } -void CheckerRegistry::printList( - raw_ostream &out, SmallVectorImpl &opts) const { +void CheckerRegistry::printList(raw_ostream &out, + const AnalyzerOptions &opts) const { llvm::sort(Checkers, checkerNameLT); + llvm::SmallVector checkerOpts = getCheckerOptList(opts); // Collect checkers enabled by the options. CheckerInfoSet enabledCheckers; - for (auto &i : opts) + for (auto &i : checkerOpts) collectCheckers(Checkers, Packages, i, enabledCheckers); for (const auto *i : enabledCheckers) Index: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -17,7 +17,6 @@ #include "clang/StaticAnalyzer/Checkers/ClangCheckers.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h" #include "clang/StaticAnalyzer/Core/CheckerRegistry.h" #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" #include "llvm/ADT/SmallVector.h" @@ -102,16 +101,6 @@ << pluginAPIVersion; } -static SmallVector -getCheckerOptList(const AnalyzerOptions &opts) { - SmallVector checkerOpts; - for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) { - const std::pair &opt = opts.CheckersControlList[i]; - checkerOpts.push_back(CheckerOptInfo(opt.first, opt.second)); - } - return checkerOpts; -} - std::unique_ptr ento::createCheckerManager( ASTContext &context, AnalyzerOptions &opts, @@ -120,26 +109,15 @@ DiagnosticsEngine &diags) { auto checkerMgr = llvm::make_unique(context, opts); - SmallVector checkerOpts = getCheckerOptList(opts); - ClangCheckerRegistry allCheckers(plugins, &diags); for (const auto &Fn : checkerRegistrationFns) Fn(allCheckers); - allCheckers.initializeManager(*checkerMgr, checkerOpts); + allCheckers.initializeManager(*checkerMgr, opts, diags); allCheckers.validateCheckerOptions(opts, diags); checkerMgr->finishedCheckerRegistration(); - for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) { - if (checkerOpts[i].isUnclaimed()) { - diags.Report(diag::err_unknown_analyzer_checker) - << checkerOpts[i].getName(); - diags.Report(diag::note_suggest_disabling_all_checkers); - } - - } - return checkerMgr; } @@ -155,8 +133,7 @@ const AnalyzerOptions &opts) { out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; - SmallVector checkerOpts = getCheckerOptList(opts); - ClangCheckerRegistry(plugins).printList(out, checkerOpts); + ClangCheckerRegistry(plugins).printList(out, opts); } void ento::printAnalyzerConfigList(raw_ostream &out) {