clang 20.0.0git
CheckerRegistryData.cpp
Go to the documentation of this file.
1//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/ADT/Twine.h"
12#include <map>
13
14using namespace clang;
15using namespace ento;
16
17//===----------------------------------------------------------------------===//
18// Methods of CmdLineOption, PackageInfo and CheckerInfo.
19//===----------------------------------------------------------------------===//
20
21LLVM_DUMP_METHOD void CmdLineOption::dump() const {
22 dumpToStream(llvm::errs());
23}
24
25LLVM_DUMP_METHOD void
26CmdLineOption::dumpToStream(llvm::raw_ostream &Out) const {
27 // The description can be just checked in Checkers.inc, the point here is to
28 // debug whether we succeeded in parsing it.
29 Out << OptionName << " (" << OptionType << ", "
30 << (IsHidden ? "hidden, " : "") << DevelopmentStatus << ") default: \""
32}
33
34static StringRef toString(StateFromCmdLine Kind) {
35 switch (Kind) {
36 case StateFromCmdLine::State_Disabled:
37 return "Disabled";
38 case StateFromCmdLine::State_Enabled:
39 return "Enabled";
40 case StateFromCmdLine::State_Unspecified:
41 return "Unspecified";
42 }
43 llvm_unreachable("Unhandled StateFromCmdLine enum");
44}
45
46LLVM_DUMP_METHOD void CheckerInfo::dump() const { dumpToStream(llvm::errs()); }
47
48LLVM_DUMP_METHOD void CheckerInfo::dumpToStream(llvm::raw_ostream &Out) const {
49 // The description can be just checked in Checkers.inc, the point here is to
50 // debug whether we succeeded in parsing it. Same with documentation uri.
51 Out << FullName << " (" << toString(State) << (IsHidden ? ", hidden" : "")
52 << ")\n";
53 Out << " Options:\n";
54 for (const CmdLineOption &Option : CmdLineOptions) {
55 Out << " ";
56 Option.dumpToStream(Out);
57 Out << '\n';
58 }
59 Out << " Dependencies:\n";
60 for (const CheckerInfo *Dependency : Dependencies) {
61 Out << " " << Dependency->FullName << '\n';
62 }
63 Out << " Weak dependencies:\n";
64 for (const CheckerInfo *Dependency : WeakDependencies) {
65 Out << " " << Dependency->FullName << '\n';
66 }
67}
68
69LLVM_DUMP_METHOD void PackageInfo::dump() const { dumpToStream(llvm::errs()); }
70
71LLVM_DUMP_METHOD void PackageInfo::dumpToStream(llvm::raw_ostream &Out) const {
72 Out << FullName << "\n";
73 Out << " Options:\n";
74 for (const CmdLineOption &Option : CmdLineOptions) {
75 Out << " ";
76 Option.dumpToStream(Out);
77 Out << '\n';
78 }
79}
80
81static constexpr char PackageSeparator = '.';
82
83static bool isInPackage(const CheckerInfo &Checker, StringRef PackageName) {
84 // Does the checker's full name have the package as a prefix?
85 if (!Checker.FullName.starts_with(PackageName))
86 return false;
87
88 // Is the package actually just the name of a specific checker?
89 if (Checker.FullName.size() == PackageName.size())
90 return true;
91
92 // Is the checker in the package (or a subpackage)?
93 if (Checker.FullName[PackageName.size()] == PackageSeparator)
94 return true;
95
96 return false;
97}
98
101 auto It = checker_registry::binaryFind(Checkers, CmdLineArg);
102
103 if (!isInPackage(*It, CmdLineArg))
104 return {Checkers.end(), Checkers.end()};
105
106 // See how large the package is.
107 // If the package doesn't exist, assume the option refers to a single
108 // checker.
109 size_t Size = 1;
110 llvm::StringMap<size_t>::const_iterator PackageSize =
111 PackageSizes.find(CmdLineArg);
112
113 if (PackageSize != PackageSizes.end())
114 Size = PackageSize->getValue();
115
116 return {It, It + Size};
117}
118//===----------------------------------------------------------------------===//
119// Printing functions.
120//===----------------------------------------------------------------------===//
121
123 const AnalyzerOptions &AnOpts, raw_ostream &Out,
124 size_t MaxNameChars) const {
125 // FIXME: Print available packages.
126
127 Out << "CHECKERS:\n";
128
129 // Find the maximum option length.
130 size_t OptionFieldWidth = 0;
131 for (const auto &Checker : Checkers) {
132 // Limit the amount of padding we are willing to give up for alignment.
133 // Package.Name Description [Hidden]
134 size_t NameLength = Checker.FullName.size();
135 if (NameLength <= MaxNameChars)
136 OptionFieldWidth = std::max(OptionFieldWidth, NameLength);
137 }
138
139 const size_t InitialPad = 2;
140
141 auto Print = [=](llvm::raw_ostream &Out, const CheckerInfo &Checker,
142 StringRef Description) {
143 AnalyzerOptions::printFormattedEntry(Out, {Checker.FullName, Description},
144 InitialPad, OptionFieldWidth);
145 Out << '\n';
146 };
147
148 for (const auto &Checker : Checkers) {
149 // The order of this if branches is significant, we wouldn't like to display
150 // developer checkers even in the alpha output. For example,
151 // alpha.cplusplus.IteratorModeling is a modeling checker, hence it's hidden
152 // by default, and users (even when the user is a developer of an alpha
153 // checker) shouldn't normally tinker with whether they should be enabled.
154
155 if (Checker.IsHidden) {
156 if (AnOpts.ShowCheckerHelpDeveloper)
157 Print(Out, Checker, Checker.Desc);
158 continue;
159 }
160
161 if (Checker.FullName.starts_with("alpha")) {
162 if (AnOpts.ShowCheckerHelpAlpha)
163 Print(Out, Checker,
164 ("(Enable only for development!) " + Checker.Desc).str());
165 continue;
166 }
167
168 if (AnOpts.ShowCheckerHelp)
169 Print(Out, Checker, Checker.Desc);
170 }
171}
172
174 for (const auto *i : EnabledCheckers)
175 Out << i->FullName << '\n';
176}
177
179 raw_ostream &Out) const {
180 Out << "OVERVIEW: Clang Static Analyzer Checker and Package Option List\n\n";
181 Out << "USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>\n\n";
182 Out << " -analyzer-config OPTION1=VALUE, -analyzer-config "
183 "OPTION2=VALUE, ...\n\n";
184 Out << "OPTIONS:\n\n";
185
186 // It's usually ill-advised to use multimap, but clang will terminate after
187 // this function.
188 std::multimap<StringRef, const CmdLineOption &> OptionMap;
189
190 for (const CheckerInfo &Checker : Checkers) {
191 for (const CmdLineOption &Option : Checker.CmdLineOptions) {
192 OptionMap.insert({Checker.FullName, Option});
193 }
194 }
195
196 for (const PackageInfo &Package : Packages) {
197 for (const CmdLineOption &Option : Package.CmdLineOptions) {
198 OptionMap.insert({Package.FullName, Option});
199 }
200 }
201
202 auto Print = [](llvm::raw_ostream &Out, StringRef FullOption,
203 StringRef Desc) {
204 AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc},
205 /*InitialPad*/ 2,
206 /*EntryWidth*/ 50,
207 /*MinLineWidth*/ 90);
208 Out << "\n\n";
209 };
210 for (const std::pair<const StringRef, const CmdLineOption &> &Entry :
211 OptionMap) {
212 const CmdLineOption &Option = Entry.second;
213 std::string FullOption = (Entry.first + ":" + Option.OptionName).str();
214
215 std::string Desc =
216 ("(" + Option.OptionType + ") " + Option.Description + " (default: " +
217 (Option.DefaultValStr.empty() ? "\"\"" : Option.DefaultValStr) + ")")
218 .str();
219
220 // The list of these if branches is significant, we wouldn't like to
221 // display hidden alpha checker options for
222 // -analyzer-checker-option-help-alpha.
223
224 if (Option.IsHidden) {
226 Print(Out, FullOption, Desc);
227 continue;
228 }
229
230 if (Option.DevelopmentStatus == "alpha" ||
231 Entry.first.starts_with("alpha")) {
233 Print(Out, FullOption,
234 llvm::Twine("(Enable only for development!) " + Desc).str());
235 continue;
236 }
237
238 if (AnOpts.ShowCheckerOptionList)
239 Print(Out, FullOption, Desc);
240 }
241}
static constexpr char PackageSeparator
static bool isInPackage(const CheckerInfo &Checker, StringRef PackageName)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Stores options for the analyzer from the command line.
unsigned ShowCheckerOptionDeveloperList
static void printFormattedEntry(llvm::raw_ostream &Out, std::pair< StringRef, StringRef > EntryDescPair, size_t InitialPad, size_t EntryWidth, size_t MinLineWidth=0)
Convenience function for printing options or checkers and their description in a formatted manner.
std::conditional_t< std::is_const< CheckerOrPackageInfoList >::value, typename CheckerOrPackageInfoList::const_iterator, typename CheckerOrPackageInfoList::iterator > binaryFind(CheckerOrPackageInfoList &Collection, StringRef FullName)
llvm::iterator_range< CheckerInfoList::iterator > CheckerInfoListRange
The JSON file list parser is used to communicate input to InstallAPI.
Specifies a checker.
ConstCheckerInfoList WeakDependencies
ConstCheckerInfoList Dependencies
CmdLineOptionList CmdLineOptions
LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const
LLVM_DUMP_METHOD void dump() const
CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg)
void printCheckerOptionList(const AnalyzerOptions &AnOpts, raw_ostream &Out) const
void printCheckerWithDescList(const AnalyzerOptions &AnOpts, raw_ostream &Out, size_t MaxNameChars=30) const
Prints the name and description of all checkers in this registry.
void printEnabledCheckerList(raw_ostream &Out) const
llvm::StringMap< size_t > PackageSizes
Used for counting how many checkers belong to a certain package in the Checkers field.
Specifies a command line option.
LLVM_DUMP_METHOD void dump() const
LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const
CmdLineOptionList CmdLineOptions
LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const
LLVM_DUMP_METHOD void dump() const