vmiklos updated this revision to Diff 64204.

https://reviews.llvm.org/D21814

Files:
  clang-rename/tool/ClangRename.cpp
  test/clang-rename/ClassFindByName.cpp
  test/clang-rename/ClassReplacements.cpp
  test/clang-rename/ClassSimpleRenaming.cpp
  test/clang-rename/ClassTest.cpp
  test/clang-rename/ClassTestByName.cpp
  test/clang-rename/ClassTestReplacements.cpp
  test/clang-rename/ConstCastExpr.cpp
  test/clang-rename/ConstructExpr.cpp
  test/clang-rename/CtorDefTest.cpp
  test/clang-rename/CtorFindByDeclaration.cpp
  test/clang-rename/CtorFindByDefinition.cpp
  test/clang-rename/CtorInitializer.cpp
  test/clang-rename/CtorInitializerTest.cpp
  test/clang-rename/DeclRefExpr.cpp
  test/clang-rename/DtorDeclaration.cpp
  test/clang-rename/DtorDefTest.cpp
  test/clang-rename/DtorDefinition.cpp
  test/clang-rename/DynamicCastExpr.cpp
  test/clang-rename/Field.cpp
  test/clang-rename/FieldTest.cpp
  test/clang-rename/FunctionMacro.cpp
  test/clang-rename/MemberExprMacro.cpp
  test/clang-rename/Namespace.cpp
  test/clang-rename/NoNewName.cpp
  test/clang-rename/ReinterpretCastExpr.cpp
  test/clang-rename/StaticCastExpr.cpp
  test/clang-rename/VarTest.cpp
  test/clang-rename/Variable.cpp
  test/clang-rename/VariableMacro.cpp

Index: test/clang-rename/VariableMacro.cpp
===================================================================
--- test/clang-rename/VariableMacro.cpp
+++ test/clang-rename/VariableMacro.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=208 -new-name=Z %t.cpp -i --
+// RUN: clang-rename rename-at -offset=218 -new-name=Z %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 #define Y X // CHECK: #define Y Z
Index: test/clang-rename/Variable.cpp
===================================================================
--- test/clang-rename/Variable.cpp
+++ test/clang-rename/Variable.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=148 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=158 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 namespace A {
Index: test/clang-rename/VarTest.cpp
===================================================================
--- test/clang-rename/VarTest.cpp
+++ test/clang-rename/VarTest.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=150 -new-name=hector %t.cpp -i --
+// RUN: clang-rename rename-at -offset=160 -new-name=hector %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 namespace A { int foo;  // CHECK: int hector;
 }
Index: test/clang-rename/StaticCastExpr.cpp
===================================================================
--- test/clang-rename/StaticCastExpr.cpp
+++ test/clang-rename/StaticCastExpr.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=150 -new-name=X %t.cpp -i --
+// RUN: clang-rename rename-at -offset=160 -new-name=X %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Base {
 };
Index: test/clang-rename/ReinterpretCastExpr.cpp
===================================================================
--- test/clang-rename/ReinterpretCastExpr.cpp
+++ test/clang-rename/ReinterpretCastExpr.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=133 -new-name=X %t.cpp -i --
+// RUN: clang-rename rename-at -offset=143 -new-name=X %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Cla {
 public:
Index: test/clang-rename/NoNewName.cpp
===================================================================
--- test/clang-rename/NoNewName.cpp
+++ test/clang-rename/NoNewName.cpp
@@ -1,4 +1,4 @@
 // Check for an error while -new-name argument has not been passed to
 // clang-rename.
-// RUN: not clang-rename -offset=133 %s 2>&1 | FileCheck %s
+// RUN: not clang-rename rename-at -offset=133 %s 2>&1 | FileCheck %s
 // CHECK: clang-rename: no new name provided.
