This is another variant of doing the same. Here we pass check name and context
via constructor arguments. This way we need to delegate the corresponding
constructor in each check, but we reduce the ClangTidyCheck API significantly
and allow getting options in the constructor, which is more straightforward.

http://reviews.llvm.org/D5296

Files:
  clang-tidy/ClangTidy.cpp
  clang-tidy/ClangTidy.h
  clang-tidy/ClangTidyModule.cpp
  clang-tidy/ClangTidyModule.h
  clang-tidy/ClangTidyOptions.cpp
  clang-tidy/ClangTidyOptions.h
  clang-tidy/google/AvoidCStyleCastsCheck.h
  clang-tidy/google/ExplicitConstructorCheck.h
  clang-tidy/google/ExplicitMakePairCheck.h
  clang-tidy/google/IntegerTypesCheck.h
  clang-tidy/google/MemsetZeroLengthCheck.h
  clang-tidy/google/NamedParameterCheck.h
  clang-tidy/google/OverloadedUnaryAndCheck.h
  clang-tidy/google/StringReferenceMemberCheck.h
  clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
  clang-tidy/google/UsingNamespaceDirectiveCheck.h
  clang-tidy/llvm/HeaderGuardCheck.h
  clang-tidy/llvm/IncludeOrderCheck.h
  clang-tidy/llvm/NamespaceCommentCheck.cpp
  clang-tidy/llvm/NamespaceCommentCheck.h
  clang-tidy/llvm/TwineLocalCheck.cpp
  clang-tidy/llvm/TwineLocalCheck.h
  clang-tidy/misc/ArgumentCommentCheck.cpp
  clang-tidy/misc/ArgumentCommentCheck.h
  clang-tidy/misc/BoolPointerImplicitConversion.h
  clang-tidy/misc/RedundantSmartptrGet.h
  clang-tidy/misc/SwappedArgumentsCheck.h
  clang-tidy/misc/UndelegatedConstructor.h
  clang-tidy/misc/UnusedRAII.h
  clang-tidy/misc/UseOverride.h
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/utils/HeaderGuard.h
  unittests/clang-tidy/ClangTidyDiagnosticConsumerTest.cpp
  unittests/clang-tidy/ClangTidyTest.h
  unittests/clang-tidy/LLVMModuleTest.cpp
Index: clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tidy/ClangTidy.cpp
+++ clang-tidy/ClangTidy.cpp
@@ -214,13 +214,11 @@
   Context.setASTContext(&Compiler.getASTContext());
 
   std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
-  GlobList &Filter = Context.getChecksFilter();
-  CheckFactories->createChecks(Filter, Checks);
+  CheckFactories->createChecks(&Context, Checks);
 
   std::unique_ptr<ast_matchers::MatchFinder> Finder(
       new ast_matchers::MatchFinder);
   for (auto &Check : Checks) {
-    Check->setContext(&Context);
     Check->registerMatchers(&*Finder);
     Check->registerPPCallbacks(Compiler);
   }
@@ -235,6 +233,7 @@
   AnalyzerOptions->Config["cfg-temporary-dtors"] =
       Context.getOptions().AnalyzeTemporaryDtors ? "true" : "false";
 
+  GlobList &Filter = Context.getChecksFilter();
   AnalyzerOptions->CheckersControlList = getCheckersControlList(Filter);
   if (!AnalyzerOptions->CheckersControlList.empty()) {
     AnalyzerOptions->AnalysisStoreOpt = RegionStoreModel;
@@ -251,9 +250,9 @@
       std::move(Consumers), std::move(Finder), std::move(Checks));
 }
 
