arphaman created this revision.

This patch ensures that CommonOptionsParser works with subcommands. This allows 
clang-refactor to use the `CommonOptionsParser`.

Depends on https://reviews.llvm.org/D36574.


Repository:
  rL LLVM

https://reviews.llvm.org/D37618

Files:
  lib/Tooling/CommonOptionsParser.cpp
  test/Refactor/LocalRename/Field.cpp
  test/Refactor/tool-common-options.c
  tools/clang-refactor/ClangRefactor.cpp

Index: tools/clang-refactor/ClangRefactor.cpp
===================================================================
--- tools/clang-refactor/ClangRefactor.cpp
+++ tools/clang-refactor/ClangRefactor.cpp
@@ -15,6 +15,7 @@
 
 #include "TestSupport.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/Refactoring/RefactoringAction.h"
 #include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
@@ -33,12 +34,6 @@
 
 static cl::OptionCategory CommonRefactorOptions("Common refactoring options");
 
-static cl::opt<bool>
-    NoDatabases("no-dbs",
-                cl::desc("Ignore external databases including Clang's "
-                         "compilation database and indexer stores"),
-                cl::cat(CommonRefactorOptions), cl::sub(*cl::AllSubCommands));
-
 static cl::opt<bool> Verbose("v", cl::desc("Use verbose output"),
                              cl::cat(CommonRefactorOptions),
                              cl::sub(*cl::AllSubCommands));
@@ -122,10 +117,6 @@
                               cl::OptionCategory &Category)
       : SubCommand(Action->getCommand(), Action->getDescription()),
         Action(std::move(Action)), ActionRules(std::move(ActionRules)) {
-    Sources = llvm::make_unique<cl::list<std::string>>(
-        cl::Positional, cl::ZeroOrMore, cl::desc("<source0> [... <sourceN>]"),
-        cl::cat(Category), cl::sub(*this));
-
     // Check if the selection option is supported.
     bool HasSelection = false;
     for (const auto &Rule : this->ActionRules) {
@@ -162,13 +153,9 @@
     assert(Selection && "selection not supported!");
     return ParsedSelection.get();
   }
-
-  ArrayRef<std::string> getSources() const { return *Sources; }
-
 private:
   std::unique_ptr<RefactoringAction> Action;
   RefactoringActionRules ActionRules;
-  std::unique_ptr<cl::list<std::string>> Sources;
   std::unique_ptr<cl::opt<std::string>> Selection;
   std::unique_ptr<SourceSelectionArgument> ParsedSelection;
 };
@@ -214,20 +201,9 @@
   /// Parses the translation units that were given to the subcommand using
   /// the 'sources' option and invokes the callback for each parsed
   /// translation unit.
-  bool foreachTranslationUnit(RefactoringActionSubcommand &Subcommand,
+  bool foreachTranslationUnit(const CompilationDatabase &DB,
+                              ArrayRef<std::string> Sources,
                               TUCallbackType Callback) {
-    std::unique_ptr<CompilationDatabase> Compilations;
-    if (opts::NoDatabases) {
-      // FIXME (Alex L): Support compilation options.
-      Compilations =
-          llvm::make_unique<clang::tooling::FixedCompilationDatabase>(
-              ".", std::vector<std::string>());
-    } else {
-      // FIXME (Alex L): Support compilation database.
-      llvm::errs() << "compilation databases are not supported yet!\n";
-      return true;
-    }
-
     class ToolASTConsumer : public ASTConsumer {
     public:
       TUCallbackType Callback;
@@ -247,7 +223,7 @@
       }
     };
 
-    ClangTool Tool(*Compilations, Subcommand.getSources());
+    ClangTool Tool(DB, Sources);
     ActionWrapper ToolAction(std::move(Callback));
     std::unique_ptr<tooling::FrontendActionFactory> Factory =
         tooling::newFrontendActionFactory(&ToolAction);
@@ -270,7 +246,9 @@
     }
   }
 
