forked from OSchip/llvm-project
Intoduce '-analyzer-checker-help' flag which outputs a list of all available static analyzer checkers.
This is pretty basic for now, eventually checkers should be grouped according to package, hidden checkers should be indicated etc. llvm-svn: 126454
This commit is contained in:
parent
4322a2864e
commit
17bee3e70a
|
@ -105,6 +105,9 @@ def analyzer_disable_checker : Separate<"-analyzer-disable-checker">,
|
|||
def analyzer_disable_checker_EQ : Joined<"-analyzer-disable-checker=">,
|
||||
Alias<analyzer_disable_checker>;
|
||||
|
||||
def analyzer_checker_help : Flag<"-analyzer-checker-help">,
|
||||
HelpText<"Display the list of analyzer checkers that are available">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CodeGen Options
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
std::string AnalyzeSpecificFunction;
|
||||
unsigned MaxNodes;
|
||||
unsigned MaxLoop;
|
||||
unsigned ShowCheckerHelp : 1;
|
||||
unsigned AnalyzeAll : 1;
|
||||
unsigned AnalyzerDisplayProgress : 1;
|
||||
unsigned AnalyzeNestedBlocks : 1;
|
||||
|
@ -86,6 +87,7 @@ public:
|
|||
AnalysisStoreOpt = BasicStoreModel;
|
||||
AnalysisConstraintsOpt = RangeConstraintsModel;
|
||||
AnalysisDiagOpt = PD_HTML;
|
||||
ShowCheckerHelp = 0;
|
||||
AnalyzeAll = 0;
|
||||
AnalyzerDisplayProgress = 0;
|
||||
AnalyzeNestedBlocks = 0;
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
|
||||
namespace ento {
|
||||
|
@ -45,6 +49,7 @@ public:
|
|||
virtual ~CheckerProvider();
|
||||
virtual void registerCheckers(CheckerManager &checkerMgr,
|
||||
CheckerOptInfo *checkOpts, unsigned numCheckOpts) = 0;
|
||||
virtual void printHelp(llvm::raw_ostream &OS) = 0;
|
||||
};
|
||||
|
||||
} // end ento namespace
|
||||
|
|
|
@ -26,6 +26,8 @@ protected:
|
|||
llvm::StringRef InFile);
|
||||
};
|
||||
|
||||
void printCheckerHelp(llvm::raw_ostream &OS);
|
||||
|
||||
} // end GR namespace
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -78,6 +78,8 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
|
|||
std::vector<std::string> &Res) {
|
||||
for (unsigned i = 0, e = Opts.AnalysisList.size(); i != e; ++i)
|
||||
Res.push_back(getAnalysisName(Opts.AnalysisList[i]));
|
||||
if (Opts.ShowCheckerHelp)
|
||||
Res.push_back("-analyzer-checker-help");
|
||||
if (Opts.AnalysisStoreOpt != BasicStoreModel) {
|
||||
Res.push_back("-analyzer-store");
|
||||
Res.push_back(getAnalysisStoreName(Opts.AnalysisStoreOpt));
|
||||
|
@ -859,6 +861,7 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
|
|||
Opts.AnalysisDiagOpt = Value;
|
||||
}
|
||||
|
||||
Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
|
||||
Opts.VisualizeEGDot = Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
|
||||
Opts.VisualizeEGUbi = Args.hasArg(OPT_analyzer_viz_egraph_ubigraph);
|
||||
Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
|
||||
|
|
|
@ -108,6 +108,12 @@ bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Honor -analyzer-checker-help.
|
||||
if (Clang->getAnalyzerOpts().ShowCheckerHelp) {
|
||||
ento::printCheckerHelp(llvm::outs());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Honor -version.
|
||||
//
|
||||
// FIXME: Use a better -version message?
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
#include "ClangSACheckers.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "map"
|
||||
|
||||
using namespace clang;
|
||||
using namespace ento;
|
||||
|
@ -28,6 +30,7 @@ class ClangSACheckerProvider : public CheckerProvider {
|
|||
public:
|
||||
virtual void registerCheckers(CheckerManager &checkerMgr,
|
||||
CheckerOptInfo *checkOpts, unsigned numCheckOpts);
|
||||
virtual void printHelp(llvm::raw_ostream &OS);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -41,6 +44,7 @@ namespace {
|
|||
struct StaticCheckerInfoRec {
|
||||
const char *FullName;
|
||||
void (*RegFunc)(CheckerManager &mgr);
|
||||
const char *HelpText;
|
||||
bool Hidden;
|
||||
};
|
||||
|
||||
|
@ -49,13 +53,16 @@ struct StaticCheckerInfoRec {
|
|||
static const StaticCheckerInfoRec StaticCheckerInfo[] = {
|
||||
#define GET_CHECKERS
|
||||
#define CHECKER(FULLNAME,CLASS,DESCFILE,HELPTEXT,HIDDEN) \
|
||||
{ FULLNAME, register##CLASS, HIDDEN },
|
||||
{ FULLNAME, register##CLASS, HELPTEXT, HIDDEN },
|
||||
#include "Checkers.inc"
|
||||
{ 0, 0, 0}
|
||||
{ 0, 0, 0, 0}
|
||||
#undef CHECKER
|
||||
#undef GET_CHECKERS
|
||||
};
|
||||
|
||||
static const unsigned NumCheckers = sizeof(StaticCheckerInfo)
|
||||
/ sizeof(StaticCheckerInfoRec) - 1;
|
||||
|
||||
namespace {
|
||||
|
||||
struct CheckNameOption {
|
||||
|
@ -136,3 +143,41 @@ void ClangSACheckerProvider::registerCheckers(CheckerManager &checkerMgr,
|
|||
(*I)->RegFunc(checkerMgr);
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map<std::string, const StaticCheckerInfoRec *> SortedCheckers;
|
||||
|
||||
static void printCheckerOption(llvm::raw_ostream &OS,SortedCheckers &checkers) {
|
||||
// Find the maximum option length.
|
||||
unsigned OptionFieldWidth = 0;
|
||||
for (SortedCheckers::iterator
|
||||
I = checkers.begin(), E = checkers.end(); I != E; ++I) {
|
||||
// Limit the amount of padding we are willing to give up for alignment.
|
||||
unsigned Length = strlen(I->second->FullName);
|
||||
if (Length <= 30)
|
||||
OptionFieldWidth = std::max(OptionFieldWidth, Length);
|
||||
}
|
||||
|
||||
const unsigned InitialPad = 2;
|
||||
for (SortedCheckers::iterator
|
||||
I = checkers.begin(), E = checkers.end(); I != E; ++I) {
|
||||
const std::string &Option = I->first;
|
||||
int Pad = OptionFieldWidth - int(Option.size());
|
||||
OS.indent(InitialPad) << Option;
|
||||
|
||||
// Break on long option names.
|
||||
if (Pad < 0) {
|
||||
OS << "\n";
|
||||
Pad = OptionFieldWidth + InitialPad;
|
||||
}
|
||||
OS.indent(Pad + 1) << I->second->HelpText << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void ClangSACheckerProvider::printHelp(llvm::raw_ostream &OS) {
|
||||
// Sort checkers according to their full name.
|
||||
SortedCheckers checkers;
|
||||
for (unsigned i = 0; i != NumCheckers; ++i)
|
||||
checkers[StaticCheckerInfo[i].FullName] = &StaticCheckerInfo[i];
|
||||
|
||||
printCheckerOption(OS, checkers);
|
||||
}
|
||||
|
|
|
@ -12,12 +12,14 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
|
||||
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
|
||||
#include "../Checkers/ClangSACheckerProvider.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
|
||||
#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
|
||||
#include "clang/Frontend/AnalyzerOptions.h"
|
||||
#include "clang/Frontend/FrontendDiagnostic.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
|
@ -49,3 +51,16 @@ CheckerManager *ento::registerCheckers(const AnalyzerOptions &opts,
|
|||
|
||||
return checkerMgr.take();
|
||||
}
|
||||
|
||||
void ento::printCheckerHelp(llvm::raw_ostream &OS) {
|
||||
OS << "OVERVIEW: Clang Static Analyzer Checkers List\n";
|
||||
OS << '\n';
|
||||
OS << "USAGE: -analyzer-checker <check1,check2,...>\n";
|
||||
OS << '\n';
|
||||
OS << "CHECKERS:\n";
|
||||
|
||||
llvm::OwningPtr<CheckerProvider> provider(createClangSACheckerProvider());
|
||||
provider->printHelp(OS);
|
||||
|
||||
// FIXME: Load CheckerProviders from plugins.
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue