17 #include "../ClangTidy.h" 18 #include "../ClangTidyForceLinker.h" 19 #include "../GlobList.h" 20 #include "clang/Tooling/CommonOptionsParser.h" 21 #include "llvm/Support/InitLLVM.h" 22 #include "llvm/Support/Process.h" 23 #include "llvm/Support/Signals.h" 24 #include "llvm/Support/TargetSelect.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 any configuration options have a corresponding command-line 39 option, command-line option takes precedence. The effective 40 configuration can be inspected using -dump-config: 42 $ clang-tidy -dump-config 44 Checks: '-*,some-check' 50 - key: some-check.SomeOption 60 static cl::opt<std::string>
Checks(
"checks", cl::desc(R
"( 61 Comma-separated list of globs with optional '-' 62 prefix. Globs are processed in order of 63 appearance in the list. Globs without '-' 64 prefix add checks with matching names to the 65 set, globs with the '-' prefix remove checks 66 with matching names from the set of enabled 67 checks. This option's value is appended to the 68 value of the 'Checks' option in .clang-tidy 73 static cl::opt<std::string>
WarningsAsErrors(
"warnings-as-errors", cl::desc(R
"( 74 Upgrades warnings to errors. Same format as 76 This option's value is appended to the value of 77 the 'WarningsAsErrors' option in .clang-tidy 83 static cl::opt<std::string>
HeaderFilter(
"header-filter", cl::desc(R
"( 84 Regular expression matching the names of the 85 headers to output diagnostics from. Diagnostics 86 from the main file of each translation unit are 88 Can be used together with -line-filter. 89 This option overrides the 'HeaderFilterRegex' 90 option in .clang-tidy file, if any. 97 cl::desc(
"Display the errors from system headers."),
99 static cl::opt<std::string>
LineFilter(
"line-filter", cl::desc(R
"( 100 List of files with line ranges to filter the 101 warnings. Can be used together with 102 -header-filter. The format of the list is a 103 JSON array of objects: 105 {"name":"file1.cpp","lines":[[1,3],[5,7]]}, 112 static cl::opt<bool>
Fix(
"fix", cl::desc(R
"( 113 Apply suggested fixes. Without -fix-errors 114 clang-tidy will bail out if any compilation 119 static cl::opt<bool>
FixErrors(
"fix-errors", cl::desc(R
"( 120 Apply suggested fixes even if compilation 121 errors were found. If compiler errors have 122 attached fix-its, clang-tidy will apply them as 127 static cl::opt<std::string>
FormatStyle(
"format-style", cl::desc(R
"( 128 Style for formatting code around applied fixes: 129 - 'none' (default) turns off formatting 130 - 'file' (literally 'file', not a placeholder) 131 uses .clang-format file in the closest parent 133 - '{ <json> }' specifies options inline, e.g. 134 -format-style='{BasedOnStyle: llvm, IndentWidth: 8}' 135 - 'llvm', 'google', 'webkit', 'mozilla' 136 See clang-format documentation for the up-to-date 137 information about formatting styles and options. 138 This option overrides the 'FormatStyle` option in 139 .clang-tidy file, if any. 144 static cl::opt<bool>
ListChecks(
"list-checks", cl::desc(R
"( 145 List all enabled checks and exit. Use with 146 -checks=* to list all available checks. 150 static cl::opt<bool>
ExplainConfig(
"explain-config", cl::desc(R
"( 151 For each enabled check explains, where it is 152 enabled, i.e. in clang-tidy binary, command 153 line or a specific configuration file. 157 static cl::opt<std::string>
Config(
"config", cl::desc(R
"( 158 Specifies a configuration in YAML/JSON format: 159 -config="{Checks: '*', 160 CheckOptions: [{key: x, 162 When the value is empty, clang-tidy will 163 attempt to find a file named .clang-tidy for 164 each source file in its parent directories. 168 static cl::opt<bool>
DumpConfig(
"dump-config", cl::desc(R
"( 169 Dumps configuration in the YAML format to 170 stdout. This option can be used along with a 171 file name (and '--' if the file is outside of a 172 project with configured compilation database). 173 The configuration used for this file will be 175 Use along with -checks=* to include 176 configuration of all checks. 181 Enable per-check timing profiles, and print a 189 By default reports are printed in tabulated 190 format to stderr. When this option is passed, 191 these per-TU profiles are instead stored as JSON. 193 cl::value_desc("prefix"),
201 cl::init(
false), cl::Hidden,
204 static cl::opt<std::string>
ExportFixes(
"export-fixes", cl::desc(R
"( 205 YAML file to store suggested fixes in. The 206 stored fixes can be applied to the input source 207 code with clang-apply-replacements. 209 cl::value_desc("filename"),
212 static cl::opt<bool>
Quiet(
"quiet", cl::desc(R
"( 213 Run clang-tidy in quiet mode. This suppresses 214 printing statistics about ignored warnings and 215 warnings treated as errors if the respective 216 options are specified. 221 static cl::opt<std::string>
VfsOverlay(
"vfsoverlay", cl::desc(R
"( 222 Overlay the virtual filesystem described by file 223 over the real file system. 225 cl::value_desc("filename"),
233 llvm::errs() <<
"Suppressed " << Stats.
errorsIgnored() <<
" warnings (";
241 <<
" due to line filter";
250 <<
" with check filters";
251 llvm::errs() <<
").\n";
253 llvm::errs() <<
"Use -header-filter=.* to display errors from all " 254 "non-system headers. Use -system-headers to display " 255 "errors from system headers as well.\n";
260 llvm::IntrusiveRefCntPtr<vfs::FileSystem>
FS) {
263 llvm::errs() <<
"Invalid LineFilter: " << Err.message() <<
"\n\nUsage:\n";
264 llvm::cl::PrintHelpMessage(
false,
true);
274 DefaultOptions.
User = llvm::sys::Process::GetEnv(
"USER");
276 if (!DefaultOptions.
User)
277 DefaultOptions.
User = llvm::sys::Process::GetEnv(
"USERNAME");
280 if (
Checks.getNumOccurrences() > 0)
292 if (llvm::ErrorOr<ClangTidyOptions> ParsedConfig =
294 return std::make_unique<ConfigOptionsProvider>(
296 ClangTidyOptions::getDefaults().mergeWith(DefaultOptions),
297 *ParsedConfig, OverrideOptions);
299 llvm::errs() <<
"Error: invalid configuration specified.\n" 300 << ParsedConfig.getError().message() <<
"\n";
304 return std::make_unique<FileOptionsProvider>(GlobalOptions, DefaultOptions,
305 OverrideOptions, std::move(FS));
308 llvm::IntrusiveRefCntPtr<vfs::FileSystem>
310 llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS) {
311 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
312 BaseFS->getBufferForFile(OverlayFile);
314 llvm::errs() <<
"Can't load virtual filesystem overlay file '" 315 << OverlayFile <<
"': " << Buffer.getError().message()
320 IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getVFSFromYAML(
321 std::move(Buffer.get()),
nullptr, OverlayFile);
323 llvm::errs() <<
"Error: invalid virtual filesystem overlay file '" 324 << OverlayFile <<
"'.\n";
331 llvm::InitLLVM
X(argc, argv);
334 llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> BaseFS(
335 new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
338 IntrusiveRefCntPtr<vfs::FileSystem> VfsFromFile =
342 BaseFS->pushOverlay(VfsFromFile);
346 auto *OptionsProvider = OwningOptionsProvider.get();
347 if (!OptionsProvider)
350 auto MakeAbsolute = [](
const std::string &Input) -> SmallString<256> {
353 SmallString<256> AbsolutePath(Input);
355 llvm::errs() <<
"Can't make absolute path from " << Input <<
": " 356 << EC.message() <<
"\n";
364 auto PathList = OptionsParser.getSourcePathList();
365 if (!PathList.empty()) {
369 SmallString<256> FilePath = MakeAbsolute(
FileName);
372 std::vector<std::string> EnabledChecks =
377 std::vector<clang::tidy::ClangTidyOptionsProvider::OptionsSource>
378 RawOptions = OptionsProvider->getRawOptions(FilePath);
379 for (
const std::string &Check : EnabledChecks) {
380 for (
auto It = RawOptions.rbegin(); It != RawOptions.rend(); ++It) {
381 if (It->first.Checks && GlobList(*It->first.Checks).contains(Check)) {
382 llvm::outs() <<
"'" << Check <<
"' is enabled in the " << It->second
392 if (EnabledChecks.empty()) {
393 llvm::errs() <<
"No checks enabled.\n";
396 llvm::outs() <<
"Enabled checks:";
397 for (
const auto &CheckName : EnabledChecks)
398 llvm::outs() <<
"\n " << CheckName;
399 llvm::outs() <<
"\n\n";
407 ClangTidyOptions::getDefaults().mergeWith(
413 if (EnabledChecks.empty()) {
414 llvm::errs() <<
"Error: no checks enabled.\n";
415 llvm::cl::PrintHelpMessage(
false,
true);
419 if (PathList.empty()) {
420 llvm::errs() <<
"Error: no input files specified.\n";
421 llvm::cl::PrintHelpMessage(
false,
true);
425 llvm::InitializeAllTargetInfos();
426 llvm::InitializeAllTargetMCs();
427 llvm::InitializeAllAsmParsers();
429 ClangTidyContext Context(std::move(OwningOptionsProvider),
431 std::vector<ClangTidyError> Errors =
432 runClangTidy(Context, OptionsParser.getCompilations(), PathList, BaseFS,
434 bool FoundErrors = llvm::find_if(Errors, [](
const ClangTidyError &
E) {
435 return E.DiagLevel == ClangTidyError::Error;
438 const bool DisableFixes =
Fix && FoundErrors && !
FixErrors;
440 unsigned WErrorCount = 0;
448 llvm::raw_fd_ostream OS(
ExportFixes, EC, llvm::sys::fs::OF_None);
450 llvm::errs() <<
"Error opening output file: " << EC.message() <<
'\n';
460 <<
"Found compiler errors, but -fix-errors was not specified.\n" 461 "Fixes have NOT been applied.\n\n";
466 StringRef Plural = WErrorCount == 1 ?
"" :
"s";
467 llvm::errs() << WErrorCount <<
" warning" << Plural <<
" treated as error" 482 llvm::errs() <<
"Found compiler error(s).\n";
492 int main(
int argc,
const char **argv) {
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 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
User: user
CheckOptions:
- key: some-check.SomeOption
value: 'some value'
...
)")
llvm::Optional< std::string > Checks
Checks filter.
static void printStats(const ClangTidyStats &Stats)
Some operations such as code completion produce a set of candidates.
llvm::Optional< std::string > User
Specifies the name or e-mail of the user running clang-tidy.
static cl::opt< bool > SystemHeaders("system-headers", cl::desc("Display the errors from system headers."), cl::init(false), 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 > 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< 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< 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::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))
llvm::Optional< std::string > HeaderFilterRegex
Output warnings from headers matching this filter.
def make_absolute(f, directory)
Contains options for clang-tidy.
unsigned ErrorsIgnoredCheckFilter
ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options, bool AllowEnablingAnalyzerAlphaCheckers)
Returns the effective check-specific options.
std::error_code parseLineFilter(StringRef LineFilter, clang::tidy::ClangTidyGlobalOptions &Options)
Parses -line-filter option and stores it to the Options.
llvm::ErrorOr< ClangTidyOptions > parseConfiguration(StringRef Config)
unsigned ErrorsIgnoredNOLINT
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))
OptionMap CheckOptions
Key-value mapping used to store check-specific options.
llvm::IntrusiveRefCntPtr< vfs::FileSystem > getVfsFromFile(const std::string &OverlayFile, llvm::IntrusiveRefCntPtr< vfs::FileSystem > BaseFS)
llvm::Optional< bool > SystemHeaders
Output warnings from system headers matching HeaderFilterRegex.
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 ClangTidyModuleRegistry::Add< AbseilModule > X("abseil-module", "Add Abseil checks.")
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.
llvm::Optional< std::string > FormatStyle
Format code around applied fixes with clang-format using this style.
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 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 errorsIgnored() const
unsigned ErrorsIgnoredNonUserCode
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
static cl::OptionCategory ClangTidyCategory("clang-tidy options")
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))
unsigned ErrorsIgnoredLineFilter
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::extrahelp CommonHelp(CommonOptionsParser::HelpMessage)
llvm::Optional< std::string > WarningsAsErrors
WarningsAsErrors filter.
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 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 int clangTidyMain(int argc, const char **argv)
static std::unique_ptr< ClangTidyOptionsProvider > createOptionsProvider(llvm::IntrusiveRefCntPtr< vfs::FileSystem > FS)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void exportReplacements(const llvm::StringRef MainFilePath, const std::vector< ClangTidyError > &Errors, raw_ostream &OS)
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 > 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[]
int main(int argc, const char **argv)
Contains displayed and ignored diagnostic counters for a ClangTidy run.
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< 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))
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))
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))