Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 116f364

Browse files
committed
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126454 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 10aad44 commit 116f364

File tree

8 files changed

+83
-2
lines changed

8 files changed

+83
-2
lines changed

include/clang/Driver/CC1Options.td

+3
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ def analyzer_disable_checker : Separate<"-analyzer-disable-checker">,
105105
def analyzer_disable_checker_EQ : Joined<"-analyzer-disable-checker=">,
106106
Alias<analyzer_disable_checker>;
107107

108+
def analyzer_checker_help : Flag<"-analyzer-checker-help">,
109+
HelpText<"Display the list of analyzer checkers that are available">;
110+
108111
//===----------------------------------------------------------------------===//
109112
// CodeGen Options
110113
//===----------------------------------------------------------------------===//

include/clang/Frontend/AnalyzerOptions.h

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class AnalyzerOptions {
6464
std::string AnalyzeSpecificFunction;
6565
unsigned MaxNodes;
6666
unsigned MaxLoop;
67+
unsigned ShowCheckerHelp : 1;
6768
unsigned AnalyzeAll : 1;
6869
unsigned AnalyzerDisplayProgress : 1;
6970
unsigned AnalyzeNestedBlocks : 1;
@@ -86,6 +87,7 @@ class AnalyzerOptions {
8687
AnalysisStoreOpt = BasicStoreModel;
8788
AnalysisConstraintsOpt = RangeConstraintsModel;
8889
AnalysisDiagOpt = PD_HTML;
90+
ShowCheckerHelp = 0;
8991
AnalyzeAll = 0;
9092
AnalyzerDisplayProgress = 0;
9193
AnalyzeNestedBlocks = 0;

include/clang/StaticAnalyzer/Core/CheckerProvider.h

+5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include "llvm/ADT/StringRef.h"
1818
#include <vector>
1919

20+
namespace llvm {
21+
class raw_ostream;
22+
}
23+
2024
namespace clang {
2125

2226
namespace ento {
@@ -45,6 +49,7 @@ class CheckerProvider {
4549
virtual ~CheckerProvider();
4650
virtual void registerCheckers(CheckerManager &checkerMgr,
4751
CheckerOptInfo *checkOpts, unsigned numCheckOpts) = 0;
52+
virtual void printHelp(llvm::raw_ostream &OS) = 0;
4853
};
4954

5055
} // end ento namespace

include/clang/StaticAnalyzer/Frontend/FrontendActions.h

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class AnalysisAction : public ASTFrontendAction {
2626
llvm::StringRef InFile);
2727
};
2828

29+
void printCheckerHelp(llvm::raw_ostream &OS);
30+
2931
} // end GR namespace
3032

3133
} // end namespace clang

lib/Frontend/CompilerInvocation.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
7878
std::vector<std::string> &Res) {
7979
for (unsigned i = 0, e = Opts.AnalysisList.size(); i != e; ++i)
8080
Res.push_back(getAnalysisName(Opts.AnalysisList[i]));
81+
if (Opts.ShowCheckerHelp)
82+
Res.push_back("-analyzer-checker-help");
8183
if (Opts.AnalysisStoreOpt != BasicStoreModel) {
8284
Res.push_back("-analyzer-store");
8385
Res.push_back(getAnalysisStoreName(Opts.AnalysisStoreOpt));
@@ -859,6 +861,7 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
859861
Opts.AnalysisDiagOpt = Value;
860862
}
861863

864+
Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
862865
Opts.VisualizeEGDot = Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
863866
Opts.VisualizeEGUbi = Args.hasArg(OPT_analyzer_viz_egraph_ubigraph);
864867
Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);

lib/FrontendTool/ExecuteCompilerInvocation.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
108108
return 0;
109109
}
110110

111+
// Honor -analyzer-checker-help.
112+
if (Clang->getAnalyzerOpts().ShowCheckerHelp) {
113+
ento::printCheckerHelp(llvm::outs());
114+
return 0;
115+
}
116+
111117
// Honor -version.
112118
//
113119
// FIXME: Use a better -version message?

lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp

+47-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
#include "ClangSACheckers.h"
1717
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
1818
#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
19+
#include "llvm/Support/raw_ostream.h"
1920
#include "llvm/ADT/DenseSet.h"
21+
#include "map"
2022

2123
using namespace clang;
2224
using namespace ento;
@@ -28,6 +30,7 @@ class ClangSACheckerProvider : public CheckerProvider {
2830
public:
2931
virtual void registerCheckers(CheckerManager &checkerMgr,
3032
CheckerOptInfo *checkOpts, unsigned numCheckOpts);
33+
virtual void printHelp(llvm::raw_ostream &OS);
3134
};
3235