-std::vector<std::string>
-ClangTidyASTConsumerFactory::getCheckNames(GlobList &Filter) {
+std::vector<std::string> ClangTidyASTConsumerFactory::getCheckNames() {
   std::vector<std::string> CheckNames;
+  GlobList &Filter = Context.getChecksFilter();
   for (const auto &CheckFactory : *CheckFactories) {
     if (Filter.contains(CheckFactory.first))
       CheckNames.push_back(CheckFactory.first);
@@ -266,6 +265,15 @@
   return CheckNames;
 }
 
+ClangTidyOptions::OptionMap ClangTidyASTConsumerFactory::getCheckOptions() {
+  ClangTidyOptions::OptionMap Options;
+  std::vector<std::unique_ptr<ClangTidyCheck>> Checks;
+  CheckFactories->createChecks(&Context, Checks);
+  for (const auto &Check : Checks)
+    Check->storeOptions(Options);
+  return Options;
+}
+
 ClangTidyASTConsumerFactory::CheckersList
 ClangTidyASTConsumerFactory::getCheckersControlList(GlobList &Filter) {
   CheckersList List;
@@ -307,17 +315,19 @@
   check(Result);
 }
 
-void ClangTidyCheck::setName(StringRef Name) {
-  assert(CheckName.empty());
-  CheckName = Name.str();
-}
-
 std::vector<std::string> getCheckNames(const ClangTidyOptions &Options) {
   clang::tidy::ClangTidyContext Context(
       llvm::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(),
                                                 Options));
   ClangTidyASTConsumerFactory Factory(Context);
-  return Factory.getCheckNames(Context.getChecksFilter());
+  return Factory.getCheckNames();
+}
+ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options) {
+  clang::tidy::ClangTidyContext Context(
+      llvm::make_unique<DefaultOptionsProvider>(ClangTidyGlobalOptions(),
+                                                Options));
+  ClangTidyASTConsumerFactory Factory(Context);
+  return Factory.getCheckOptions();
 }
 
 ClangTidyStats
Index: clang-tidy/ClangTidy.h
===================================================================
--- clang-tidy/ClangTidy.h
+++ clang-tidy/ClangTidy.h
@@ -16,7 +16,10 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Tooling/Refactoring.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
 #include <memory>
+#include <type_traits>
 #include <vector>
 
 namespace clang {
@@ -49,6 +52,17 @@
 /// useful/necessary.
 class ClangTidyCheck : public ast_matchers::MatchFinder::MatchCallback {
 public:
+  /// \brief Initializes the check with \p CheckName and \p Context.
+  ///
+  /// Derived classes must implement the constructor with this signature or
+  /// delegate it. If a check needs to read options, it can do this in the
+  /// constructor using the getOption() methods below.
+  ClangTidyCheck(StringRef CheckName, ClangTidyContext *Context)
+      : CheckName(CheckName), Context(Context) {
+    assert(Context != nullptr);
+    assert(!CheckName.empty());
+  }
+
   virtual ~ClangTidyCheck() {}
 
   /// \brief Overwrite this to register \c PPCallbacks with \c Compiler.
@@ -75,21 +89,75 @@
   /// work in here.
   virtual void check(const ast_matchers::MatchFinder::MatchResult &Result) {}
 
-  /// \brief The infrastructure sets the context to \p Ctx with this function.
-  void setContext(ClangTidyContext *Ctx) { Context = Ctx; }
-
   /// \brief Add a diagnostic with the check's name.
   DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
                          DiagnosticIDs::Level Level = DiagnosticIDs::Warning);
 
-  /// \brief Sets the check name. Intended to be used by the clang-tidy
-  /// framework. Can be called only once.
-  void setName(StringRef Name);
+  /// \brief Should store all options supported by this check with their
+  /// current values or default values for options that haven't been overridden.
+  ///
+  /// The check should use \c storeOption() to store each option it supports
+  /// whether it has the default value or has been overridden.
+  virtual void storeOptions(ClangTidyOptions::OptionMap &Options) {}
+
+protected:
+  /// \brief Read a named option from the \c Context.
+  ///
+  /// Reads the option named <code>CheckName + "." +</code> \p LocalName
+  /// from the current options in the \c Context. If the corresponding key is
+  /// not present, returns \p Default.
+  std::string getOption(StringRef LocalName, std::string Default) const {
+    const auto &Options = Context->getOptions().CheckOptions;
+    const auto &Iter = Options.find(getQualifiedOptionName(LocalName));
+    if (Iter != Options.end())
+      return Iter->second;
+    return Default;
+  }
+
+  /// \brief Read a named option from the \c Context and parse it as \c T.
+  ///
+  /// Reads the option named <code>CheckName + "." +</code> \p LocalName
+  /// from the current options in the \c Context. If the corresponding key is
+  /// not present, returns \p Default.
+  template <typename T>
+  typename std::enable_if<std::is_integral<T>::value, T>::type
+  getOption(StringRef LocalName, T Default) const {
+    std::string Value = getOption(LocalName, "");
+    T Result = Default;
+    if (!Value.empty())
+      StringRef(Value).getAsInteger(10, Result);
+    return Result;
+  }
+
+  /// \brief Stores an option named \p LocalName with string value \p Value to
+  /// \p Options.
+  ///
+  /// The function calls \c getQualifiedOptionName(LocalName) to get the global
+  /// option name by prepending the check name.
+  void storeOption(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
+                   StringRef Value) const {
+    Options[getQualifiedOptionName(LocalName)] = Value;
+  }
+
+  /// \brief Stores an option named \p LocalName with \c int64_t value \p Value
+  /// to \p Options.
+  ///
+  /// The function calls \c getQualifiedOptionName(LocalName) to get the global
+  /// option name by prepending the check name.
+  void storeOption(ClangTidyOptions::OptionMap &Options, StringRef LocalName,
+                   int64_t Value) const {
+    storeOption(Options, LocalName, llvm::itostr(Value));
+  }
 
 private:
+  std::string getQualifiedOptionName(StringRef OptionName) const {
+    assert(!CheckName.empty());
+    return CheckName + "." + OptionName.str();
+  }
+
   void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
-  ClangTidyContext *Context;
   std::string CheckName;
+  ClangTidyContext *Context;
 };
 
 class ClangTidyCheckFactories;