Index: test/clang-rename/Namespace.cpp
===================================================================
--- test/clang-rename/Namespace.cpp
+++ test/clang-rename/Namespace.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=143 -new-name=llvm %t.cpp -i --
+// RUN: clang-rename rename-at -offset=153 -new-name=llvm %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 namespace foo { // CHECK: namespace llvm {
Index: test/clang-rename/MemberExprMacro.cpp
===================================================================
--- test/clang-rename/MemberExprMacro.cpp
+++ test/clang-rename/MemberExprMacro.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=156 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=166 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Baz {
Index: test/clang-rename/FunctionMacro.cpp
===================================================================
--- test/clang-rename/FunctionMacro.cpp
+++ test/clang-rename/FunctionMacro.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=199 -new-name=macro_function %t.cpp -i --
+// RUN: clang-rename rename-at -offset=209 -new-name=macro_function %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 #define moo foo // CHECK: #define moo macro_function
Index: test/clang-rename/FieldTest.cpp
===================================================================
--- test/clang-rename/FieldTest.cpp
+++ test/clang-rename/FieldTest.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=150 -new-name=hector %t.cpp -i --
+// RUN: clang-rename rename-at -offset=160 -new-name=hector %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Cla
 {
Index: test/clang-rename/Field.cpp
===================================================================
--- test/clang-rename/Field.cpp
+++ test/clang-rename/Field.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=148 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=158 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Baz {
Index: test/clang-rename/DynamicCastExpr.cpp
===================================================================
--- test/clang-rename/DynamicCastExpr.cpp
+++ test/clang-rename/DynamicCastExpr.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=193 -new-name=X %t.cpp -i -- -frtti
+// RUN: clang-rename rename-at -offset=203 -new-name=X %t.cpp -i -- -frtti
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Base {
   virtual int getValue() const = 0;
Index: test/clang-rename/DtorDefinition.cpp
===================================================================
--- test/clang-rename/DtorDefinition.cpp
+++ test/clang-rename/DtorDefinition.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=219 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=229 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {     // CHECK: class Bar {
Index: test/clang-rename/DtorDefTest.cpp
===================================================================
--- test/clang-rename/DtorDefTest.cpp
+++ test/clang-rename/DtorDefTest.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=135 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=145 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Foo {
 public:
Index: test/clang-rename/DtorDeclaration.cpp
===================================================================
--- test/clang-rename/DtorDeclaration.cpp
+++ test/clang-rename/DtorDeclaration.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=175 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=185 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo { // CHECK: class Bar {
Index: test/clang-rename/DeclRefExpr.cpp
===================================================================
--- test/clang-rename/DeclRefExpr.cpp
+++ test/clang-rename/DeclRefExpr.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=161 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=171 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class C {
Index: test/clang-rename/CtorInitializerTest.cpp
===================================================================
--- test/clang-rename/CtorInitializerTest.cpp
+++ test/clang-rename/CtorInitializerTest.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=162 -new-name=hector %t.cpp -i --
+// RUN: clang-rename rename-at -offset=172 -new-name=hector %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class A
 {
Index: test/clang-rename/CtorInitializer.cpp
===================================================================
--- test/clang-rename/CtorInitializer.cpp
+++ test/clang-rename/CtorInitializer.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=163 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=173 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Baz {};
Index: test/clang-rename/CtorFindByDefinition.cpp
===================================================================
--- test/clang-rename/CtorFindByDefinition.cpp
+++ test/clang-rename/CtorFindByDefinition.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=212 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=222 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {   // CHECK: class Bar
Index: test/clang-rename/CtorFindByDeclaration.cpp
===================================================================
--- test/clang-rename/CtorFindByDeclaration.cpp
+++ test/clang-rename/CtorFindByDeclaration.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=174 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=184 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {   // CHECK: class Bar
Index: test/clang-rename/CtorDefTest.cpp
===================================================================
--- test/clang-rename/CtorDefTest.cpp
+++ test/clang-rename/CtorDefTest.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=133 -new-name=D %t.cpp -i --
+// RUN: clang-rename rename-at -offset=143 -new-name=D %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class C
 {
Index: test/clang-rename/ConstructExpr.cpp
===================================================================
--- test/clang-rename/ConstructExpr.cpp
+++ test/clang-rename/ConstructExpr.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=136 -new-name=Boo %t.cpp -i --
+// RUN: clang-rename rename-at -offset=146 -new-name=Boo %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {};         // CHECK: class Boo {};
Index: test/clang-rename/ConstCastExpr.cpp
===================================================================
--- test/clang-rename/ConstCastExpr.cpp
+++ test/clang-rename/ConstCastExpr.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=136 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=146 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {                         // CHECK: class Bar {
Index: test/clang-rename/ClassTestReplacements.cpp
===================================================================
--- test/clang-rename/ClassTestReplacements.cpp
+++ test/clang-rename/ClassTestReplacements.cpp
@@ -1,12 +1,9 @@
 // RUN: rm -rf %t
 // RUN: mkdir -p %t/fixes
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=256 -new-name=Hector -export-fixes=%t/fixes/clang-rename.yaml %t.cpp --
+// RUN: clang-rename rename-all -old-name=Cla -new-name=Hector -export-fixes=%t/fixes/clang-rename.yaml %t.cpp --
 // RUN: clang-apply-replacements %t
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Cla  // CHECK: class Hector
 {
 };
-
-// Use grep -FUbo 'Cla' <file> to get the correct offset of Cla when changing
-// this file.
Index: test/clang-rename/ClassTestByName.cpp
===================================================================
--- test/clang-rename/ClassTestByName.cpp
+++ test/clang-rename/ClassTestByName.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -old-name=Cla -new-name=Hector %t.cpp -i --
+// RUN: clang-rename rename-all -old-name=Cla -new-name=Hector %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Cla { // CHECK: class Hector
 };
Index: test/clang-rename/ClassTest.cpp
===================================================================
--- test/clang-rename/ClassTest.cpp
+++ test/clang-rename/ClassTest.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=138 -new-name=Hector %t.cpp -i --
+// RUN: clang-rename rename-at -offset=148 -new-name=Hector %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 class Cla  // CHECK: class Hector
 {
Index: test/clang-rename/ClassSimpleRenaming.cpp
===================================================================
--- test/clang-rename/ClassSimpleRenaming.cpp
+++ test/clang-rename/ClassSimpleRenaming.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=136 -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-at -offset=146 -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {};       // CHECK: class Bar
Index: test/clang-rename/ClassReplacements.cpp
===================================================================
--- test/clang-rename/ClassReplacements.cpp
+++ test/clang-rename/ClassReplacements.cpp
@@ -1,11 +1,8 @@
 // RUN: rm -rf %t
 // RUN: mkdir -p %t/fixes
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -offset=254 -new-name=Bar -export-fixes=%t/fixes/clang-rename.yaml %t.cpp --
+// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar -export-fixes=%t/fixes/clang-rename.yaml %t.cpp --
 // RUN: clang-apply-replacements %t
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {}; // CHECK: class Bar {};
-
-// Use grep -FUbo 'Foo' <file> to get the correct offset of Cla when changing
-// this file.
Index: test/clang-rename/ClassFindByName.cpp
===================================================================
--- test/clang-rename/ClassFindByName.cpp
+++ test/clang-rename/ClassFindByName.cpp
@@ -1,5 +1,5 @@
 // RUN: cat %s > %t.cpp
-// RUN: clang-rename -old-name=Foo -new-name=Bar %t.cpp -i --
+// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar %t.cpp -i --
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {         // CHECK: class Bar
Index: clang-rename/tool/ClangRename.cpp
===================================================================
--- clang-rename/tool/ClangRename.cpp
+++ clang-rename/tool/ClangRename.cpp
@@ -40,44 +40,45 @@
 
 using namespace llvm;
 
-cl::OptionCategory ClangRenameCategory("Clang-rename options");
+cl::OptionCategory ClangRenameAtCategory("clang-rename rename-at options");
+cl::OptionCategory ClangRenameAllCategory("clang-rename rename-all options");
 
 static cl::opt<std::string>
 NewName(
     "new-name",
     cl::desc("The new name to change the symbol to."),
-    cl::cat(ClangRenameCategory));
+    cl::cat(ClangRenameAtCategory), cl::cat(ClangRenameAllCategory));
 static cl::opt<unsigned>
 SymbolOffset(
     "offset",
     cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
-    cl::cat(ClangRenameCategory));
+    cl::cat(ClangRenameAtCategory));
 static cl::opt<std::string>
 OldName(
     "old-name",
     cl::desc("The fully qualified name of the symbol, if -offset is not used."),
-    cl::cat(ClangRenameCategory));
+    cl::cat(ClangRenameAllCategory));
 static cl::opt<bool>
 Inplace(
     "i",
     cl::desc("Overwrite edited <file>s."),
-    cl::cat(ClangRenameCategory));
+    cl::cat(ClangRenameAtCategory), cl::cat(ClangRenameAllCategory));
 static cl::opt<bool>
 PrintName(
     "pn",
     cl::desc("Print the found symbol's name prior to renaming to stderr."),
-    cl::cat(ClangRenameCategory));
+    cl::cat(ClangRenameAtCategory));
 static cl::opt<bool>
 PrintLocations(
     "pl",
     cl::desc("Print the locations affected by renaming to stderr."),
-    cl::cat(ClangRenameCategory));
+    cl::cat(ClangRenameAtCategory));
 static cl::opt<std::string>
 ExportFixes(
     "export-fixes",
     cl::desc("YAML file to store suggested fixes in."),
     cl::value_desc("filename"),
-    cl::cat(ClangRenameCategory));
+    cl::cat(ClangRenameAllCategory));
 
 #define CLANG_RENAME_VERSION "0.0.1"
 
@@ -87,14 +88,14 @@
 
 using namespace clang;
 
-const char RenameUsage[] = "A tool to rename symbols in C/C++ code.\n\
+const char RenameAtUsage[] = "A tool to rename symbols in C/C++ code.\n\
 clang-rename renames every occurrence of a symbol found at <offset> in\n\
 <source0>. If -i is specified, the edited files are overwritten to disk.\n\
 Otherwise, the results are written to stdout.\n";
 
-int main(int argc, const char **argv) {
-  cl::SetVersionPrinter(PrintVersion);
-  tooling::CommonOptionsParser OP(argc, argv, ClangRenameCategory, RenameUsage);
+/// \brief rename-at subcommand.
+int renameAtMain(int argc, const char **argv) {
+  tooling::CommonOptionsParser OP(argc, argv, ClangRenameAtCategory, RenameAtUsage);
 
   // Check the arguments for correctness.
 
@@ -133,6 +134,71 @@
   } else {
     ExitCode = Tool.run(Factory.get());
 
+    // Write every file to stdout. Right now we just barf the files without any
+    // indication of which files start where, other than that we print the files
+    // in the same order we see them.
+    LangOptions DefaultLangOptions;
+    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
+        new DiagnosticOptions();
+    TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts);
+    DiagnosticsEngine Diagnostics(
+        IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()),
+        &*DiagOpts, &DiagnosticPrinter, false);
+    auto &FileMgr = Tool.getFiles();
+    SourceManager Sources(Diagnostics, FileMgr);
+    Rewriter Rewrite(Sources, DefaultLangOptions);
+
+    Tool.applyAllReplacements(Rewrite);
+    for (const auto &File : Files) {
+      const auto *Entry = FileMgr.getFile(File);
+      auto ID = Sources.translateFile(Entry);
+      Rewrite.getEditBuffer(ID).write(outs());
+    }
+  }
+
+  exit(ExitCode);
+}
+
+const char RenameAllUsage[] = "A tool to rename symbols in C/C++ code.\n\
+clang-rename renames every occurrence of a symbol named <old-name>.\n";
+
+/// \brief rename-all subcommand.
+int renameAllMain(int argc, const char **argv) {
+  tooling::CommonOptionsParser OP(argc, argv, ClangRenameAllCategory, RenameAllUsage);
+
+  // Check the arguments for correctness.
+
+  if (NewName.empty()) {
+    errs() << "clang-rename: no new name provided.\n\n";
+    exit(1);
+  }
+
+  // Get the USRs.
+  auto Files = OP.getSourcePathList();
+  tooling::RefactoringTool Tool(OP.getCompilations(), Files);
+  rename::USRFindingAction USRAction(SymbolOffset, OldName);
+
+  // Find the USRs.
+  Tool.run(tooling::newFrontendActionFactory(&USRAction).get());
+  const auto &USRs = USRAction.getUSRs();
+  const auto &PrevName = USRAction.getUSRSpelling();
+
+  if (PrevName.empty()) {
+    // An error should have already been printed.
+    exit(1);
+  }
+
+  // Perform the renaming.
+  rename::RenamingAction RenameAction(NewName, PrevName, USRs,
+                                      Tool.getReplacements(), PrintLocations);
+  auto Factory = tooling::newFrontendActionFactory(&RenameAction);
+  int ExitCode;
+
+  if (Inplace) {
+    ExitCode = Tool.runAndSave(Factory.get());
+  } else {
+    ExitCode = Tool.run(Factory.get());
+
     if (!ExportFixes.empty()) {
       std::error_code EC;
       llvm::raw_fd_ostream OS(ExportFixes, EC, llvm::sys::fs::F_None);
@@ -177,3 +243,45 @@
 
   exit(ExitCode);
 }
+
+/// \brief Top level help.
+static int helpMain(int argc, const char *argv[]) {
+  errs() << "Usage: clang-rename {rename-at|rename-all} [OPTION]...\n\n"
+         << "A tool to rename symbols in C/C++ code.\n\n"
+         << "Subcommands:\n"
+         << "  rename-at:  Perform rename off of a location in a file.\n"
+         << "  rename-all: Perform rename of all symbols matching a fully qualified name.\n";
+  return 0;
+}
+
+/// \brief Top level version information.
+static int versionMain(int argc, const char *argv[]) {
+  cl::PrintVersionMessage();
+  return 0;
+}
+
+int main(int argc, const char **argv) {
+  cl::SetVersionPrinter(PrintVersion);
+
+  if (argc > 1) {
+    typedef int (*MainFunction)(int, const char *[]);
+    MainFunction Func = StringSwitch<MainFunction>(argv[1])
+      .Case("rename-at", renameAtMain)
+      .Case("rename-all", renameAllMain)
+      .Cases("-help", "--help", helpMain)
+      .Cases("-version", "--version", versionMain)
+      .Default(nullptr);
+
+    if (Func) {
+      std::string Invocation = std::string(argv[0]) + " " + argv[1];
+      argv[1] = Invocation.c_str();
+      return Func(argc - 1, argv + 1);
+    }
+  }
+
+  if (argc > 1) {
+    errs() << "clang-rename: unrecognized command: " << argv[1] << '\n';
+  }
+  helpMain(argc, argv);
+  return 1;
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to