From 64956b5e9afb2badbd91354aefba7bfdbd1652d4 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Mon, 9 Nov 2015 16:28:11 +0000 Subject: [PATCH] Add ExtraArgs and ExtraArgsBefore options to enable clang warnings via configuration files. Summary: This patch depends on http://reviews.llvm.org/D14191 Reviewers: djasper, klimek Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D14192 llvm-svn: 252485 --- clang-tools-extra/clang-tidy/ClangTidy.cpp | 14 ++++++++++++++ .../clang-tidy/ClangTidyDiagnosticConsumer.cpp | 11 ++++++++--- .../clang-tidy/ClangTidyDiagnosticConsumer.h | 10 +++++++++- clang-tools-extra/clang-tidy/ClangTidyOptions.cpp | 7 +++++++ clang-tools-extra/clang-tidy/ClangTidyOptions.h | 8 ++++++++ .../test/clang-tidy/custom-diagnostics.cpp | 12 ++++++++++++ 6 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/custom-diagnostics.cpp diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp index c637f6a3d84b0..f9d0da76c0e1a 100644 --- a/clang-tools-extra/clang-tidy/ClangTidy.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp @@ -36,6 +36,7 @@ #include "clang/Tooling/Refactoring.h" #include "clang/Tooling/ReplacementsYaml.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" @@ -376,6 +377,19 @@ runClangTidy(std::unique_ptr OptionsProvider, std::vector *Errors, ProfileData *Profile) { ClangTool Tool(Compilations, InputFiles); clang::tidy::ClangTidyContext Context(std::move(OptionsProvider)); + ArgumentsAdjuster PerFileExtraArgumentsInserter = [&Context]( + const CommandLineArguments &Args, StringRef Filename) { + ClangTidyOptions Opts = Context.getOptionsForFile(Filename); + CommandLineArguments AdjustedArgs; + if (Opts.ExtraArgsBefore) + AdjustedArgs = *Opts.ExtraArgsBefore; + AdjustedArgs.insert(AdjustedArgs.begin(), Args.begin(), Args.end()); + if (Opts.ExtraArgs) + AdjustedArgs.insert(AdjustedArgs.end(), Opts.ExtraArgs->begin(), + Opts.ExtraArgs->end()); + return AdjustedArgs; + }; + Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter); if (Profile) Context.setCheckProfileData(Profile); diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index a42efe8322742..a3e5701121e4c 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -202,9 +202,7 @@ void ClangTidyContext::setSourceManager(SourceManager *SourceMgr) { void ClangTidyContext::setCurrentFile(StringRef File) { CurrentFile = File; - // Safeguard against options with unset values. - CurrentOptions = ClangTidyOptions::getDefaults().mergeWith( - OptionsProvider->getOptions(CurrentFile)); + CurrentOptions = getOptionsForFile(CurrentFile); CheckFilter.reset(new GlobList(*getOptions().Checks)); } @@ -221,6 +219,13 @@ const ClangTidyOptions &ClangTidyContext::getOptions() const { return CurrentOptions; } +ClangTidyOptions ClangTidyContext::getOptionsForFile(StringRef File) const { + // Merge options on top of getDefaults() as a safeguard against options with + // unset values. + return ClangTidyOptions::getDefaults().mergeWith( + OptionsProvider->getOptions(CurrentFile)); +} + void ClangTidyContext::setCheckProfileData(ProfileData *P) { Profile = P; } GlobList &ClangTidyContext::getChecksFilter() { diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h index f13d4fe2ce3a9..65d7e4eba738d 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -149,7 +149,7 @@ class ClangTidyContext { /// \brief Sets ASTContext for the current translation unit. void setASTContext(ASTContext *Context); - /// \brief Gets the language options from the AST context + /// \brief Gets the language options from the AST context. LangOptions getLangOpts() const { return LangOpts; } /// \brief Returns the name of the clang-tidy check which produced this @@ -157,14 +157,22 @@ class ClangTidyContext { StringRef getCheckName(unsigned DiagnosticID) const; /// \brief Returns check filter for the \c CurrentFile. + /// + /// The \c CurrentFile can be changed using \c setCurrentFile. GlobList &getChecksFilter(); /// \brief Returns global options. const ClangTidyGlobalOptions &getGlobalOptions() const; /// \brief Returns options for \c CurrentFile. + /// + /// The \c CurrentFile can be changed using \c setCurrentFile. const ClangTidyOptions &getOptions() const; + /// \brief Returns options for \c File. Does not change or depend on + /// \c CurrentFile. + ClangTidyOptions getOptionsForFile(StringRef File) const; + /// \brief Returns \c ClangTidyStats containing issued and ignored diagnostic /// counters. const ClangTidyStats &getStats() const { return Stats; } diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp index 15ca21553994e..6baca370e8731 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -27,6 +27,7 @@ using clang::tidy::FileFilter; LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter::LineRange) LLVM_YAML_IS_SEQUENCE_VECTOR(ClangTidyOptions::StringPair) +LLVM_YAML_IS_SEQUENCE_VECTOR(std::string) namespace llvm { namespace yaml { @@ -88,6 +89,8 @@ template <> struct MappingTraits { IO.mapOptional("AnalyzeTemporaryDtors", Options.AnalyzeTemporaryDtors); IO.mapOptional("User", Options.User); IO.mapOptional("CheckOptions", NOpts->Options); + IO.mapOptional("ExtraArgs", Options.ExtraArgs); + IO.mapOptional("ExtraArgsBefore", Options.ExtraArgsBefore); } }; @@ -129,6 +132,10 @@ ClangTidyOptions::mergeWith(const ClangTidyOptions &Other) const { Result.AnalyzeTemporaryDtors = Other.AnalyzeTemporaryDtors; if (Other.User) Result.User = Other.User; + if (Other.ExtraArgs) + Result.ExtraArgs = Other.ExtraArgs; + if (Other.ExtraArgsBefore) + Result.ExtraArgsBefore = Other.ExtraArgsBefore; for (const auto &KeyValue : Other.CheckOptions) Result.CheckOptions[KeyValue.first] = KeyValue.second; diff --git a/clang-tools-extra/clang-tidy/ClangTidyOptions.h b/clang-tools-extra/clang-tidy/ClangTidyOptions.h index a92a405e0caa5..b3d956f84ffac 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyOptions.h +++ b/clang-tools-extra/clang-tidy/ClangTidyOptions.h @@ -83,6 +83,14 @@ struct ClangTidyOptions { /// \brief Key-value mapping used to store check-specific options. OptionMap CheckOptions; + + typedef std::vector ArgList; + + /// \brief Add extra compilation arguments to the end of the list. + llvm::Optional ExtraArgs; + + /// \brief Add extra compilation arguments to the start of the list. + llvm::Optional ExtraArgsBefore; }; /// \brief Abstract interface for retrieving various ClangTidy options. diff --git a/clang-tools-extra/test/clang-tidy/custom-diagnostics.cpp b/clang-tools-extra/test/clang-tidy/custom-diagnostics.cpp new file mode 100644 index 0000000000000..61a929203171f --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/custom-diagnostics.cpp @@ -0,0 +1,12 @@ +// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' %s -- | count 0 +// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-shadow,clang-diagnostic-float-conversion' \ +// RUN: -config='{ExtraArgs: ["-Wshadow","-Wno-unused-variable"], ExtraArgsBefore: ["-Wno-shadow","-Wfloat-conversion","-Wunused-variable"]}' %s -- \ +// RUN: | FileCheck -implicit-check-not='{{warning:|error:}}' %s + +void f(float x) { + int a; + { int a; } + // CHECK: :[[@LINE-1]]:9: warning: declaration shadows a local variable [clang-diagnostic-shadow] + int b = x; + // CHECK: :[[@LINE-1]]:11: warning: implicit conversion turns floating-point number into integer: 'float' to 'int' [clang-diagnostic-float-conversion] +}