@@ -103,10 +171,13 @@
   CreateASTConsumer(clang::CompilerInstance &Compiler, StringRef File);
 
   /// \brief Get the list of enabled checks.
-  std::vector<std::string> getCheckNames(GlobList &Filter);
+  std::vector<std::string> getCheckNames();
+
+  /// \brief Get the union of options from all checks.
+  ClangTidyOptions::OptionMap getCheckOptions();
 
 private:
-  typedef std::vector<std::pair<std::string, bool> > CheckersList;
+  typedef std::vector<std::pair<std::string, bool>> CheckersList;
   CheckersList getCheckersControlList(GlobList &Filter);
 
   ClangTidyContext &Context;
@@ -117,6 +188,14 @@
 /// filters are applied.
 std::vector<std::string> getCheckNames(const ClangTidyOptions &Options);
 
+/// \brief Returns the effective check-specific options.
+///
+/// The method configures ClangTidy with the specified \p Options and collects
+/// effective options from all created checks. The returned set of options
+/// includes default check-specific options for all keys not overridden by \p
+/// Options.
+ClangTidyOptions::OptionMap getCheckOptions(const ClangTidyOptions &Options);
+
 /// \brief Run a set of clang-tidy checks on a set of files.
 ClangTidyStats
 runClangTidy(std::unique_ptr<ClangTidyOptionsProvider> OptionsProvider,
Index: clang-tidy/ClangTidyModule.cpp
===================================================================
--- clang-tidy/ClangTidyModule.cpp
+++ clang-tidy/ClangTidyModule.cpp
@@ -16,19 +16,18 @@
 namespace clang {
 namespace tidy {
 
-void ClangTidyCheckFactories::registerCheckFactory(
-    StringRef Name, std::function<ClangTidyCheck *()> Factory) {
+void ClangTidyCheckFactories::registerCheckFactory(StringRef Name,
+                                                   CheckFactory Factory) {
   Factories[Name] = Factory;
 }
 
 void ClangTidyCheckFactories::createChecks(
-    GlobList &Filter, std::vector<std::unique_ptr<ClangTidyCheck>> &Checks) {
+    ClangTidyContext *Context,
+    std::vector<std::unique_ptr<ClangTidyCheck>> &Checks) {
+  GlobList &Filter = Context->getChecksFilter();
   for (const auto &Factory : Factories) {
-    if (Filter.contains(Factory.first)) {
-      ClangTidyCheck *Check = Factory.second();
-      Check->setName(Factory.first);
-      Checks.emplace_back(Check);
-    }
+    if (Filter.contains(Factory.first))
+      Checks.emplace_back(Factory.second(Factory.first, Context));
   }
 }
 
Index: clang-tidy/ClangTidyModule.h
===================================================================
--- clang-tidy/ClangTidyModule.h
+++ clang-tidy/ClangTidyModule.h
@@ -26,11 +26,13 @@
 /// this object.
 class ClangTidyCheckFactories {
 public:
+  typedef std::function<ClangTidyCheck *(
+      StringRef Name, ClangTidyContext *Context)> CheckFactory;
+
   /// \brief Registers check \p Factory with name \p Name.
   ///
   /// For all checks that have default constructors, use \c registerCheck.
-  void registerCheckFactory(StringRef Name,
-                            std::function<ClangTidyCheck *()> Factory);
+  void registerCheckFactory(StringRef Name, CheckFactory Factory);
 
   /// \brief Registers the \c CheckType with the name \p Name.
   ///
@@ -53,19 +55,21 @@
   ///   }
   /// };
   /// \endcode
-  template<typename CheckType>
-  void registerCheck(StringRef Name) {
-    registerCheckFactory(Name, []() { return new CheckType(); });
+  template <typename CheckType> void registerCheck(StringRef CheckName) {
+    registerCheckFactory(CheckName,
+                         [](StringRef Name, ClangTidyContext *Context) {
+      return new CheckType(Name, Context);
+    });
   }
 
   /// \brief Create instances of all checks matching \p CheckRegexString and
   /// store them in \p Checks.
   ///
   /// The caller takes ownership of the return \c ClangTidyChecks.
-  void createChecks(GlobList &Filter,
+  void createChecks(ClangTidyContext *Context,
                     std::vector<std::unique_ptr<ClangTidyCheck>> &Checks);
 
-  typedef std::map<std::string, std::function<ClangTidyCheck *()>> FactoryMap;
+  typedef std::map<std::string, CheckFactory> FactoryMap;
   FactoryMap::const_iterator begin() const { return Factories.begin(); }
   FactoryMap::const_iterator end() const { return Factories.end(); }
   bool empty() const { return Factories.empty(); }
Index: clang-tidy/ClangTidyOptions.cpp
===================================================================
--- clang-tidy/ClangTidyOptions.cpp
+++ clang-tidy/ClangTidyOptions.cpp
@@ -25,6 +25,7 @@
 
 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter)
 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(FileFilter::LineRange)
+LLVM_YAML_IS_SEQUENCE_VECTOR(ClangTidyOptions::StringPair);
 
 namespace llvm {
 namespace yaml {
@@ -57,11 +58,34 @@
   }
 };
 
+template <> struct MappingTraits<ClangTidyOptions::StringPair> {
+  static void mapping(IO &IO, ClangTidyOptions::StringPair &KeyValue) {
+    IO.mapRequired("key", KeyValue.first);
+    IO.mapRequired("value", KeyValue.second);
+  }
+};
+
+struct NOptionMap {
+  NOptionMap(IO &) {}
+  NOptionMap(IO &, const ClangTidyOptions::OptionMap &OptionMap)
+      : Options(OptionMap.begin(), OptionMap.end()) {}
+  ClangTidyOptions::OptionMap denormalize(IO &) {
+    ClangTidyOptions::OptionMap Map;
+    for (const auto &KeyValue : Options)
+      Map[KeyValue.first] = KeyValue.second;
+    return Map;
+  }
+  std::vector<ClangTidyOptions::StringPair> Options;
+};
+
 template <> struct MappingTraits<ClangTidyOptions> {
   static void mapping(IO &IO, ClangTidyOptions &Options) {
+    MappingNormalization<NOptionMap, ClangTidyOptions::OptionMap> NOpts(
+        IO, Options.CheckOptions);
     IO.mapOptional("Checks", Options.Checks);
     IO.mapOptional("HeaderFilterRegex", Options.HeaderFilterRegex);
     IO.mapOptional("AnalyzeTemporaryDtors", Options.AnalyzeTemporaryDtors);
+    IO.mapOptional("CheckOptions", NOpts->Options);
   }
 };
 
@@ -85,6 +109,10 @@
     Result.HeaderFilterRegex = Other.HeaderFilterRegex;
   if (Other.AnalyzeTemporaryDtors)
     Result.AnalyzeTemporaryDtors = Other.AnalyzeTemporaryDtors;
+
+  for (const auto &KeyValue : Other.CheckOptions)
+    Result.CheckOptions[KeyValue.first] = KeyValue.second;
+
   return Result;
 }
 
@@ -169,6 +197,10 @@
       llvm::MemoryBuffer::getFile(ConfigFile.c_str());
   if (std::error_code EC = Text.getError())
     return EC;
+  // Skip empty files, e.g. files opened for writing via shell output
+  // redirection.
+  if ((*Text)->getBuffer().empty())
+    return make_error_code(llvm::errc::no_such_file_or_directory);
   if (std::error_code EC = parseConfiguration((*Text)->getBuffer(), Options))
     return EC;
   return Options.mergeWith(OverrideOptions);
Index: clang-tidy/ClangTidyOptions.h
===================================================================
--- clang-tidy/ClangTidyOptions.h
+++ clang-tidy/ClangTidyOptions.h
@@ -14,6 +14,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorOr.h"
+#include <map>
 #include <string>
 #include <system_error>
 #include <utility>
@@ -70,6 +71,12 @@
 
   /// \brief Turns on temporary destructor-based analysis.
   llvm::Optional<bool> AnalyzeTemporaryDtors;
+
+  typedef std::pair<std::string, std::string> StringPair;
+  typedef std::map<std::string, std::string> OptionMap;
+
+  /// \brief Key-value mapping used to store check-specific options.
+  OptionMap CheckOptions;
 };
 
 /// \brief Abstract interface for retrieving various ClangTidy options.
Index: clang-tidy/google/AvoidCStyleCastsCheck.h
===================================================================
--- clang-tidy/google/AvoidCStyleCastsCheck.h
+++ clang-tidy/google/AvoidCStyleCastsCheck.h
@@ -26,6 +26,8 @@
 /// ones generated by -Wold-style-cast.
 class AvoidCStyleCastsCheck : public ClangTidyCheck {
 public:
+  AvoidCStyleCastsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/ExplicitConstructorCheck.h
===================================================================
--- clang-tidy/google/ExplicitConstructorCheck.h
+++ clang-tidy/google/ExplicitConstructorCheck.h
@@ -21,6 +21,8 @@
 /// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Explicit_Constructors
 class ExplicitConstructorCheck : public ClangTidyCheck {
 public:
+  ExplicitConstructorCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/ExplicitMakePairCheck.h
===================================================================
--- clang-tidy/google/ExplicitMakePairCheck.h
+++ clang-tidy/google/ExplicitMakePairCheck.h
@@ -24,6 +24,8 @@
 /// Corresponding cpplint.py check name: 'build/explicit_make_pair'.
 class ExplicitMakePairCheck : public ClangTidyCheck {
 public:
+  ExplicitMakePairCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/IntegerTypesCheck.h
===================================================================
--- clang-tidy/google/IntegerTypesCheck.h
+++ clang-tidy/google/IntegerTypesCheck.h
@@ -21,9 +21,9 @@
 /// Correspondig cpplint.py check: runtime/int.
 class IntegerTypesCheck : public ClangTidyCheck {
 public:
-  IntegerTypesCheck()
-      : UnsignedTypePrefix("uint"), SignedTypePrefix("int"),
-        AddUnderscoreT(false) {}
+  IntegerTypesCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context), UnsignedTypePrefix("uint"),
+        SignedTypePrefix("int"), AddUnderscoreT(false) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
Index: clang-tidy/google/MemsetZeroLengthCheck.h
===================================================================
--- clang-tidy/google/MemsetZeroLengthCheck.h
+++ clang-tidy/google/MemsetZeroLengthCheck.h
@@ -24,6 +24,8 @@
 /// Corresponding cpplint.py check name: 'runtime/memset'.
 class MemsetZeroLengthCheck : public ClangTidyCheck {
 public:
+  MemsetZeroLengthCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/NamedParameterCheck.h
===================================================================
--- clang-tidy/google/NamedParameterCheck.h
+++ clang-tidy/google/NamedParameterCheck.h
@@ -22,6 +22,8 @@
 /// Corresponding cpplint.py check name: 'readability/function'.
 class NamedParameterCheck : public ClangTidyCheck {
 public:
+  NamedParameterCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/OverloadedUnaryAndCheck.h
===================================================================
--- clang-tidy/google/OverloadedUnaryAndCheck.h
+++ clang-tidy/google/OverloadedUnaryAndCheck.h
@@ -22,6 +22,8 @@
 /// Corresponding cpplint.py check name: 'runtime/operator'.
 class OverloadedUnaryAndCheck : public ClangTidyCheck {
 public:
+  OverloadedUnaryAndCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/StringReferenceMemberCheck.h
===================================================================
--- clang-tidy/google/StringReferenceMemberCheck.h
+++ clang-tidy/google/StringReferenceMemberCheck.h
@@ -39,6 +39,8 @@
 /// Corresponding cpplint.py check name: 'runtime/member_string_reference'.
 class StringReferenceMemberCheck : public ClangTidyCheck {
 public:
+  StringReferenceMemberCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
===================================================================
--- clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
+++ clang-tidy/google/UnnamedNamespaceInHeaderCheck.h
@@ -22,6 +22,8 @@
 /// Corresponding cpplint.py check name: 'build/namespaces'.
 class UnnamedNamespaceInHeaderCheck : public ClangTidyCheck {
 public:
+  UnnamedNamespaceInHeaderCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/google/UsingNamespaceDirectiveCheck.h
===================================================================
--- clang-tidy/google/UsingNamespaceDirectiveCheck.h
+++ clang-tidy/google/UsingNamespaceDirectiveCheck.h
@@ -22,6 +22,8 @@
 /// Corresponding cpplint.py check name: 'build/namespaces'.
 class UsingNamespaceDirectiveCheck : public ClangTidyCheck {
 public:
+  UsingNamespaceDirectiveCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/llvm/HeaderGuardCheck.h
===================================================================
--- clang-tidy/llvm/HeaderGuardCheck.h
+++ clang-tidy/llvm/HeaderGuardCheck.h
@@ -18,6 +18,8 @@
 /// Finds and fixes header guards that do not adhere to LLVM style.
 class LLVMHeaderGuardCheck : public HeaderGuardCheck {
 public:
+  LLVMHeaderGuardCheck(StringRef Name, ClangTidyContext *Context)
+      : HeaderGuardCheck(Name, Context) {}
   bool shouldSuggestEndifComment(StringRef Filename) override { return false; }
   bool shouldFixHeaderGuard(StringRef Filename) override;
   std::string getHeaderGuard(StringRef Filename, StringRef OldGuard) override;
Index: clang-tidy/llvm/IncludeOrderCheck.h
===================================================================
--- clang-tidy/llvm/IncludeOrderCheck.h
+++ clang-tidy/llvm/IncludeOrderCheck.h
@@ -20,6 +20,8 @@
 /// see: http://llvm.org/docs/CodingStandards.html#include-style
 class IncludeOrderCheck : public ClangTidyCheck {
 public:
+  IncludeOrderCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerPPCallbacks(CompilerInstance &Compiler) override;
 };
 
Index: clang-tidy/llvm/NamespaceCommentCheck.cpp
===================================================================
--- clang-tidy/llvm/NamespaceCommentCheck.cpp
+++ clang-tidy/llvm/NamespaceCommentCheck.cpp
@@ -11,20 +11,26 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Lex/Lexer.h"
-
-
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/StringExtras.h"
 
 using namespace clang::ast_matchers;
 
 namespace clang {
 namespace tidy {
 
-NamespaceCommentCheck::NamespaceCommentCheck()
-    : NamespaceCommentPattern("^/[/*] *(end (of )?)? *(anonymous|unnamed)? *"
+NamespaceCommentCheck::NamespaceCommentCheck(StringRef Name,
+                                             ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      NamespaceCommentPattern("^/[/*] *(end (of )?)? *(anonymous|unnamed)? *"
                               "namespace( +([a-zA-Z0-9_]+))? *(\\*/)?$",
                               llvm::Regex::IgnoreCase),
-      ShortNamespaceLines(1) {}
+      ShortNamespaceLines(getOption<unsigned>("ShortNamespaceLines", 1u)),
+      SpacesBeforeComments(getOption<unsigned>("SpacesBeforeComments", 1u)) {}
+
+void NamespaceCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Options) {
+  storeOption(Options, "ShortNamespaceLines", ShortNamespaceLines);
+  storeOption(Options, "SpacesBeforeComments", SpacesBeforeComments);
+}
 
 void NamespaceCommentCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(namespaceDecl().bind("namespace"), this);
@@ -36,10 +42,12 @@
          Sources.getFileID(Loc1) == Sources.getFileID(Loc2);
 }
 
-std::string getNamespaceComment(const NamespaceDecl *ND, bool InsertLineBreak) {
+std::string getNamespaceComment(const NamespaceDecl *ND, bool InsertLineBreak,
+                                unsigned SpacesBeforeComments) {
   std::string Fix = "// namespace";
   if (!ND->isAnonymousNamespace())
-    Fix.append(" ").append(ND->getNameAsString());
+    Fix.append(std::string(SpacesBeforeComments, ' '))
+        .append(ND->getNameAsString());
   if (InsertLineBreak)
     Fix.append("\n");
   return Fix;
@@ -97,7 +105,8 @@
       diag(Loc, "namespace closing comment refers to a wrong namespace '%0'")
           << NamespaceNameInComment
           << FixItHint::CreateReplacement(
-                 OldCommentRange, getNamespaceComment(ND, NeedLineBreak));
+                 OldCommentRange,
+                 getNamespaceComment(ND, NeedLineBreak, SpacesBeforeComments));
       return;
     }
 
@@ -110,7 +119,8 @@
 
   diag(ND->getLocation(), "namespace not terminated with a closing comment")
       << FixItHint::CreateInsertion(
-          AfterRBrace, " " + getNamespaceComment(ND, NeedLineBreak));
+          AfterRBrace,
+          " " + getNamespaceComment(ND, NeedLineBreak, SpacesBeforeComments));
 }
 
 } // namespace tidy
Index: clang-tidy/llvm/NamespaceCommentCheck.h
===================================================================
--- clang-tidy/llvm/NamespaceCommentCheck.h
+++ clang-tidy/llvm/NamespaceCommentCheck.h
@@ -21,13 +21,16 @@
 /// see: http://llvm.org/docs/CodingStandards.html#namespace-indentation
 class NamespaceCommentCheck : public ClangTidyCheck {
 public:
-  NamespaceCommentCheck();
+  NamespaceCommentCheck(StringRef Name, ClangTidyContext *Context);
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
+  void storeOptions(ClangTidyOptions::OptionMap &Options) override;
+
   llvm::Regex NamespaceCommentPattern;
   const unsigned ShortNamespaceLines;
+  const unsigned SpacesBeforeComments;
 };
 
 } // namespace tidy
Index: clang-tidy/llvm/TwineLocalCheck.cpp
===================================================================
--- clang-tidy/llvm/TwineLocalCheck.cpp
+++ clang-tidy/llvm/TwineLocalCheck.cpp
@@ -17,8 +17,6 @@
 namespace clang {
 namespace tidy {
 
-TwineLocalCheck::TwineLocalCheck() {}
-
 void TwineLocalCheck::registerMatchers(MatchFinder *Finder) {
   auto TwineType =
       qualType(hasDeclaration(recordDecl(hasName("::llvm::Twine"))));
Index: clang-tidy/llvm/TwineLocalCheck.h
===================================================================
--- clang-tidy/llvm/TwineLocalCheck.h
+++ clang-tidy/llvm/TwineLocalCheck.h
@@ -19,7 +19,8 @@
 /// and should be generally avoided.
 class TwineLocalCheck : public ClangTidyCheck {
 public:
-  TwineLocalCheck();
+  TwineLocalCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/misc/ArgumentCommentCheck.cpp
===================================================================
--- clang-tidy/misc/ArgumentCommentCheck.cpp
+++ clang-tidy/misc/ArgumentCommentCheck.cpp
@@ -18,8 +18,10 @@
 namespace clang {
 namespace tidy {
 
-ArgumentCommentCheck::ArgumentCommentCheck()
-    : IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {}
+ArgumentCommentCheck::ArgumentCommentCheck(StringRef Name,
+                                           ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {}
 
 void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
Index: clang-tidy/misc/ArgumentCommentCheck.h
===================================================================
--- clang-tidy/misc/ArgumentCommentCheck.h
+++ clang-tidy/misc/ArgumentCommentCheck.h
@@ -19,7 +19,7 @@
 /// \brief Checks that argument comments match parameter names.
 class ArgumentCommentCheck : public ClangTidyCheck {
 public:
-  ArgumentCommentCheck();
+  ArgumentCommentCheck(StringRef Name, ClangTidyContext *Context);
 
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
Index: clang-tidy/misc/BoolPointerImplicitConversion.h
===================================================================
--- clang-tidy/misc/BoolPointerImplicitConversion.h
+++ clang-tidy/misc/BoolPointerImplicitConversion.h
@@ -23,6 +23,8 @@
 /// }
 class BoolPointerImplicitConversion : public ClangTidyCheck {
 public:
+  BoolPointerImplicitConversion(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/misc/RedundantSmartptrGet.h
===================================================================
--- clang-tidy/misc/RedundantSmartptrGet.h
+++ clang-tidy/misc/RedundantSmartptrGet.h
@@ -23,6 +23,8 @@
 ///   *ptr->get()  ==>  **ptr
 class RedundantSmartptrGet : public ClangTidyCheck {
 public:
+  RedundantSmartptrGet(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/misc/SwappedArgumentsCheck.h
===================================================================
--- clang-tidy/misc/SwappedArgumentsCheck.h
+++ clang-tidy/misc/SwappedArgumentsCheck.h
@@ -19,6 +19,8 @@
 /// conversions.
 class SwappedArgumentsCheck : public ClangTidyCheck {
 public:
+  SwappedArgumentsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/misc/UndelegatedConstructor.h
===================================================================
--- clang-tidy/misc/UndelegatedConstructor.h
+++ clang-tidy/misc/UndelegatedConstructor.h
@@ -20,6 +20,8 @@
 /// meant to use a delegating constructor or base class initializer.
 class UndelegatedConstructorCheck : public ClangTidyCheck {
 public:
+  UndelegatedConstructorCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/misc/UnusedRAII.h
===================================================================
--- clang-tidy/misc/UnusedRAII.h
+++ clang-tidy/misc/UnusedRAII.h
@@ -37,6 +37,8 @@
 ///   - Ignore objects returned from a call.
 class UnusedRAIICheck : public ClangTidyCheck {
 public:
+  UnusedRAIICheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/misc/UseOverride.h
===================================================================
--- clang-tidy/misc/UseOverride.h
+++ clang-tidy/misc/UseOverride.h
@@ -18,6 +18,8 @@
 /// \brief Use C++11's 'override' and remove 'virtual' where applicable.
 class UseOverride : public ClangTidyCheck {
 public:
+  UseOverride(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 };
Index: clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -173,6 +173,7 @@
   }
 
   if (DumpConfig) {
+    EffectiveOptions.CheckOptions = getCheckOptions(EffectiveOptions);
     llvm::outs() << configurationAsText(ClangTidyOptions::getDefaults()
                                             .mergeWith(EffectiveOptions))
                  << "\n";
Index: clang-tidy/utils/HeaderGuard.h
===================================================================
--- clang-tidy/utils/HeaderGuard.h
+++ clang-tidy/utils/HeaderGuard.h
@@ -18,6 +18,8 @@
 /// \brief Finds and fixes header guards.
 class HeaderGuardCheck : public ClangTidyCheck {
 public:
+  HeaderGuardCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerPPCallbacks(CompilerInstance &Compiler) override;
 
   /// \brief Returns true if the checker should suggest inserting a trailing
Index: unittests/clang-tidy/ClangTidyDiagnosticConsumerTest.cpp
===================================================================
--- unittests/clang-tidy/ClangTidyDiagnosticConsumerTest.cpp
+++ unittests/clang-tidy/ClangTidyDiagnosticConsumerTest.cpp
@@ -8,6 +8,8 @@
 
 class TestCheck : public ClangTidyCheck {
 public:
+  TestCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
   void registerMatchers(ast_matchers::MatchFinder *Finder) override {
     Finder->addMatcher(ast_matchers::varDecl().bind("var"), this);
   }
@@ -23,9 +25,8 @@
   std::vector<ClangTidyError> Errors;
   runCheckOnCode<TestCheck>("int a;", &Errors);
   EXPECT_EQ(2ul, Errors.size());
-  // FIXME: Remove " []" once the check name is removed from the message text.
-  EXPECT_EQ("type specifier []", Errors[0].Message.Message);
-  EXPECT_EQ("variable []", Errors[1].Message.Message);
+  EXPECT_EQ("type specifier", Errors[0].Message.Message);
+  EXPECT_EQ("variable", Errors[1].Message.Message);
 }
 
 TEST(GlobList, Empty) {
Index: unittests/clang-tidy/ClangTidyTest.h
===================================================================
--- unittests/clang-tidy/ClangTidyTest.h
+++ unittests/clang-tidy/ClangTidyTest.h
@@ -44,13 +44,12 @@
                            std::vector<ClangTidyError> *Errors = nullptr,
                            const Twine &Filename = "input.cc",
                            ArrayRef<std::string> ExtraArgs = None) {
-  T Check;
   ClangTidyOptions Options;
   Options.Checks = "*";
   ClangTidyContext Context(llvm::make_unique<DefaultOptionsProvider>(
       ClangTidyGlobalOptions(), Options));
   ClangTidyDiagnosticConsumer DiagConsumer(Context);
-  Check.setContext(&Context);
+  T Check("test-check", &Context);
   std::vector<std::string> ArgCXX11(1, "-std=c++11");
   ArgCXX11.insert(ArgCXX11.end(), ExtraArgs.begin(), ExtraArgs.end());
 
Index: unittests/clang-tidy/LLVMModuleTest.cpp
===================================================================
--- unittests/clang-tidy/LLVMModuleTest.cpp
+++ unittests/clang-tidy/LLVMModuleTest.cpp
@@ -95,6 +95,8 @@
 
 namespace {
 struct WithEndifComment : public LLVMHeaderGuardCheck {
+  WithEndifComment(StringRef Name, ClangTidyContext *Context)
+      : LLVMHeaderGuardCheck(Name, Context) {}
   bool shouldSuggestEndifComment(StringRef Filename) override { return true; }
 };
 } // namespace
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to