18 #include "../ClangTidy.h"
19 #include "clang/Tooling/CommonOptionsParser.h"
20 #include "llvm/Support/Process.h"
22 using namespace clang::ast_matchers;
23 using namespace clang::driver;
24 using namespace clang::tooling;
29 static cl::extrahelp
CommonHelp(CommonOptionsParser::HelpMessage);
31 "Configuration files:\n"
32 " clang-tidy attempts to read configuration for each source file from a\n"
33 " .clang-tidy file located in the closest parent directory of the source\n"
34 " file. If any configuration options have a corresponding command-line\n"
35 " option, command-line option takes precedence. The effective\n"
36 " configuration can be inspected using -dump-config:\n"
38 " $ clang-tidy -dump-config - --\n"
40 " Checks: '-*,some-check'\n"
41 " HeaderFilterRegex: ''\n"
42 " AnalyzeTemporaryDtors: false\n"
45 " - key: some-check.SomeOption\n"
46 " value: 'some value'\n"
53 "-clang-analyzer-alpha*";
55 static cl::opt<std::string>
56 Checks(
"checks", cl::desc(
"Comma-separated list of globs with optional '-'\n"
57 "prefix. Globs are processed in order of appearance\n"
58 "in the list. Globs without '-' prefix add checks\n"
59 "with matching names to the set, globs with the '-'\n"
60 "prefix remove checks with matching names from the\n"
61 "set of enabled checks.\n"
62 "This option's value is appended to the value read\n"
63 "from a .clang-tidy file, if any."),
66 static cl::opt<std::string>
68 cl::desc(
"Regular expression matching the names of the\n"
69 "headers to output diagnostics from. Diagnostics\n"
70 "from the main file of each translation unit are\n"
72 "Can be used together with -line-filter.\n"
73 "This option overrides the value read from a\n"
79 cl::desc(
"Display the errors from system headers."),
81 static cl::opt<std::string>
83 cl::desc(
"List of files with line ranges to filter the\n"
84 "warnings. Can be used together with\n"
85 "-header-filter. The format of the list is a JSON\n"
88 " {\"name\":\"file1.cpp\",\"lines\":[[1,3],[5,7]]},\n"
89 " {\"name\":\"file2.h\"}\n"
94 Fix(
"fix", cl::desc(
"Apply suggested fixes. Without -fix-errors\n"
95 "clang-tidy will bail out if any compilation\n"
96 "errors were found."),
101 cl::desc(
"Apply suggested fixes even if compilation errors\n"
102 "were found. If compiler errors have attached\n"
103 "fix-its, clang-tidy will apply them as well."),
108 cl::desc(
"List all enabled checks and exit. Use with\n"
109 "-checks=* to list all available checks."),
112 static cl::opt<std::string>
Config(
114 cl::desc(
"Specifies a configuration in YAML/JSON format:\n"
115 " -config=\"{Checks: '*', CheckOptions: [{key: x, value: y}]}\"\n"
116 "When the value is empty, clang-tidy will attempt to find\n"
117 "a file named .clang-tidy for each source file in its parent\n"
123 cl::desc(
"Dumps configuration in the YAML format to stdout. This option\n"
124 "can be used along with a file name (and '--' if the file is\n"
125 "outside of a project with configured compilation database). The\n"
126 "configuration used for this file will be printed.\n"
127 "Use along with -checks=* to include configuration of all\n"
132 "enable-check-profile",
133 cl::desc(
"Enable per-check timing profiles, and print a report to stderr."),
137 "analyze-temporary-dtors",
138 cl::desc(
"Enable temporary destructor-aware analysis in\n"
139 "clang-analyzer- checks.\n"
140 "This option overrides the value read from a\n"
141 ".clang-tidy file."),
146 cl::desc(
"YAML file to store suggested fixes in. The\n"
147 "stored fixes can be applied to the input source\n"
148 "code with clang-apply-replacements."),
156 llvm::errs() <<
"Suppressed " << Stats.
errorsIgnored() <<
" warnings (";
157 StringRef Separator =
"";
164 <<
" due to line filter";
173 <<
" with check filters";
174 llvm::errs() <<
").\n";
176 llvm::errs() <<
"Use -header-filter=.* to display errors from all "
177 "non-system headers.\n";
182 llvm::raw_ostream &OS) {
184 std::vector<std::pair<llvm::TimeRecord, StringRef>> Timers;
187 for (
const auto& P : Profile.
Records) {
188 Timers.emplace_back(P.getValue(), P.getKey());
189 Total += P.getValue();
192 std::sort(Timers.begin(), Timers.end());
194 std::string
Line =
"===" + std::string(73,
'-') +
"===\n";
197 if (Total.getUserTime())
198 OS <<
" ---User Time---";
199 if (Total.getSystemTime())
200 OS <<
" --System Time--";
201 if (Total.getProcessTime())
202 OS <<
" --User+System--";
203 OS <<
" ---Wall Time---";
204 if (Total.getMemUsed())
206 OS <<
" --- Name ---\n";
209 for (
auto I = Timers.rbegin(), E = Timers.rend(); I != E; ++I) {
210 I->first.print(Total, OS);
211 OS << I->second <<
'\n';
214 Total.print(Total, OS);
223 llvm::errs() <<
"Invalid LineFilter: " << Err.message() <<
"\n\nUsage:\n";
224 llvm::cl::PrintHelpMessage(
false,
true);
233 DefaultOptions.
User = llvm::sys::Process::GetEnv(
"USER");
235 if (!DefaultOptions.
User)
236 DefaultOptions.
User = llvm::sys::Process::GetEnv(
"USERNAME");
239 if (
Checks.getNumOccurrences() > 0)
249 if (llvm::ErrorOr<ClangTidyOptions> ParsedConfig =
251 return llvm::make_unique<DefaultOptionsProvider>(
252 GlobalOptions, ClangTidyOptions::getDefaults()
253 .mergeWith(DefaultOptions)
254 .mergeWith(*ParsedConfig)
255 .mergeWith(OverrideOptions));
257 llvm::errs() <<
"Error: invalid configuration specified.\n"
258 << ParsedConfig.getError().message() <<
"\n";
262 return llvm::make_unique<FileOptionsProvider>(GlobalOptions, DefaultOptions,
271 if (!OptionsProvider)
274 StringRef FileName(
"dummy");
275 auto PathList = OptionsParser.getSourcePathList();
276 if (!PathList.empty()) {
277 FileName = PathList.front();
280 std::vector<std::string> EnabledChecks =
getCheckNames(EffectiveOptions);
283 llvm::outs() <<
"Enabled checks:";
284 for (
auto CheckName : EnabledChecks)
285 llvm::outs() <<
"\n " << CheckName;
286 llvm::outs() <<
"\n\n";
293 ClangTidyOptions::getDefaults().mergeWith(
299 if (EnabledChecks.empty()) {
300 llvm::errs() <<
"Error: no checks enabled.\n";
301 llvm::cl::PrintHelpMessage(
false,
true);
305 if (PathList.empty()) {
306 llvm::errs() <<
"Error: no input files specified.\n";
307 llvm::cl::PrintHelpMessage(
false,
true);
313 std::vector<ClangTidyError> Errors;
315 runClangTidy(std::move(OptionsProvider), OptionsParser.getCompilations(),
319 std::find_if(Errors.begin(), Errors.end(), [](
const ClangTidyError &E) {
320 return E.DiagLevel == ClangTidyError::Error;
323 const bool DisableFixes =
Fix && FoundErrors && !
FixErrors;
330 llvm::raw_fd_ostream OS(
ExportFixes, EC, llvm::sys::fs::F_None);
332 llvm::errs() <<
"Error opening output file: " << EC.message() <<
'\n';
341 <<
"Found compiler errors, but -fix-errors was not specified.\n"
342 "Fixes have NOT been applied.\n\n";
393 int main(
int argc,
const char **argv) {
llvm::Optional< std::string > Checks
Checks filter.
volatile int GoogleModuleAnchorSource
static void printStats(const ClangTidyStats &Stats)
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))
volatile int ReadabilityModuleAnchorSource
static cl::opt< bool > ListChecks("list-checks", cl::desc("List all enabled checks and exit. Use with\n""-checks=* to list all available checks."), cl::init(false), cl::cat(ClangTidyCategory))
static cl::opt< bool > DumpConfig("dump-config", cl::desc("Dumps configuration in the YAML format to stdout. This option\n""can be used along with a file name (and '--' if the file is\n""outside of a project with configured compilation database). The\n""configuration used for this file will be printed.\n""Use along with -checks=* to include configuration of all\n""checks.\n"), cl::init(false), cl::cat(ClangTidyCategory))
llvm::Optional< std::string > HeaderFilterRegex
Output warnings from headers matching this filter.
ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options)
Returns the effective check-specific options.
static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination
Contains options for clang-tidy.
unsigned ErrorsIgnoredCheckFilter
std::error_code parseLineFilter(StringRef LineFilter, clang::tidy::ClangTidyGlobalOptions &Options)
Parses -line-filter option and stores it to the Options.
llvm::StringMap< llvm::TimeRecord > Records
llvm::ErrorOr< ClangTidyOptions > parseConfiguration(StringRef Config)
unsigned ErrorsIgnoredNOLINT
OptionMap CheckOptions
Key-value mapping used to store check-specific options.
llvm::Optional< bool > SystemHeaders
Output warnings from system headers matching HeaderFilterRegex.
volatile int LLVMModuleAnchorSource
volatile int PerformanceModuleAnchorSource
static cl::opt< bool > EnableCheckProfile("enable-check-profile", cl::desc("Enable per-check timing profiles, and print a report to stderr."), cl::init(false), cl::cat(ClangTidyCategory))
void exportReplacements(const std::vector< ClangTidyError > &Errors, raw_ostream &OS)
Serializes replacements into YAML and writes them to the specified output stream. ...
static cl::opt< std::string > LineFilter("line-filter", cl::desc("List of files with line ranges to filter the\n""warnings. Can be used together with\n""-header-filter. The format of the list is a JSON\n""array of objects:\n"" [\n"" {\"name\":\"file1.cpp\",\"lines\":[[1,3],[5,7]]},\n"" {\"name\":\"file2.h\"}\n"" ]"), cl::init(""), cl::cat(ClangTidyCategory))
volatile int CppCoreGuidelinesModuleAnchorSource
void handleErrors(const std::vector< ClangTidyError > &Errors, bool Fix)
Displays the found Errors to the users.
static int LLVM_ATTRIBUTE_UNUSED ReadabilityModuleAnchorDestination
static cl::opt< std::string > Checks("checks", cl::desc("Comma-separated list of globs with optional '-'\n""prefix. Globs are processed in order of appearance\n""in the list. Globs without '-' prefix add checks\n""with matching names to the set, globs with the '-'\n""prefix remove checks with matching names from the\n""set of enabled checks.\n""This option's value is appended to the value read\n""from a .clang-tidy file, if any."), cl::init(""), cl::cat(ClangTidyCategory))
unsigned ErrorsIgnoredNonUserCode
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
volatile int CERTModuleAnchorSource
static cl::OptionCategory ClangTidyCategory("clang-tidy options")
static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination
std::vector< std::string > getCheckNames(const ClangTidyOptions &Options)
Fills the list of check names that are enabled when the provided filters are applied.
ClangTidyStats runClangTidy(std::unique_ptr< ClangTidyOptionsProvider > OptionsProvider, const tooling::CompilationDatabase &Compilations, ArrayRef< std::string > InputFiles, std::vector< ClangTidyError > *Errors, ProfileData *Profile)
Run a set of clang-tidy checks on a set of files.
unsigned ErrorsIgnoredLineFilter
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage)
static void printProfileData(const ProfileData &Profile, llvm::raw_ostream &OS)
volatile int MiscModuleAnchorSource
static int LLVM_ATTRIBUTE_UNUSED PerformanceModuleAnchorDestination
static int clangTidyMain(int argc, const char **argv)
static int LLVM_ATTRIBUTE_UNUSED MiscModuleAnchorDestination
static cl::opt< std::string > Config("config", cl::desc("Specifies a configuration in YAML/JSON format:\n"" -config=\"{Checks: '*', CheckOptions: [{key: x, value: y}]}\"\n""When the value is empty, clang-tidy will attempt to find\n""a file named .clang-tidy for each source file in its parent\n""directories."), cl::init(""), cl::cat(ClangTidyCategory))
static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination
llvm::Optional< bool > AnalyzeTemporaryDtors
Turns on temporary destructor-based analysis.
static int LLVM_ATTRIBUTE_UNUSED ModernizeModuleAnchorDestination
unsigned errorsIgnored() const
static cl::extrahelp ClangTidyHelp("Configuration files:\n"" clang-tidy attempts to read configuration for each source file from a\n"" .clang-tidy file located in the closest parent directory of the source\n"" file. If any configuration options have a corresponding command-line\n"" option, command-line option takes precedence. The effective\n"" configuration can be inspected using -dump-config:\n""\n"" $ clang-tidy -dump-config - --\n"" ---\n"" Checks: '-*,some-check'\n"" HeaderFilterRegex: ''\n"" AnalyzeTemporaryDtors: false\n"" User: user\n"" CheckOptions: \n"" - key: some-check.SomeOption\n"" value: 'some value'\n"" ...\n""\n\n")
const char DefaultChecks[]
static std::unique_ptr< ClangTidyOptionsProvider > createOptionsProvider()
int main(int argc, const char **argv)
static cl::opt< bool > FixErrors("fix-errors", cl::desc("Apply suggested fixes even if compilation errors\n""were found. If compiler errors have attached\n""fix-its, clang-tidy will apply them as well."), cl::init(false), cl::cat(ClangTidyCategory))
A detected error complete with information to display diagnostic and automatic fix.
Contains displayed and ignored diagnostic counters for a ClangTidy run.
volatile int ModernizeModuleAnchorSource
static int LLVM_ATTRIBUTE_UNUSED CERTModuleAnchorDestination
static cl::opt< std::string > ExportFixes("export-fixes", cl::desc("YAML file to store suggested fixes in. The\n""stored fixes can be applied to the input source\n""code with clang-apply-replacements."), cl::value_desc("filename"), cl::cat(ClangTidyCategory))
static cl::opt< bool > Fix("fix", cl::desc("Apply suggested fixes. Without -fix-errors\n""clang-tidy will bail out if any compilation\n""errors were found."), cl::init(false), cl::cat(ClangTidyCategory))
static cl::opt< std::string > HeaderFilter("header-filter", cl::desc("Regular expression matching the names of the\n""headers to output diagnostics from. Diagnostics\n""from the main file of each translation unit are\n""always displayed.\n""Can be used together with -line-filter.\n""This option overrides the value read from a\n"".clang-tidy file."), cl::init(""), cl::cat(ClangTidyCategory))
Container for clang-tidy profiling data.
static cl::opt< bool > AnalyzeTemporaryDtors("analyze-temporary-dtors", cl::desc("Enable temporary destructor-aware analysis in\n""clang-analyzer- checks.\n""This option overrides the value read from a\n"".clang-tidy file."), cl::init(false), cl::cat(ClangTidyCategory))