3336
}
@@ -41,6 +44,7 @@ namespace {
4144
struct StaticCheckerInfoRec {
4245
const char *FullName;
4346
void (*RegFunc)(CheckerManager &mgr);
47+
const char *HelpText;
4448
bool Hidden;
4549
};
4650

@@ -49,13 +53,16 @@ struct StaticCheckerInfoRec {
4953
static const StaticCheckerInfoRec StaticCheckerInfo[] = {
5054
#define GET_CHECKERS
5155
#define CHECKER(FULLNAME,CLASS,DESCFILE,HELPTEXT,HIDDEN) \
52-
{ FULLNAME, register##CLASS, HIDDEN },
56+
{ FULLNAME, register##CLASS, HELPTEXT, HIDDEN },
5357
#include "Checkers.inc"
54-
{ 0, 0, 0}
58+
{ 0, 0, 0, 0}
5559
#undef CHECKER
5660
#undef GET_CHECKERS
5761
};
5862

63+
static const unsigned NumCheckers = sizeof(StaticCheckerInfo)
64+
/ sizeof(StaticCheckerInfoRec) - 1;
65+
5966
namespace {
6067

6168
struct CheckNameOption {
@@ -136,3 +143,41 @@ void ClangSACheckerProvider::registerCheckers(CheckerManager &checkerMgr,
136143
(*I)->RegFunc(checkerMgr);
137144
}
138145
}
146+
147+
typedef std::map<std::string, const StaticCheckerInfoRec *> SortedCheckers;
148+
149+
static void printCheckerOption(llvm::raw_ostream &OS,SortedCheckers &checkers) {
150+
// Find the maximum option length.
151+
unsigned OptionFieldWidth = 0;
152+
for (SortedCheckers::iterator
153+
I = checkers.begin(), E = checkers.end(); I != E; ++I) {
154+
// Limit the amount of padding we are willing to give up for alignment.
155+
unsigned Length = strlen(I->second->FullName);
156+
if (Length <= 30)
157+
OptionFieldWidth = std::max(OptionFieldWidth, Length);
158+
}
159+
160+
const unsigned InitialPad = 2;
161+
for (SortedCheckers::iterator
162+
I = checkers.begin(), E = checkers.end(); I != E; ++I) {
163+
const std::string &Option = I->first;
164+
int Pad = OptionFieldWidth - int(Option.size());
165+
OS.indent(InitialPad) << Option;
166+
167+
// Break on long option names.
168+
if (Pad < 0) {
169+
OS << "\n";
170+
Pad = OptionFieldWidth + InitialPad;
171+
}
172+
OS.indent(Pad + 1) << I->second->HelpText << '\n';
173+
}
174+
}
175+
176+
void ClangSACheckerProvider::printHelp(llvm::raw_ostream &OS) {
177+
// Sort checkers according to their full name.
178+
SortedCheckers checkers;
179+
for (unsigned i = 0; i != NumCheckers; ++i)
180+
checkers[StaticCheckerInfo[i].FullName] = &StaticCheckerInfo[i];
181+
182+
printCheckerOption(OS, checkers);
183+
}

lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
15+
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
1516
#include "../Checkers/ClangSACheckerProvider.h"
1617
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
1718
#include "clang/StaticAnalyzer/Core/CheckerProvider.h"
1819
#include "clang/Frontend/AnalyzerOptions.h"
1920
#include "clang/Frontend/FrontendDiagnostic.h"
2021
#include "clang/Basic/Diagnostic.h"
22+
#include "llvm/Support/raw_ostream.h"
2123
#include "llvm/ADT/OwningPtr.h"
2224
#include "llvm/ADT/SmallVector.h"
2325

@@ -49,3 +51,16 @@ CheckerManager *ento::registerCheckers(const AnalyzerOptions &opts,
4951

5052
return checkerMgr.take();
5153
}
54+
55+
void ento::printCheckerHelp(llvm::raw_ostream &OS) {
56+
OS << "OVERVIEW: Clang Static Analyzer Checkers List\n";
57+
OS << '\n';
58+
OS << "USAGE: -analyzer-checker <check1,check2,...>\n";
59+
OS << '\n';
60+
OS << "CHECKERS:\n";
61+
62+
llvm::OwningPtr<CheckerProvider> provider(createClangSACheckerProvider());
63+
provider->printHelp(OS);
64+
65+
// FIXME: Load CheckerProviders from plugins.
66+
}

0 commit comments

Comments
 (0)