-  bool invokeAction(RefactoringActionSubcommand &Subcommand) {
+  bool invokeAction(RefactoringActionSubcommand &Subcommand,
+                    const CompilationDatabase &DB,
+                    ArrayRef<std::string> Sources) {
     // Find a set of matching rules.
     SmallVector<RefactoringActionRule *, 4> MatchingRules;
     llvm::StringSet<> MissingOptions;
@@ -296,7 +274,7 @@
 
     bool HasFailed = false;
     ClangRefactorConsumer Consumer;
-    if (foreachTranslationUnit(Subcommand, [&](ASTContext &AST) {
+    if (foreachTranslationUnit(DB, Sources, [&](ASTContext &AST) {
           RefactoringRuleContext Context(AST.getSourceManager());
           Context.setASTContext(AST);
 
@@ -340,12 +318,9 @@
 int main(int argc, const char **argv) {
   ClangRefactorTool Tool;
 
-  // FIXME: Use LibTooling's CommonOptions parser when subcommands are supported
-  // by it.
-  cl::HideUnrelatedOptions(opts::CommonRefactorOptions);
-  cl::ParseCommandLineOptions(
-      argc, argv, "Clang-based refactoring tool for C, C++ and Objective-C");
-  cl::PrintOptionValues();
+  CommonOptionsParser Options(
+      argc, argv, opts::CommonRefactorOptions, cl::ZeroOrMore,
+      "Clang-based refactoring tool for C, C++ and Objective-C");
 
   // Figure out which action is specified by the user. The user must specify
   // the action using a command-line subcommand, e.g. the invocation
@@ -367,17 +342,10 @@
   }
   RefactoringActionSubcommand &ActionCommand = **It;
 
-  ArrayRef<std::string> Sources = ActionCommand.getSources();
-  // When -no-dbs is used, at least one file (TU) must be given to any
-  // subcommand.
-  if (opts::NoDatabases && Sources.empty()) {
-    llvm::errs() << "error: must provide paths to the source files when "
-                    "'-no-dbs' is used\n";
-    return 1;
-  }
   if (ActionCommand.parseArguments())
     return 1;
-  if (Tool.invokeAction(ActionCommand))
+  if (Tool.invokeAction(ActionCommand, Options.getCompilations(),
+                        Options.getSourcePathList()))
     return 1;
 
   return 0;
Index: test/Refactor/tool-common-options.c
===================================================================
--- test/Refactor/tool-common-options.c
+++ test/Refactor/tool-common-options.c
@@ -1,6 +1,3 @@
 // RUN: not clang-refactor 2>&1 | FileCheck --check-prefix=MISSING_ACTION %s
 // MISSING_ACTION: error: no refactoring action given
 // MISSING_ACTION-NEXT: note: the following actions are supported:
-
-// RUN: not clang-refactor local-rename -no-dbs 2>&1 | FileCheck --check-prefix=MISSING_SOURCES %s
-// MISSING_SOURCES: error: must provide paths to the source files when '-no-dbs' is used
Index: test/Refactor/LocalRename/Field.cpp
===================================================================
--- test/Refactor/LocalRename/Field.cpp
+++ test/Refactor/LocalRename/Field.cpp
@@ -1,4 +1,4 @@
-// RUN: clang-refactor local-rename -selection=test:%s -no-dbs %s | FileCheck %s
+// RUN: clang-refactor local-rename -selection=test:%s %s -- | FileCheck %s
 
 class Baz {
   int /*range=*/Foo; // CHECK: =*/Bar;
Index: lib/Tooling/CommonOptionsParser.cpp
===================================================================
--- lib/Tooling/CommonOptionsParser.cpp
+++ lib/Tooling/CommonOptionsParser.cpp
@@ -84,24 +84,26 @@
 CommonOptionsParser::CommonOptionsParser(
     int &argc, const char **argv, cl::OptionCategory &Category,
     llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) {
-  static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
+  static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden,
+                            cl::sub(*cl::AllSubCommands));
 
   static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
-                                        cl::Optional, cl::cat(Category));
+                                        cl::Optional, cl::cat(Category),
+                                        cl::sub(*cl::AllSubCommands));
 
   static cl::list<std::string> SourcePaths(
       cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
-      cl::cat(Category));
+      cl::cat(Category), cl::sub(*cl::AllSubCommands));
 
   static cl::list<std::string> ArgsAfter(
       "extra-arg",
       cl::desc("Additional argument to append to the compiler command line"),
-      cl::cat(Category));
+      cl::cat(Category), cl::sub(*cl::AllSubCommands));
 
   static cl::list<std::string> ArgsBefore(
       "extra-arg-before",
       cl::desc("Additional argument to prepend to the compiler command line"),
-      cl::cat(Category));
+      cl::cat(Category), cl::sub(*cl::AllSubCommands));
 
   cl::HideUnrelatedOptions(Category);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to