Hiralo created this revision.
Hiralo added reviewers: alexfh, njames93, hokein, DmitryPolukhin.
Hiralo added a project: clang-tools-extra.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Hiralo requested review of this revision.
commit 5c98467825b128aabd04a770ac26905d856a3757
Author: Hiral Oza <[email protected]>
Date: Wed Oct 21 23:30:22 2020 -0700
clang-tidy: adding "--clang-tidy-config=<file-path>" to specify custom config
file.
Let clang-tidy to read config from specified file.
Example:
$ clang-tidy --clang-tidy-config=/some/path/myTidyConfig --list-checks --
...this will read config from '/some/path/myTidyConfig'.
May speed-up tidy runtime since now it will just look-up <file-path>
instead of searching ".clang-tidy" in parent-dir(s).
Directly specifying config path helps setting build dependencies.
Thank you in advance for your kind review.
-Hiral
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D89936
Files:
clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
clang-tools-extra/clang-tidy/ClangTidyOptions.h
clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
Index: clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -73,6 +73,13 @@
)"),
cl::init(""), cl::cat(ClangTidyCategory));
+static cl::opt<std::string> ClangTidyConfig("clang-tidy-config", cl::desc(R"(
+Specify full path of .clang-tidy config file.
+For example, --clang-tidy-config=/some/path/myTidyConfig
+)"),
+ 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'.
@@ -279,6 +286,7 @@
ClangTidyOptions DefaultOptions;
DefaultOptions.Checks = DefaultChecks;
+ DefaultOptions.ClangTidyConfig = "";
DefaultOptions.WarningsAsErrors = "";
DefaultOptions.HeaderFilterRegex = HeaderFilter;
DefaultOptions.SystemHeaders = SystemHeaders;
@@ -291,6 +299,8 @@
ClangTidyOptions OverrideOptions;
if (Checks.getNumOccurrences() > 0)
OverrideOptions.Checks = Checks;
+ if (ClangTidyConfig.getNumOccurrences() > 0)
+ OverrideOptions.ClangTidyConfig = ClangTidyConfig;
if (WarningsAsErrors.getNumOccurrences() > 0)
OverrideOptions.WarningsAsErrors = WarningsAsErrors;
if (HeaderFilter.getNumOccurrences() > 0)
Index: clang-tools-extra/clang-tidy/ClangTidyOptions.h
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyOptions.h
+++ clang-tools-extra/clang-tidy/ClangTidyOptions.h
@@ -64,6 +64,9 @@
/// Checks filter.
llvm::Optional<std::string> Checks;
+ /// Clang-tidy-config
+ llvm::Optional<std::string> ClangTidyConfig;
+
/// WarningsAsErrors filter.
llvm::Optional<std::string> WarningsAsErrors;
@@ -227,6 +230,8 @@
/// Try to read configuration files from \p Directory using registered
/// \c ConfigHandlers.
llvm::Optional<OptionsSource> tryReadConfigFile(llvm::StringRef Directory);
+ llvm::Optional<OptionsSource> tryReadConfigFile(llvm::StringRef Path,
+ bool IsFile);
llvm::StringMap<OptionsSource> CachedOptions;
ClangTidyOptions OverrideOptions;
Index: clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
===================================================================
--- clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
+++ clang-tools-extra/clang-tidy/ClangTidyOptions.cpp
@@ -109,6 +109,7 @@
ClangTidyOptions ClangTidyOptions::getDefaults() {
ClangTidyOptions Options;
Options.Checks = "";
+ Options.ClangTidyConfig = "";
Options.WarningsAsErrors = "";
Options.HeaderFilterRegex = "";
Options.SystemHeaders = false;
@@ -306,7 +307,41 @@
<< "...\n");
assert(FS && "FS must be set.");
- llvm::SmallString<128> AbsoluteFilePath(FileName);
+ llvm::SmallString<1024> AbsoluteFilePath(FileName);
+ if (!OverrideOptions.ClangTidyConfig.getValue().empty()) {
+ AbsoluteFilePath.assign(OverrideOptions.ClangTidyConfig.getValue());
+ if (FS->makeAbsolute(AbsoluteFilePath)) {
+ std::string Msg;
+ llvm::raw_string_ostream ErrStream(Msg);
+ ErrStream << " reading configuration from <" << AbsoluteFilePath
+ << "> can't make absolute path.\n";
+ llvm::report_fatal_error(ErrStream.str());
+ }
+ bool IsFile = false;
+ bool IsLink = false;
+ llvm::sys::fs::is_regular_file(Twine(AbsoluteFilePath), IsFile);
+ llvm::sys::fs::is_symlink_file(Twine(AbsoluteFilePath), IsLink);
+ if (!(IsFile || IsLink)) {
+ std::string Msg;
+ llvm::raw_string_ostream ErrStream(Msg);
+ ErrStream << " reading configuration from <" << AbsoluteFilePath
+ << "> file doesn't exist or not regular/symlink file.\n";
+ llvm::report_fatal_error(ErrStream.str());
+ }
+
+ std::vector<OptionsSource> RawOptions =
+ DefaultOptionsProvider::getRawOptions(AbsoluteFilePath.str());
+ OptionsSource CommandLineOptions(OverrideOptions,
+ OptionsSourceTypeCheckCommandLineOption);
+
+ llvm::Optional<OptionsSource> Result;
+ Result = tryReadConfigFile(AbsoluteFilePath, true);
+ if (Result) {
+ RawOptions.push_back(*Result);
+ }
+ RawOptions.push_back(CommandLineOptions);
+ return RawOptions;
+ }
if (FS->makeAbsolute(AbsoluteFilePath))
return {};
@@ -368,6 +403,47 @@
return llvm::None;
}
+llvm::Optional<OptionsSource>
+FileOptionsProvider::tryReadConfigFile(StringRef Path, bool IsFile) {
+ // llvm::outs() << "tryReadConfigFile IsFile<" <<
+ // OverrideOptions.ClangTidyConfig << ">\n";
+ assert(!Path.empty());
+
+ if (!IsFile) {
+ tryReadConfigFile(Path);
+ }
+
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+ llvm::MemoryBuffer::getFile(Path);
+ if (std::error_code EC = Text.getError()) {
+ std::string Msg;
+ llvm::raw_string_ostream ErrStream(Msg);
+ ErrStream << " Can't read <" << Path << ">: " << EC.message() << "\n";
+ llvm::report_fatal_error(ErrStream.str());
+ }
+
+ // Skip empty files, e.g. files opened for writing via shell output
+ // redirection.
+ if ((*Text)->getBuffer().empty()) {
+ std::string Msg;
+ llvm::raw_string_ostream ErrStream(Msg);
+ ErrStream << " empty configuration file <" << Path << ">.\n";
+ llvm::report_fatal_error(ErrStream.str());
+ }
+ llvm::ErrorOr<ClangTidyOptions> ParsedOptions =
+ parseConfiguration((*Text)->getBuffer());
+ if (!ParsedOptions) {
+ if (ParsedOptions.getError()) {
+ std::string Msg;
+ llvm::raw_string_ostream ErrStream(Msg);
+ ErrStream << " parsing <" << Path
+ << ">: " << ParsedOptions.getError().message() << "\n";
+ llvm::report_fatal_error(ErrStream.str());
+ }
+ }
+ return OptionsSource(*ParsedOptions, Path);
+}
+
/// Parses -line-filter option and stores it to the \c Options.
std::error_code parseLineFilter(StringRef LineFilter,
clang::tidy::ClangTidyGlobalOptions &Options) {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits