[clang-tools-extra] r217155 - Implemented clang-tidy configurability via .clang-tidy files.
Alexander Kornienko
alexfh at google.com
Thu Sep 4 07:23:36 PDT 2014
Author: alexfh
Date: Thu Sep 4 09:23:36 2014
New Revision: 217155
URL: http://llvm.org/viewvc/llvm-project?rev=217155&view=rev
Log:
Implemented clang-tidy configurability via .clang-tidy files.
Summary:
This adds a support for the .clang-tidy file reading using
FileOptionsProvider, -dump-config option, and changes tests to not depend on
default checks set.
Reviewers: klimek, bkramer, djasper
Reviewed By: djasper
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D5186
Added:
clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/
clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/.clang-tidy
clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/1/
clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/1/.clang-tidy
clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/2/
clang-tools-extra/trunk/test/clang-tidy/config-files.cpp
clang-tools-extra/trunk/test/clang-tidy/validate-check-names.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
clang-tools-extra/trunk/clang-tidy/ClangTidy.h
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp
clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h
clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyOptionsTest.cpp
clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.cpp Thu Sep 4 09:23:36 2014
@@ -314,17 +314,19 @@ void ClangTidyCheck::setName(StringRef N
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options) {
clang::tidy::ClangTidyContext Context(
- new DefaultOptionsProvider(ClangTidyGlobalOptions(), Options));
+ llvm::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(),
+ Options));
ClangTidyASTConsumerFactory Factory(Context);
return Factory.getCheckNames(Context.getChecksFilter());
}
-ClangTidyStats runClangTidy(ClangTidyOptionsProvider *OptionsProvider,
- const tooling::CompilationDatabase &Compilations,
- ArrayRef<std::string> InputFiles,
- std::vector<ClangTidyError> *Errors) {
+ClangTidyStats
+runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
+ const tooling::CompilationDatabase &Compilations,
+ ArrayRef<std::string> InputFiles,
+ std::vector<ClangTidyError> *Errors) {
ClangTool Tool(Compilations, InputFiles);
- clang::tidy::ClangTidyContext Context(OptionsProvider);
+ clang::tidy::ClangTidyContext Context(std::move(OptionsProvider));
ClangTidyDiagnosticConsumer DiagConsumer(Context);
Tool.setDiagnosticConsumer(&DiagConsumer);
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidy.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidy.h?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidy.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidy.h Thu Sep 4 09:23:36 2014
@@ -118,10 +118,8 @@ private:
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options);
/// \brief Run a set of clang-tidy checks on a set of files.
-///
-/// Takes ownership of the \c OptionsProvider.
ClangTidyStats
-runClangTidy(ClangTidyOptionsProvider *OptionsProvider,
+runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
const tooling::CompilationDatabase &Compilations,
ArrayRef<std::string> InputFiles,
std::vector<ClangTidyError> *Errors);
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Thu Sep 4 09:23:36 2014
@@ -160,8 +160,9 @@ bool GlobList::contains(StringRef S, boo
return Contains;
}
-ClangTidyContext::ClangTidyContext(ClangTidyOptionsProvider *OptionsProvider)
- : DiagEngine(nullptr), OptionsProvider(OptionsProvider) {
+ClangTidyContext::ClangTidyContext(
+ std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider)
+ : DiagEngine(nullptr), OptionsProvider(std::move(OptionsProvider)) {
// Before the first translation unit we can get errors related to command-line
// parsing, use empty string for the file name in this case.
setCurrentFile("");
@@ -202,7 +203,10 @@ void ClangTidyContext::setSourceManager(
void ClangTidyContext::setCurrentFile(StringRef File) {
CurrentFile = File;
- CheckFilter.reset(new GlobList(getOptions().Checks));
+ // Safeguard against options with unset values.
+ CurrentOptions = ClangTidyOptions::getDefaults().mergeWith(
+ OptionsProvider->getOptions(CurrentFile));
+ CheckFilter.reset(new GlobList(*getOptions().Checks));
}
void ClangTidyContext::setASTContext(ASTContext *Context) {
@@ -214,7 +218,7 @@ const ClangTidyGlobalOptions &ClangTidyC
}
const ClangTidyOptions &ClangTidyContext::getOptions() const {
- return OptionsProvider->getOptions(CurrentFile);
+ return CurrentOptions;
}
GlobList &ClangTidyContext::getChecksFilter() {
@@ -328,7 +332,7 @@ void ClangTidyDiagnosticConsumer::BeginS
const Preprocessor *PP) {
// Before the first translation unit we don't need HeaderFilter, as we
// shouldn't get valid source locations in diagnostics.
- HeaderFilter.reset(new llvm::Regex(Context.getOptions().HeaderFilterRegex));
+ HeaderFilter.reset(new llvm::Regex(*Context.getOptions().HeaderFilterRegex));
}
bool ClangTidyDiagnosticConsumer::passesLineFilter(StringRef FileName,
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.h Thu Sep 4 09:23:36 2014
@@ -117,9 +117,7 @@ struct ClangTidyStats {
class ClangTidyContext {
public:
/// \brief Initializes \c ClangTidyContext instance.
- ///
- /// Takes ownership of the \c OptionsProvider.
- ClangTidyContext(ClangTidyOptionsProvider *OptionsProvider);
+ ClangTidyContext(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider);
/// \brief Report any errors detected using this method.
///
@@ -180,6 +178,7 @@ private:
std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider;
std::string CurrentFile;
+ ClangTidyOptions CurrentOptions;
std::unique_ptr<GlobList> CheckFilter;
ClangTidyStats Stats;
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.cpp Thu Sep 4 09:23:36 2014
@@ -8,7 +8,16 @@
//===----------------------------------------------------------------------===//
#include "ClangTidyOptions.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/YAMLTraits.h"
+#include <utility>
+
+#define DEBUG_TYPE "clang-tidy-options"
using clang::tidy::ClangTidyOptions;
using clang::tidy::FileFilter;
@@ -61,20 +70,134 @@ template <> struct MappingTraits<ClangTi
namespace clang {
namespace tidy {
+ClangTidyOptions
+ClangTidyOptions::mergeWith(const ClangTidyOptions &Other) const {
+ ClangTidyOptions Result = *this;
+
+ // Merge comma-separated glob lists by appending the new value after a comma.
+ if (Other.Checks)
+ Result.Checks =
+ (Result.Checks && !Result.Checks->empty() ? *Result.Checks + "," : "") +
+ *Other.Checks;
+
+ if (Other.HeaderFilterRegex)
+ Result.HeaderFilterRegex = Other.HeaderFilterRegex;
+ if (Other.AnalyzeTemporaryDtors)
+ Result.AnalyzeTemporaryDtors = Other.AnalyzeTemporaryDtors;
+ return Result;
+}
+
+FileOptionsProvider::FileOptionsProvider(
+ const ClangTidyGlobalOptions &GlobalOptions,
+ const ClangTidyOptions &FallbackOptions,
+ const ClangTidyOptions &OverrideOptions)
+ : DefaultOptionsProvider(GlobalOptions, FallbackOptions),
+ OverrideOptions(OverrideOptions) {
+ CachedOptions[""] = FallbackOptions.mergeWith(OverrideOptions);
+}
+
+static const char ConfigFileName[] = ".clang-tidy";
+
+// FIXME: This method has some common logic with clang::format::getStyle().
+// Consider pulling out common bits to a findParentFileWithName function or
+// similar.
+const ClangTidyOptions &FileOptionsProvider::getOptions(StringRef FileName) {
+ DEBUG(llvm::dbgs() << "Getting options for file " << FileName << "...\n");
+ SmallString<256> FilePath(FileName);
+
+ if (std::error_code EC = llvm::sys::fs::make_absolute(FilePath)) {
+ llvm::errs() << "Can't make absolute path from " << FileName << ": "
+ << EC.message() << "\n";
+ // FIXME: Figure out what to do.
+ } else {
+ FileName = FilePath;
+ }
+
+ // Look for a suitable configuration file in all parent directories of the
+ // file. Start with the immediate parent directory and move up.
+ StringRef Path = llvm::sys::path::parent_path(FileName);
+ for (StringRef CurrentPath = Path;;
+ CurrentPath = llvm::sys::path::parent_path(CurrentPath)) {
+ llvm::ErrorOr<ClangTidyOptions> Result = std::error_code();
+
+ auto Iter = CachedOptions.find(CurrentPath);
+ if (Iter != CachedOptions.end())
+ Result = Iter->second;
+
+ if (!Result)
+ Result = TryReadConfigFile(CurrentPath);
+
+ if (Result) {
+ // Store cached value for all intermediate directories.
+ while (Path != CurrentPath) {
+ DEBUG(llvm::dbgs() << "Caching configuration for path " << Path
+ << ".\n");
+ CachedOptions.GetOrCreateValue(Path, *Result);
+ Path = llvm::sys::path::parent_path(Path);
+ }
+ return CachedOptions.GetOrCreateValue(Path, *Result).getValue();
+ }
+ if (Result.getError() != std::errc::no_such_file_or_directory) {
+ llvm::errs() << "Error reading " << ConfigFileName << " from " << Path
+ << ": " << Result.getError().message() << "\n";
+ }
+ }
+}
+
+llvm::ErrorOr<ClangTidyOptions>
+FileOptionsProvider::TryReadConfigFile(StringRef Directory) {
+ assert(!Directory.empty());
+
+ ClangTidyOptions Options = DefaultOptionsProvider::getOptions(Directory);
+ if (!llvm::sys::fs::is_directory(Directory))
+ return std::errc::not_a_directory;
+
+ SmallString<128> ConfigFile(Directory);
+ llvm::sys::path::append(ConfigFile, ".clang-tidy");
+ DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n");
+
+ bool IsFile = false;
+ // Ignore errors from is_regular_file: we only need to know if we can read
+ // the file or not.
+ llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile);
+
+ if (!IsFile)
+ return std::errc::no_such_file_or_directory;
+
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+ llvm::MemoryBuffer::getFile(ConfigFile.c_str());
+ if (std::error_code EC = Text.getError())
+ return EC;
+ if (std::error_code EC = parseConfiguration((*Text)->getBuffer(), Options))
+ return EC;
+ return Options.mergeWith(OverrideOptions);
+}
+
/// \brief Parses -line-filter option and stores it to the \c Options.
-std::error_code parseLineFilter(const std::string &LineFilter,
+std::error_code parseLineFilter(StringRef LineFilter,
clang::tidy::ClangTidyGlobalOptions &Options) {
llvm::yaml::Input Input(LineFilter);
Input >> Options.LineFilter;
return Input.error();
}
-std::error_code parseConfiguration(const std::string &Config,
+std::error_code parseConfiguration(StringRef Config,
clang::tidy::ClangTidyOptions &Options) {
llvm::yaml::Input Input(Config);
Input >> Options;
return Input.error();
}
+std::string configurationAsText(const ClangTidyOptions &Options) {
+ std::string Text;
+ llvm::raw_string_ostream Stream(Text);
+ llvm::yaml::Output Output(Stream);
+ // We use the same mapping method for input and output, so we need a non-const
+ // reference here.
+ ClangTidyOptions NonConstValue = Options;
+ Output << NonConstValue;
+ return Stream.str();
+}
+
} // namespace tidy
} // namespace clang
Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h (original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyOptions.h Thu Sep 4 09:23:36 2014
@@ -10,7 +10,10 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_OPTIONS_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CLANG_TIDY_OPTIONS_H
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorOr.h"
#include <string>
#include <system_error>
#include <utility>
@@ -42,18 +45,31 @@ struct ClangTidyGlobalOptions {
/// \brief Contains options for clang-tidy. These options may be read from
/// configuration files, and may be different for different translation units.
struct ClangTidyOptions {
- /// \brief Allow all checks and no headers by default.
- ClangTidyOptions() : Checks("*"), AnalyzeTemporaryDtors(false) {}
+ /// \brief These options are used for all settings that haven't been
+ /// overridden by the \c OptionsProvider.
+ ///
+ /// Allow no checks and no headers by default.
+ static ClangTidyOptions getDefaults() {
+ ClangTidyOptions Options;
+ Options.Checks = "";
+ Options.HeaderFilterRegex = "";
+ Options.AnalyzeTemporaryDtors = false;
+ return Options;
+ }
+
+ /// \brief Creates a new \c ClangTidyOptions instance combined from all fields
+ /// of this instance overridden by the fields of \p Other that have a value.
+ ClangTidyOptions mergeWith(const ClangTidyOptions &Other) const;
/// \brief Checks filter.
- std::string Checks;
+ llvm::Optional<std::string> Checks;
/// \brief Output warnings from headers matching this filter. Warnings from
/// main files will always be displayed.
- std::string HeaderFilterRegex;
+ llvm::Optional<std::string> HeaderFilterRegex;
/// \brief Turns on temporary destructor-based analysis.
- bool AnalyzeTemporaryDtors;
+ llvm::Optional<bool> AnalyzeTemporaryDtors;
};
/// \brief Abstract interface for retrieving various ClangTidy options.
@@ -79,7 +95,7 @@ public:
const ClangTidyGlobalOptions &getGlobalOptions() override {
return GlobalOptions;
}
- const ClangTidyOptions &getOptions(llvm::StringRef) override {
+ const ClangTidyOptions &getOptions(llvm::StringRef /*FileName*/) override {
return DefaultOptions;
}
@@ -88,13 +104,45 @@ private:
ClangTidyOptions DefaultOptions;
};
+/// \brief Implementation of the \c ClangTidyOptionsProvider interface, which
+/// tries to find a .clang-tidy file in the closest parent directory of each
+/// file.
+class FileOptionsProvider : public DefaultOptionsProvider {
+public:
+ /// \brief Initializes the \c FileOptionsProvider instance.
+ ///
+ /// \param GlobalOptions are just stored and returned to the caller of
+ /// \c getGlobalOptions.
+ ///
+ /// \param FallbackOptions are used in case there's no corresponding
+ /// .clang-tidy file.
+ ///
+ /// If any of the \param OverrideOptions fields are set, they will override
+ /// whatever options are read from the configuration file.
+ FileOptionsProvider(const ClangTidyGlobalOptions &GlobalOptions,
+ const ClangTidyOptions &FallbackOptions,
+ const ClangTidyOptions &OverrideOptions);
+ const ClangTidyOptions &getOptions(llvm::StringRef FileName) override;
+
+private:
+ /// \brief Try to read configuration file from \p Directory. If \p Directory
+ /// is empty, use the fallback value.
+ llvm::ErrorOr<ClangTidyOptions> TryReadConfigFile(llvm::StringRef Directory);
+
+ llvm::StringMap<ClangTidyOptions> CachedOptions;
+ ClangTidyOptions OverrideOptions;
+};
+
/// \brief Parses LineFilter from JSON and stores it to the \p Options.
-std::error_code parseLineFilter(const std::string &LineFilter,
- clang::tidy::ClangTidyGlobalOptions &Options);
+std::error_code parseLineFilter(llvm::StringRef LineFilter,
+ ClangTidyGlobalOptions &Options);
/// \brief Parses configuration from JSON and stores it to the \p Options.
-std::error_code parseConfiguration(const std::string &Config,
- clang::tidy::ClangTidyOptions &Options);
+std::error_code parseConfiguration(llvm::StringRef Config,
+ ClangTidyOptions &Options);
+
+/// \brief Serializes configuration to a YAML-encoded string.
+std::string configurationAsText(const ClangTidyOptions &Options);
} // end namespace tidy
} // end namespace clang
Modified: clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/tool/ClangTidyMain.cpp Thu Sep 4 09:23:36 2014
@@ -26,6 +26,13 @@ using namespace llvm;
static cl::OptionCategory ClangTidyCategory("clang-tidy options");
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
+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");
const char DefaultChecks[] =
"*," // Enable all checks, except these:
@@ -39,7 +46,9 @@ Checks("checks", cl::desc("Comma-separat
"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."),
+ "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));
static cl::opt<std::string>
@@ -48,7 +57,9 @@ HeaderFilter("header-filter",
"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."),
+ "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));
static cl::opt<std::string>
@@ -73,10 +84,17 @@ ListChecks("list-checks",
cl::init(false), cl::cat(ClangTidyCategory));
static cl::opt<bool>
-AnalyzeTemporaryDtors("analyze-temporary-dtors",
- cl::desc("Enable temporary destructor-aware analysis in\n"
- "clang-analyzer- checks."),
- cl::init(false), cl::cat(ClangTidyCategory));
+DumpConfig("dump-config",
+ cl::desc("Dumps configuration in the YAML format to stdout."),
+ cl::init(false), cl::cat(ClangTidyCategory));
+
+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));
static cl::opt<std::string> ExportFixes(
"export-fixes",
@@ -123,12 +141,25 @@ int main(int argc, const char **argv) {
return 1;
}
- clang::tidy::ClangTidyOptions Options;
- Options.Checks = DefaultChecks + Checks;
- Options.HeaderFilterRegex = HeaderFilter;
- Options.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
-
- std::vector<std::string> EnabledChecks = clang::tidy::getCheckNames(Options);
+ clang::tidy::ClangTidyOptions FallbackOptions;
+ FallbackOptions.Checks = DefaultChecks;
+ FallbackOptions.HeaderFilterRegex = HeaderFilter;
+ FallbackOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
+
+ clang::tidy::ClangTidyOptions OverrideOptions;
+ if (Checks.getNumOccurrences() > 0)
+ OverrideOptions.Checks = Checks;
+ if (HeaderFilter.getNumOccurrences() > 0)
+ OverrideOptions.HeaderFilterRegex = HeaderFilter;
+ if (AnalyzeTemporaryDtors.getNumOccurrences() > 0)
+ OverrideOptions.AnalyzeTemporaryDtors = AnalyzeTemporaryDtors;
+
+ auto OptionsProvider = llvm::make_unique<clang::tidy::FileOptionsProvider>(
+ GlobalOptions, FallbackOptions, OverrideOptions);
+
+ std::string FileName = OptionsParser.getSourcePathList().front();
+ std::vector<std::string> EnabledChecks =
+ clang::tidy::getCheckNames(OptionsProvider->getOptions(FileName));
// FIXME: Allow using --list-checks without positional arguments.
if (ListChecks) {
@@ -139,18 +170,23 @@ int main(int argc, const char **argv) {
return 0;
}
+ if (DumpConfig) {
+ llvm::outs() << clang::tidy::configurationAsText(
+ clang::tidy::ClangTidyOptions::getDefaults()
+ .mergeWith(OptionsProvider->getOptions(FileName)))
+ << "\n";
+ return 0;
+ }
+
if (EnabledChecks.empty()) {
llvm::errs() << "Error: no checks enabled.\n";
llvm::cl::PrintHelpMessage(/*Hidden=*/false, /*Categorized=*/true);
return 1;
}
- // TODO: Implement configuration file reading and a "real" options provider.
- auto OptionsProvider =
- new clang::tidy::DefaultOptionsProvider(GlobalOptions, Options);
std::vector<clang::tidy::ClangTidyError> Errors;
clang::tidy::ClangTidyStats Stats = clang::tidy::runClangTidy(
- OptionsProvider, OptionsParser.getCompilations(),
+ std::move(OptionsProvider), OptionsParser.getCompilations(),
OptionsParser.getSourcePathList(), &Errors);
clang::tidy::handleErrors(Errors, Fix);
Added: clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/.clang-tidy
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/.clang-tidy?rev=217155&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/.clang-tidy (added)
+++ clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/.clang-tidy Thu Sep 4 09:23:36 2014
@@ -0,0 +1,2 @@
+Checks: 'from-parent'
+HeaderFilterRegex: 'parent'
Added: clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/1/.clang-tidy
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/1/.clang-tidy?rev=217155&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/1/.clang-tidy (added)
+++ clang-tools-extra/trunk/test/clang-tidy/Inputs/config-files/1/.clang-tidy Thu Sep 4 09:23:36 2014
@@ -0,0 +1,2 @@
+Checks: 'from-child1'
+HeaderFilterRegex: 'child1'
Added: clang-tools-extra/trunk/test/clang-tidy/config-files.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/config-files.cpp?rev=217155&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/config-files.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/config-files.cpp Thu Sep 4 09:23:36 2014
@@ -0,0 +1,12 @@
+// RUN: clang-tidy -dump-config %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-BASE
+// CHECK-BASE: Checks: from-parent
+// CHECK-BASE: HeaderFilterRegex: parent
+// RUN: clang-tidy -dump-config %S/Inputs/config-files/1/- -- | FileCheck %s -check-prefix=CHECK-CHILD1
+// CHECK-CHILD1: Checks: from-child1
+// CHECK-CHILD1: HeaderFilterRegex: child1
+// RUN: clang-tidy -dump-config %S/Inputs/config-files/2/- -- | FileCheck %s -check-prefix=CHECK-CHILD2
+// CHECK-CHILD2: Checks: from-parent
+// CHECK-CHILD2: HeaderFilterRegex: parent
+// RUN: clang-tidy -dump-config -checks='from-command-line' -header-filter='from command line' %S/Inputs/config-files/- -- | FileCheck %s -check-prefix=CHECK-COMMAND-LINE
+// CHECK-COMMAND-LINE: Checks: from-parent,from-command-line
+// CHECK-COMMAND-LINE: HeaderFilterRegex: from command line
Modified: clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/diagnostic.cpp Thu Sep 4 09:23:36 2014
@@ -1,5 +1,5 @@
// RUN: clang-tidy -checks='-*,misc-use-override' %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 %s
-// RUN: clang-tidy -checks='-google-*,google-explicit-constructor' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 %s
+// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 %s
// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK3 %s
// RUN: clang-tidy -checks='-*,misc-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 %s
Added: clang-tools-extra/trunk/test/clang-tidy/validate-check-names.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/validate-check-names.cpp?rev=217155&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/validate-check-names.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/validate-check-names.cpp Thu Sep 4 09:23:36 2014
@@ -0,0 +1,2 @@
+// Check names may only contain alphanumeric characters, '-', '_', and '.'.
+// RUN: clang-tidy -checks=* -list-checks - -- | grep '^ ' | cut -b5- | not grep -v '^[a-zA-Z0-9_.\-]\+$'
Modified: clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyOptionsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyOptionsTest.cpp?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyOptionsTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyOptionsTest.cpp Thu Sep 4 09:23:36 2014
@@ -61,9 +61,9 @@ TEST(ParseConfiguration, ValidConfigurat
"AnalyzeTemporaryDtors: true\n",
Options);
EXPECT_FALSE(Error);
- EXPECT_EQ("-*,misc-*", Options.Checks);
- EXPECT_EQ(".*", Options.HeaderFilterRegex);
- EXPECT_TRUE(Options.AnalyzeTemporaryDtors);
+ EXPECT_EQ("-*,misc-*", *Options.Checks);
+ EXPECT_EQ(".*", *Options.HeaderFilterRegex);
+ EXPECT_TRUE(*Options.AnalyzeTemporaryDtors);
}
} // namespace test
Modified: clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h?rev=217155&r1=217154&r2=217155&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h (original)
+++ clang-tools-extra/trunk/unittests/clang-tidy/ClangTidyTest.h Thu Sep 4 09:23:36 2014
@@ -45,8 +45,10 @@ std::string runCheckOnCode(StringRef Cod
const Twine &Filename = "input.cc",
ArrayRef<std::string> ExtraArgs = None) {
T Check;
- ClangTidyContext Context(
- new DefaultOptionsProvider(ClangTidyGlobalOptions(), ClangTidyOptions()));
+ ClangTidyOptions Options;
+ Options.Checks = "*";
+ ClangTidyContext Context(llvm::make_unique<DefaultOptionsProvider>(
+ ClangTidyGlobalOptions(), Options));
ClangTidyDiagnosticConsumer DiagConsumer(Context);
Check.setContext(&Context);
std::vector<std::string> ArgCXX11(1, "-std=c++11");
More information about the cfe-commits
mailing list