Implemented clang-tidy-check-specific options.

Summary:
Each check can implement readOptions and storeOptions methods to read
and store custom options. Each check's options are stored in a local namespace
to avoid name collisions and provide some sort of context to the user.

Reviewers: bkramer, klimek

Reviewed By: klimek

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D5296

llvm-svn: 217661
diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp
index f543e2f..0712f69 100644
--- a/clang-tools-extra/clang-tidy/ClangTidy.cpp
+++ b/clang-tools-extra/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,9 +315,25 @@
   check(Result);
 }
 
-void ClangTidyCheck::setName(StringRef Name) {
-  assert(CheckName.empty());
-  CheckName = Name.str();
+OptionsView::OptionsView(StringRef CheckName,
+                         const ClangTidyOptions::OptionMap &CheckOptions)
+    : NamePrefix(CheckName.str() + "."), CheckOptions(CheckOptions) {}
+
+std::string OptionsView::get(StringRef LocalName, std::string Default) const {
+  const auto &Iter = CheckOptions.find(NamePrefix + LocalName.str());
+  if (Iter != CheckOptions.end())
+    return Iter->second;
+  return Default;
+}
+
+void OptionsView::store(ClangTidyOptions::OptionMap &Options,
+                        StringRef LocalName, StringRef Value) const {
+  Options[NamePrefix + LocalName.str()] = Value;
+}
+
+void OptionsView::store(ClangTidyOptions::OptionMap &Options,
+                        StringRef LocalName, int64_t Value) const {
+  store(Options, LocalName, llvm::itostr(Value));
 }
 
 std::vector<std::string> getCheckNames(const ClangTidyOptions &Options) {
@@ -317,7 +341,15 @@
       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