Go to the documentation of this file.
18 #include "../ClangTidy.h"
19 #include "../ClangTidyForceLinker.h"
20 #include "../GlobList.h"
21 #include "clang/Tooling/CommonOptionsParser.h"
22 #include "llvm/Support/InitLLVM.h"
23 #include "llvm/Support/Process.h"
24 #include "llvm/Support/Signals.h"
25 #include "llvm/Support/TargetSelect.h"
26 #include "llvm/Support/WithColor.h"
33 static cl::extrahelp
CommonHelp(CommonOptionsParser::HelpMessage);
36 clang-tidy attempts to read configuration for each source file from a
37 .clang-tidy file located in the closest parent directory of the source
38 file. If InheritParentConfig is true in a config file, the configuration file
39 in the parent directory (if any exists) will be taken and current config file
40 will be applied on top of the parent one. If any configuration options have
41 a corresponding command-line option, command-line option takes precedence.
42 The effective configuration can be inspected using -dump-config:
44 $ clang-tidy -dump-config
46 Checks: '-*,some-check'
50 InheritParentConfig: true
53 - key: some-check.SomeOption
63 static cl::opt<std::string>
Checks(
"checks", cl::desc(R
"(
64 Comma-separated list of globs with optional '-'
65 prefix. Globs are processed in order of
66 appearance in the list. Globs without '-'
67 prefix add checks with matching names to the
68 set, globs with the '-' prefix remove checks
69 with matching names from the set of enabled
70 checks. This option's value is appended to the
71 value of the 'Checks' option in .clang-tidy
76 static cl::opt<std::string>
WarningsAsErrors(
"warnings-as-errors", cl::desc(R
"(
77 Upgrades warnings to errors. Same format as
79 This option's value is appended to the value of
80 the 'WarningsAsErrors' option in .clang-tidy
86 static cl::opt<std::string>
HeaderFilter(
"header-filter", cl::desc(R
"(
87 Regular expression matching the names of the
88 headers to output diagnostics from. Diagnostics
89 from the main file of each translation unit are
91 Can be used together with -line-filter.
92 This option overrides the 'HeaderFilterRegex'
93 option in .clang-tidy file, if any.
100 cl::desc(
"Display the errors from system headers."),
102 static cl::opt<std::string>
LineFilter(
"line-filter", cl::desc(R
"(
103 List of files with line ranges to filter the
104 warnings. Can be used together with
105 -header-filter. The format of the list is a
106 JSON array of objects:
108 {"name":"file1.cpp","lines":[[1,3],[5,7]]},
115 static cl::opt<bool>
Fix(
"fix", cl::desc(R
"(
116 Apply suggested fixes. Without -fix-errors
117 clang-tidy will bail out if any compilation
122 static cl::opt<bool>
FixErrors(
"fix-errors", cl::desc(R
"(
123 Apply suggested fixes even if compilation
124 errors were found. If compiler errors have
125 attached fix-its, clang-tidy will apply them as
130 static cl::opt<std::string>
FormatStyle(
"format-style", cl::desc(R
"(
131 Style for formatting code around applied fixes:
132 - 'none' (default) turns off formatting
133 - 'file' (literally 'file', not a placeholder)
134 uses .clang-format file in the closest parent
136 - '{ <json> }' specifies options inline, e.g.
137 -format-style='{BasedOnStyle: llvm, IndentWidth: 8}'
138 - 'llvm', 'google', 'webkit', 'mozilla'
139 See clang-format documentation for the up-to-date
140 information about formatting styles and options.
141 This option overrides the 'FormatStyle` option in
142 .clang-tidy file, if any.
147 static cl::opt<bool>
ListChecks(
"list-checks", cl::desc(R
"(
148 List all enabled checks and exit. Use with
149 -checks=* to list all available checks.
153 static cl::opt<bool>
ExplainConfig(
"explain-config", cl::desc(R
"(
154 For each enabled check explains, where it is
155 enabled, i.e. in clang-tidy binary, command
156 line or a specific configuration file.
160 static cl::opt<std::string>
Config(
"config", cl::desc(R
"(
161 Specifies a configuration in YAML/JSON format:
162 -config="{Checks: '*',
163 CheckOptions: [{key: x,
165 When the value is empty, clang-tidy will
166 attempt to find a file named .clang-tidy for
167 each source file in its parent directories.
171 static cl::opt<bool>
DumpConfig(
"dump-config", cl::desc(R
"(
172 Dumps configuration in the YAML format to
173 stdout. This option can be used along with a
174 file name (and '--' if the file is outside of a
175 project with configured compilation database).
176 The configuration used for this file will be
178 Use along with -checks=* to include
179 configuration of all checks.
184 Enable per-check timing profiles, and print a
192 By default reports are printed in tabulated
193 format to stderr. When this option is passed,
194 these per-TU profiles are instead stored as JSON.
196 cl::value_desc("prefix"),
204 cl::init(
false), cl::Hidden,
207 static cl::opt<std::string>
ExportFixes(
"export-fixes", cl::desc(R
"(
208 YAML file to store suggested fixes in. The
209 stored fixes can be applied to the input source
210 code with clang-apply-replacements.
212 cl::value_desc("filename"),
215 static cl::opt<bool>
Quiet(
"quiet", cl::desc(R
"(
216 Run clang-tidy in quiet mode. This suppresses
217 printing statistics about ignored warnings and
218 warnings treated as errors if the respective
219 options are specified.
224 static cl::opt<std::string>
VfsOverlay(
"vfsoverlay", cl::desc(R
"(
225 Overlay the virtual filesystem described by file
226 over the real file system.
228 cl::value_desc("filename"),
231 static cl::opt<bool>
UseColor(
"use-color", cl::desc(R
"(
232 Use colors in diagnostics. If not set, colors
233 will be used if the terminal connected to
234 standard output supports colors.
235 This option overrides the 'UseColor' option in
236 .clang-tidy file, if any.
245 llvm::errs() <<
"Suppressed " << Stats.
errorsIgnored() <<
" warnings (";
253 <<
" due to line filter";
262 <<
" with check filters";
263 llvm::errs() <<
").\n";
265 llvm::errs() <<
"Use -header-filter=.* to display errors from all "
266 "non-system headers. Use -system-headers to display "
267 "errors from system headers as well.\n";
272 llvm::IntrusiveRefCntPtr<vfs::FileSystem>
FS) {
273 ClangTidyGlobalOptions GlobalOptions;
275 llvm::errs() <<
"Invalid LineFilter: " << Err.message() <<
"\n\nUsage:\n";
276 llvm::cl::PrintHelpMessage(
false,
true);
280 ClangTidyOptions DefaultOptions;
282 DefaultOptions.WarningsAsErrors =
"";
286 DefaultOptions.User = llvm::sys::Process::GetEnv(
"USER");
288 if (!DefaultOptions.User)
289 DefaultOptions.User = llvm::sys::Process::GetEnv(
"USERNAME");
291 ClangTidyOptions OverrideOptions;
292 if (
Checks.getNumOccurrences() > 0)
293 OverrideOptions.Checks =
Checks;
302 if (
UseColor.getNumOccurrences() > 0)
303 OverrideOptions.UseColor =
UseColor;
306 if (llvm::ErrorOr<ClangTidyOptions> ParsedConfig =
308 return std::make_unique<ConfigOptionsProvider>(
310 ClangTidyOptions::getDefaults().mergeWith(DefaultOptions, 0),
311 *ParsedConfig, OverrideOptions, std::move(
FS));
313 llvm::errs() <<
"Error: invalid configuration specified.\n"
314 << ParsedConfig.getError().message() <<
"\n";
318 return std::make_unique<FileOptionsProvider>(GlobalOptions, DefaultOptions,
319 OverrideOptions, std::move(
FS));
322 llvm::IntrusiveRefCntPtr<vfs::FileSystem>
324 llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS) {
325 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
326 BaseFS->getBufferForFile(OverlayFile);
328 llvm::errs() <<
"Can't load virtual filesystem overlay file '"
329 << OverlayFile <<
"': " << Buffer.getError().message()
334 IntrusiveRefCntPtr<vfs::FileSystem>
FS = vfs::getVFSFromYAML(
335 std::move(Buffer.get()),
nullptr, OverlayFile);
337 llvm::errs() <<
"Error: invalid virtual filesystem overlay file '"
338 << OverlayFile <<
"'.\n";
345 llvm::InitLLVM
X(argc, argv);
346 llvm::Expected<CommonOptionsParser> OptionsParser =
349 if (!OptionsParser) {
354 llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> BaseFS(
355 new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
358 IntrusiveRefCntPtr<vfs::FileSystem> VfsFromFile =
362 BaseFS->pushOverlay(VfsFromFile);
366 auto *OptionsProvider = OwningOptionsProvider.get();
367 if (!OptionsProvider)
370 auto MakeAbsolute = [](
const std::string &Input) -> SmallString<256> {
373 SmallString<256> AbsolutePath(Input);
375 llvm::errs() <<
"Can't make absolute path from " << Input <<
": "
376 << EC.message() <<
"\n";
384 auto PathList = OptionsParser->getSourcePathList();
385 if (!PathList.empty()) {
389 SmallString<256> FilePath = MakeAbsolute(std::string(
FileName));
391 ClangTidyOptions EffectiveOptions = OptionsProvider->getOptions(FilePath);
392 std::vector<std::string> EnabledChecks =
397 std::vector<clang::tidy::ClangTidyOptionsProvider::OptionsSource>
398 RawOptions = OptionsProvider->getRawOptions(FilePath);
399 for (
const std::string &Check : EnabledChecks) {
400 for (
auto It = RawOptions.rbegin(); It != RawOptions.rend(); ++It) {
401 if (It->first.Checks && GlobList(*It->first.Checks).contains(Check)) {
402 llvm::outs() <<
"'" << Check <<
"' is enabled in the " << It->second
412 if (EnabledChecks.empty()) {
413 llvm::errs() <<
"No checks enabled.\n";
416 llvm::outs() <<
"Enabled checks:";
417 for (
const auto &CheckName : EnabledChecks)
418 llvm::outs() <<
"\n " << CheckName;
419 llvm::outs() <<
"\n\n";
424 EffectiveOptions.CheckOptions =
427 ClangTidyOptions::getDefaults().mergeWith(
428 EffectiveOptions, 0))
433 if (EnabledChecks.empty()) {
434 llvm::errs() <<
"Error: no checks enabled.\n";
435 llvm::cl::PrintHelpMessage(
false,
true);
439 if (PathList.empty()) {
440 llvm::errs() <<
"Error: no input files specified.\n";
441 llvm::cl::PrintHelpMessage(
false,
true);
445 llvm::InitializeAllTargetInfos();
446 llvm::InitializeAllTargetMCs();
447 llvm::InitializeAllAsmParsers();
449 ClangTidyContext Context(std::move(OwningOptionsProvider),
451 std::vector<ClangTidyError> Errors =
452 runClangTidy(Context, OptionsParser->getCompilations(), PathList, BaseFS,
454 bool FoundErrors = llvm::find_if(Errors, [](
const ClangTidyError &
E) {
458 const bool DisableFixes =
Fix && FoundErrors && !
FixErrors;
460 unsigned WErrorCount = 0;
468 llvm::raw_fd_ostream
OS(
ExportFixes, EC, llvm::sys::fs::OF_None);
470 llvm::errs() <<
"Error opening output file: " << EC.message() <<
'\n';
480 <<
"Found compiler errors, but -fix-errors was not specified.\n"
481 "Fixes have NOT been applied.\n\n";
486 StringRef Plural = WErrorCount == 1 ?
"" :
"s";
487 llvm::errs() << WErrorCount <<
" warning" << Plural <<
" treated as error"
502 llvm::errs() <<
"Found compiler error(s).\n";
Some operations such as code completion produce a set of candidates.
static cl::opt< std::string > StoreCheckProfile("store-check-profile", cl::desc(R"(
By default reports are printed in tabulated
format to stderr. When this option is passed,
these per-TU profiles are instead stored as JSON.
)"), cl::value_desc("prefix"), cl::cat(ClangTidyCategory))
unsigned ErrorsIgnoredCheckFilter
static cl::opt< std::string > Checks("checks", cl::desc(R"(
Comma-separated list of globs with optional '-'
prefix. Globs are processed in order of
appearance in the list. Globs without '-'
prefix add checks with matching names to the
set, globs with the '-' prefix remove checks
with matching names from the set of enabled
checks. This option's value is appended to the
value of the 'Checks' option in .clang-tidy
file, if any.
)"), cl::init(""), cl::cat(ClangTidyCategory))
static cl::opt< std::string > FormatStyle("format-style", cl::desc(R"(
Style for formatting code around applied fixes:
- 'none' (default) turns off formatting
- 'file' (literally 'file', not a placeholder)
uses .clang-format file in the closest parent
directory
- '{ <json> }' specifies options inline, e.g.
-format-style='{BasedOnStyle: llvm, IndentWidth: 8}'
- 'llvm', 'google', 'webkit', 'mozilla'
See clang-format documentation for the up-to-date
information about formatting styles and options.
This option overrides the 'FormatStyle` option in
.clang-tidy file, if any.
)"), cl::init("none"), cl::cat(ClangTidyCategory))
std::error_code parseLineFilter(StringRef LineFilter, clang::tidy::ClangTidyGlobalOptions &Options)
Parses -line-filter option and stores it to the Options.
Contains displayed and ignored diagnostic counters for a ClangTidy run.
static cl::opt< bool > SystemHeaders("system-headers", cl::desc("Display the errors from system headers."), cl::init(false), cl::cat(ClangTidyCategory))
static cl::OptionCategory ClangTidyCategory("clang-tidy options")
ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options, bool AllowEnablingAnalyzerAlphaCheckers)
Returns the effective check-specific options.
int clangTidyMain(int argc, const char **argv)
static cl::opt< bool > ListChecks("list-checks", cl::desc(R"(
List all enabled checks and exit. Use with
-checks=* to list all available checks.
)"), cl::init(false), cl::cat(ClangTidyCategory))
static cl::opt< bool > Fix("fix", cl::desc(R"(
Apply suggested fixes. Without -fix-errors
clang-tidy will bail out if any compilation
errors were found.
)"), cl::init(false), cl::cat(ClangTidyCategory))
def make_absolute(f, directory)
static cl::opt< bool > UseColor("use-color", cl::desc(R"(
Use colors in diagnostics. If not set, colors
will be used if the terminal connected to
standard output supports colors.
This option overrides the 'UseColor' option in
.clang-tidy file, if any.
)"), cl::init(false), cl::cat(ClangTidyCategory))
constexpr static llvm::SourceMgr::DiagKind Error
std::vector< ClangTidyError > runClangTidy(clang::tidy::ClangTidyContext &Context, const CompilationDatabase &Compilations, ArrayRef< std::string > InputFiles, llvm::IntrusiveRefCntPtr< llvm::vfs::OverlayFileSystem > BaseFS, bool EnableCheckProfile, llvm::StringRef StoreCheckProfile)
static cl::opt< bool > AllowEnablingAnalyzerAlphaCheckers("allow-enabling-analyzer-alpha-checkers", cl::init(false), cl::Hidden, cl::cat(ClangTidyCategory))
This option allows enabling the experimental alpha checkers from the static analyzer.
unsigned ErrorsIgnoredNOLINT
void handleErrors(llvm::ArrayRef< ClangTidyError > Errors, ClangTidyContext &Context, bool Fix, unsigned &WarningsAsErrorsCount, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)
Displays the found Errors to the users.
unsigned errorsIgnored() const
llvm::ErrorOr< ClangTidyOptions > parseConfiguration(StringRef Config)
llvm::IntrusiveRefCntPtr< vfs::FileSystem > getVfsFromFile(const std::string &OverlayFile, llvm::IntrusiveRefCntPtr< vfs::FileSystem > BaseFS)
static ClangTidyModuleRegistry::Add< AbseilModule > X("abseil-module", "Add Abseil checks.")
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
static cl::opt< bool > Quiet("quiet", cl::desc(R"(
Run clang-tidy in quiet mode. This suppresses
printing statistics about ignored warnings and
warnings treated as errors if the respective
options are specified.
)"), cl::init(false), cl::cat(ClangTidyCategory))
unsigned ErrorsIgnoredLineFilter
unsigned ErrorsIgnoredNonUserCode
static cl::opt< std::string > HeaderFilter("header-filter", cl::desc(R"(
Regular expression matching the names of the
headers to output diagnostics from. Diagnostics
from the main file of each translation unit are
always displayed.
Can be used together with -line-filter.
This option overrides the 'HeaderFilterRegex'
option in .clang-tidy file, if any.
)"), cl::init(""), cl::cat(ClangTidyCategory))
const char DefaultChecks[]
static cl::opt< std::string > Config("config", cl::desc(R"(
Specifies a configuration in YAML/JSON format:
-config="{Checks:' *', CheckOptions:[{key:x, value:y}]}"
When the value is empty, clang-tidy will
attempt to find a file named .clang-tidy for
each source file in its parent directories.
)"), cl::init(""), cl::cat(ClangTidyCategory))
static cl::opt< std::string > WarningsAsErrors("warnings-as-errors", cl::desc(R"(
Upgrades warnings to errors. Same format as
'-checks'.
This option's value is appended to the value of
the 'WarningsAsErrors' option in .clang-tidy
file, if any.
)"), cl::init(""), cl::cat(ClangTidyCategory))
static cl::opt< bool > FixErrors("fix-errors", cl::desc(R"(
Apply suggested fixes even if compilation
errors were found. If compiler errors have
attached fix-its, clang-tidy will apply them as
well.
)"), cl::init(false), cl::cat(ClangTidyCategory))
static cl::opt< bool > EnableCheckProfile("enable-check-profile", cl::desc(R"(
Enable per-check timing profiles, and print a
report to stderr.
)"), cl::init(false), cl::cat(ClangTidyCategory))
static cl::opt< std::string > ExportFixes("export-fixes", cl::desc(R"(
YAML file to store suggested fixes in. The
stored fixes can be applied to the input source
code with clang-apply-replacements.
)"), cl::value_desc("filename"), cl::cat(ClangTidyCategory))
static cl::opt< std::string > LineFilter("line-filter", cl::desc(R"(
List of files with line ranges to filter the
warnings. Can be used together with
-header-filter. The format of the list is a
JSON array of objects:
[
{"name":"file1.cpp","lines":[[1,3],[5,7]]},
{"name":"file2.h"}
]
)"), cl::init(""), cl::cat(ClangTidyCategory))
static std::unique_ptr< ClangTidyOptionsProvider > createOptionsProvider(llvm::IntrusiveRefCntPtr< vfs::FileSystem > FS)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static LLVM_ATTRIBUTE_NORETURN void error(Twine Message)
llvm::raw_string_ostream OS
static llvm::StringRef toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K)
std::vector< std::string > getCheckNames(const ClangTidyOptions &Options, bool AllowEnablingAnalyzerAlphaCheckers)
Fills the list of check names that are enabled when the provided filters are applied.
static cl::opt< std::string > VfsOverlay("vfsoverlay", cl::desc(R"(
Overlay the virtual filesystem described by file
over the real file system.
)"), cl::value_desc("filename"), cl::cat(ClangTidyCategory))
static void printStats(const ClangTidyStats &Stats)
void exportReplacements(const llvm::StringRef MainFilePath, const std::vector< ClangTidyError > &Errors, raw_ostream &OS)
static cl::opt< bool > DumpConfig("dump-config", cl::desc(R"(
Dumps configuration in the YAML format to
stdout. This option can be used along with a
file name (and '--' if the file is outside of a
project with configured compilation database).
The configuration used for this file will be
printed.
Use along with -checks=* to include
configuration of all checks.
)"), cl::init(false), cl::cat(ClangTidyCategory))
static cl::opt< bool > ExplainConfig("explain-config", cl::desc(R"(
For each enabled check explains, where it is
enabled, i.e. in clang-tidy binary, command
line or a specific configuration file.
)"), cl::init(false), cl::cat(ClangTidyCategory))
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage)
static cl::extrahelp ClangTidyHelp(R"(
Configuration files:
clang-tidy attempts to read configuration for each source file from a
.clang-tidy file located in the closest parent directory of the source
file. If InheritParentConfig is true in a config file, the configuration file
in the parent directory (if any exists) will be taken and current config file
will be applied on top of the parent one. If any configuration options have
a corresponding command-line option, command-line option takes precedence.
The effective configuration can be inspected using -dump-config:
$ clang-tidy -dump-config
---
Checks: '-*,some-check'
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle: none
InheritParentConfig: true
User: user
CheckOptions:
- key: some-check.SomeOption
value: 'some value'
...
)")