16
16
#include " ClangSACheckers.h"
17
17
#include " clang/StaticAnalyzer/Core/CheckerManager.h"
18
18
#include " clang/StaticAnalyzer/Core/CheckerProvider.h"
19
+ #include " llvm/Support/raw_ostream.h"
19
20
#include " llvm/ADT/DenseSet.h"
21
+ #include " map"
20
22
21
23
using namespace clang ;
22
24
using namespace ento ;
@@ -28,6 +30,7 @@ class ClangSACheckerProvider : public CheckerProvider {
28
30
public:
29
31
virtual void registerCheckers (CheckerManager &checkerMgr,
30
32
CheckerOptInfo *checkOpts, unsigned numCheckOpts);
33
+ virtual void printHelp (llvm::raw_ostream &OS);
31
34
};
32
35
33
36
}
@@ -41,6 +44,7 @@ namespace {
41
44
struct StaticCheckerInfoRec {
42
45
const char *FullName;
43
46
void (*RegFunc)(CheckerManager &mgr);
47
+ const char *HelpText;
44
48
bool Hidden;
45
49
};
46
50
@@ -49,13 +53,16 @@ struct StaticCheckerInfoRec {
49
53
static const StaticCheckerInfoRec StaticCheckerInfo[] = {
50
54
#define GET_CHECKERS
51
55
#define CHECKER (FULLNAME,CLASS,DESCFILE,HELPTEXT,HIDDEN ) \
52
- { FULLNAME, register ##CLASS, HIDDEN },
56
+ { FULLNAME, register ##CLASS, HELPTEXT, HIDDEN },
53
57
#include " Checkers.inc"
54
- { 0 , 0 , 0 }
58
+ { 0 , 0 , 0 , 0 }
55
59
#undef CHECKER
56
60
#undef GET_CHECKERS
57
61
};
58
62
63
+ static const unsigned NumCheckers = sizeof (StaticCheckerInfo)
64
+ / sizeof (StaticCheckerInfoRec) - 1 ;
65
+
59
66
namespace {
60
67
61
68
struct CheckNameOption {
@@ -136,3 +143,41 @@ void ClangSACheckerProvider::registerCheckers(CheckerManager &checkerMgr,
136
143
(*I)->RegFunc (checkerMgr);
137
144
}
138
145
}
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
+ }
0 commit comments