omtcyfz created this revision.
omtcyfz added reviewers: alexfh, klimek, ioeric, bkramer.
omtcyfz added a subscriber: cfe-commits.

This patch basically creates `clang-refactor` binary and merges both 
`clang-rename rename-at` and `clang-rename rename-at` a.k.a. `clang-rename` 
into `clang-refactor rename` subcommand.

All USR processing routine is moved to `USREngine`, which should be reused by 
future potential submodules.

`clang-refactor` (as opposed to `clang-rename`) now uses LLVM policy about 
brackets around single line statements in `if`/`while`/...

Editor integrations are moved with minor changes, i.e. they are just named 
differently now.

Docs are updated.

The tool itself doesn't have to be perfect in the first iteration, so I would 
be really happy to push this one early enough so that everyone could start 
building modules on top of it. As soon as this one is landed more refactoring 
and cleanup patches are welcome. This also isn't about "the one true way how 
clang-refactor has to be designed". Thus said, consider this version of 
clang-refactor to be highly experimental.

https://reviews.llvm.org/D24192

Files:
  CMakeLists.txt
  TemplatedClassFunction.cpp
  clang-refactor/CMakeLists.txt
  clang-refactor/USREngine/CMakeLists.txt
  clang-refactor/USREngine/USRFinder.cpp
  clang-refactor/USREngine/USRFinder.h
  clang-refactor/USREngine/USRFindingAction.cpp
  clang-refactor/USREngine/USRFindingAction.h
  clang-refactor/USREngine/USRLocFinder.cpp
  clang-refactor/USREngine/USRLocFinder.h
  clang-refactor/driver/CMakeLists.txt
  clang-refactor/driver/ClangRefactorOptions.h
  clang-refactor/driver/Driver.cpp
  clang-refactor/driver/Rename.h
  clang-refactor/editor-integrations/CMakeLists.txt
  clang-refactor/editor-integrations/clang-refactor-rename.el
  clang-refactor/editor-integrations/clang-refactor-rename.py
  clang-refactor/modules/CMakeLists.txt
  clang-refactor/modules/rename/CMakeLists.txt
  clang-refactor/modules/rename/RenamingAction.cpp
  clang-refactor/modules/rename/RenamingAction.h
  clang-rename/CMakeLists.txt
  clang-rename/RenamingAction.cpp
  clang-rename/RenamingAction.h
  clang-rename/USRFinder.cpp
  clang-rename/USRFinder.h
  clang-rename/USRFindingAction.cpp
  clang-rename/USRFindingAction.h
  clang-rename/USRLocFinder.cpp
  clang-rename/USRLocFinder.h
  clang-rename/tool/CMakeLists.txt
  clang-rename/tool/ClangRename.cpp
  clang-rename/tool/clang-rename.el
  clang-rename/tool/clang-rename.py
  docs/clang-refactor/index.rst
  docs/clang-refactor/rename.rst
  docs/clang-rename.rst
  docs/index.rst
  test/CMakeLists.txt
  test/clang-refactor/rename/ClassAsTemplateArgument.cpp
  test/clang-refactor/rename/ClassFindByName.cpp
  test/clang-refactor/rename/ClassReplacements.cpp
  test/clang-refactor/rename/ClassSimpleRenaming.cpp
  test/clang-refactor/rename/ClassTestMulti.cpp
  test/clang-refactor/rename/ClassTestMultiByName.cpp
  test/clang-refactor/rename/ClassTestMultiByNameYAML.cpp
  test/clang-refactor/rename/ComplexFunctionOverride.cpp
  test/clang-refactor/rename/ComplicatedClassType.cpp
  test/clang-refactor/rename/Ctor.cpp
  test/clang-refactor/rename/CtorInitializer.cpp
  test/clang-refactor/rename/DeclRefExpr.cpp
  test/clang-refactor/rename/Field.cpp
  test/clang-refactor/rename/FunctionMacro.cpp
  test/clang-refactor/rename/FunctionOverride.cpp
  test/clang-refactor/rename/FunctionWithClassFindByName.cpp
  test/clang-refactor/rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml
  test/clang-refactor/rename/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml
  test/clang-refactor/rename/InvalidNewName.cpp
  test/clang-refactor/rename/MemberExprMacro.cpp
  test/clang-refactor/rename/Namespace.cpp
  test/clang-refactor/rename/NoNewName.cpp
  test/clang-refactor/rename/QualifiedNameNotFound.cpp
  test/clang-refactor/rename/TemplateClassInstantiation.cpp
  test/clang-refactor/rename/TemplateTypename.cpp
  test/clang-refactor/rename/UserDefinedConversion.cpp
  test/clang-refactor/rename/Variable.cpp
  test/clang-refactor/rename/VariableMacro.cpp
  test/clang-rename/ClassAsTemplateArgument.cpp
  test/clang-rename/ClassFindByName.cpp
  test/clang-rename/ClassReplacements.cpp
  test/clang-rename/ClassSimpleRenaming.cpp
  test/clang-rename/ClassTestMulti.cpp
  test/clang-rename/ClassTestMultiByName.cpp
  test/clang-rename/ClassTestMultiByNameYAML.cpp
  test/clang-rename/ComplexFunctionOverride.cpp
  test/clang-rename/ComplicatedClassType.cpp
  test/clang-rename/Ctor.cpp
  test/clang-rename/CtorInitializer.cpp
  test/clang-rename/DeclRefExpr.cpp
  test/clang-rename/Field.cpp
  test/clang-rename/FunctionMacro.cpp
  test/clang-rename/FunctionOverride.cpp
  test/clang-rename/FunctionWithClassFindByName.cpp
  test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml
  test/clang-rename/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml
  test/clang-rename/InvalidNewName.cpp
  test/clang-rename/InvalidOldName.cpp
  test/clang-rename/MemberExprMacro.cpp
  test/clang-rename/Namespace.cpp
  test/clang-rename/NoNewName.cpp
  test/clang-rename/TemplateClassInstantiation.cpp
  test/clang-rename/TemplateTypename.cpp
  test/clang-rename/UserDefinedConversion.cpp
  test/clang-rename/Variable.cpp
  test/clang-rename/VariableMacro.cpp
  unittests/CMakeLists.txt
  unittests/clang-rename/CMakeLists.txt
  unittests/clang-rename/USRLocFindingTest.cpp

Index: unittests/clang-rename/USRLocFindingTest.cpp
===================================================================
--- unittests/clang-rename/USRLocFindingTest.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "USRFindingAction.h"
-#include "clang/Tooling/Tooling.h"
-#include "gtest/gtest.h"
-#include <map>
-#include <set>
-#include <vector>
-
-namespace clang {
-namespace rename {
-namespace test {
-
-// Determines if the symbol group invariants hold. To recap, those invariants
-// are:
-//  (1) All symbols in the same symbol group share the same USR.
-//  (2) Two symbols from two different groups do not share the same USR.
-static void testOffsetGroups(const char *Code,
-                             const std::vector<std::vector<unsigned>> Groups) {
-  std::set<std::string> AllUSRs, CurrUSR;
-
-  for (const auto &Group : Groups) {
-    // Groups the invariants do not hold then the value of USR is also invalid,
-    // but at that point the test has already failed and USR ceases to be
-    // useful.
-    std::string USR;
-    for (const auto &Offset : Group) {
-      USRFindingAction Action(Offset, std::string());
-      auto Factory = tooling::newFrontendActionFactory(&Action);
-      EXPECT_TRUE(tooling::runToolOnCode(Factory->create(), Code));
-      const auto &USRs = Action.getUSRs();
-      EXPECT_EQ(1u, USRs.size());
-      USR = USRs[0];
-      CurrUSR.insert(USR);
-    }
-    EXPECT_EQ(1u, CurrUSR.size());
-    CurrUSR.clear();
-    AllUSRs.insert(USR);
-  }
-
-  EXPECT_EQ(Groups.size(), AllUSRs.size());
-}
-
-
-TEST(USRLocFinding, FindsVarUSR) {
-  const char VarTest[] = "\n\
-namespace A {\n\
-int foo;\n\
-}\n\
-int foo;\n\
-int bar = foo;\n\
-int baz = A::foo;\n\
-void fun1() {\n\
-  struct {\n\
-    int foo;\n\
-  } b = { 100 };\n\
-  int foo = 100;\n\
-  baz = foo;\n\
-  {\n\
-    extern int foo;\n\
-    baz = foo;\n\
-    foo = A::foo + baz;\n\
-    A::foo = b.foo;\n\
-  }\n\
- foo = b.foo;\n\
-}\n";
-  std::vector<std::vector<unsigned>> VarTestOffsets(3);
-  VarTestOffsets[0].push_back(19);
-  VarTestOffsets[0].push_back(63);
-  VarTestOffsets[0].push_back(205);
-  VarTestOffsets[0].push_back(223);
-  VarTestOffsets[1].push_back(30);
-  VarTestOffsets[1].push_back(45);
-  VarTestOffsets[1].push_back(172);
-  VarTestOffsets[1].push_back(187);
-  VarTestOffsets[2].push_back(129);
-  VarTestOffsets[2].push_back(148);
-  VarTestOffsets[2].push_back(242);
-
-  testOffsetGroups(VarTest, VarTestOffsets);
-}
-
-} // namespace test
-} // namespace rename
-} // namespace clang
Index: unittests/clang-rename/CMakeLists.txt
===================================================================
--- unittests/clang-rename/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  support
-  )
-
-get_filename_component(CLANG_RENAME_SOURCE_DIR
-  ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-rename REALPATH)
-include_directories(
-  ${CLANG_RENAME_SOURCE_DIR}
-  )
-
-add_extra_unittest(ClangRenameTests
-  USRLocFindingTest.cpp
-  ${CLANG_RENAME_SOURCE_DIR}/USRFinder.cpp
-  ${CLANG_RENAME_SOURCE_DIR}/USRFindingAction.cpp
-  )
-
-target_link_libraries(ClangRenameTests
-  clangAST
-  clangASTMatchers
-  clangBasic
-  clangFrontend
-  clangIndex
-  clangLex
-  clangTooling
-  )
Index: unittests/CMakeLists.txt
===================================================================
--- unittests/CMakeLists.txt
+++ unittests/CMakeLists.txt
@@ -6,7 +6,6 @@
 endfunction()
 
 add_subdirectory(clang-apply-replacements)
-add_subdirectory(clang-rename)
 add_subdirectory(clang-query)
 add_subdirectory(clang-tidy)
 add_subdirectory(include-fixer)
Index: test/clang-rename/NoNewName.cpp
===================================================================
--- test/clang-rename/NoNewName.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// 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
-// CHECK: clang-rename: for the -new-name option: must be specified
Index: test/clang-rename/InvalidOldName.cpp
===================================================================
--- test/clang-rename/InvalidOldName.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: not clang-rename rename-all -new-name=Foo -old-name=Bar %s -- 2>&1 | FileCheck %s
-// CHECK: clang-rename: could not find symbol Bar.
Index: test/clang-rename/InvalidNewName.cpp
===================================================================
--- test/clang-rename/InvalidNewName.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: not clang-rename -new-name=class -offset=133 %s 2>&1 | FileCheck %s
-// CHECK: ERROR: new name is not a valid identifier in C++17.
Index: test/clang-rename/ClassTestMultiByNameYAML.cpp
===================================================================
--- test/clang-rename/ClassTestMultiByNameYAML.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-class Foo1 { // CHECK: class Bar1
-};
-
-class Foo2 { // CHECK: class Bar2
-};
-
-// Test 1.
-// RUN: clang-rename rename-all -input %S/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml %s -- | sed 's,//.*,,' | FileCheck %s
-// Test 2.
-// RUN: clang-rename rename-all -input %S/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml %s -- | sed 's,//.*,,' | FileCheck %s
Index: test/clang-rename/ClassTestMultiByName.cpp
===================================================================
--- test/clang-rename/ClassTestMultiByName.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-class Foo1 { // CHECK: class Bar1
-};
-
-class Foo2 { // CHECK: class Bar2
-};
-
-// Test 1.
-// RUN: clang-rename rename-all -old-name=Foo1 -new-name=Bar1 -old-name=Foo2 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s
Index: test/clang-refactor/rename/VariableMacro.cpp
===================================================================
--- test/clang-refactor/rename/VariableMacro.cpp
+++ test/clang-refactor/rename/VariableMacro.cpp
@@ -11,11 +11,11 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=88 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=88 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=129 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=129 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=191 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=191 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/Variable.cpp
===================================================================
--- test/clang-refactor/rename/Variable.cpp
+++ test/clang-refactor/rename/Variable.cpp
@@ -20,13 +20,13 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=18 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=18 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=206 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=206 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=613 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=613 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 4.
-// RUN: clang-rename -offset=688 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=688 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/UserDefinedConversion.cpp
===================================================================
--- test/clang-refactor/rename/UserDefinedConversion.cpp
+++ test/clang-refactor/rename/UserDefinedConversion.cpp
@@ -18,9 +18,9 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=7 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=7 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=164 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=164 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/TemplateTypename.cpp
===================================================================
--- test/clang-refactor/rename/TemplateTypename.cpp
+++ test/clang-refactor/rename/TemplateTypename.cpp
@@ -14,11 +14,11 @@
 };
 
 // Test 1.
-// RUN: clang-rename -offset=19 -new-name=U %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=19 -new-name=U %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=126 -new-name=U %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=126 -new-name=U %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=392 -new-name=U %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=392 -new-name=U %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'T.*' <file>
Index: test/clang-refactor/rename/TemplateClassInstantiation.cpp
===================================================================
--- test/clang-refactor/rename/TemplateClassInstantiation.cpp
+++ test/clang-refactor/rename/TemplateClassInstantiation.cpp
@@ -32,11 +32,11 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=29 -new-name=Bar %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=29 -new-name=Bar %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=324 -new-name=Bar %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=324 -new-name=Bar %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=463 -new-name=Bar %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=463 -new-name=Bar %s -- -fno-delayed-template-parsing | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/QualifiedNameNotFound.cpp
===================================================================
--- /dev/null
+++ test/clang-refactor/rename/QualifiedNameNotFound.cpp
@@ -0,0 +1,2 @@
+// RUN: not clang-refactor rename  -new-name=Foo -qualified-name=Bar %s -- 2>&1 | FileCheck %s
+// CHECK: USREngine: could not find symbol Bar.
Index: test/clang-refactor/rename/NoNewName.cpp
===================================================================
--- /dev/null
+++ test/clang-refactor/rename/NoNewName.cpp
@@ -0,0 +1,4 @@
+// Check for an error while -new-name argument has not been passed to
+// clang-refactor rename.
+// RUN: not clang-refactor rename -offset=133 %s 2>&1 | FileCheck %s
+// CHECK: clang-refactor rename: -new-name or -input is required.
Index: test/clang-refactor/rename/Namespace.cpp
===================================================================
--- test/clang-refactor/rename/Namespace.cpp
+++ test/clang-refactor/rename/Namespace.cpp
@@ -7,7 +7,7 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=10 -new-name=clang %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=10 -new-name=clang %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/MemberExprMacro.cpp
===================================================================
--- test/clang-refactor/rename/MemberExprMacro.cpp
+++ test/clang-refactor/rename/MemberExprMacro.cpp
@@ -14,9 +14,9 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=26 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=26 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=155 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=155 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/InvalidNewName.cpp
===================================================================
--- /dev/null
+++ test/clang-refactor/rename/InvalidNewName.cpp
@@ -0,0 +1,2 @@
+// RUN: not clang-refactor rename -new-name=class -offset=133 %s 2>&1 | FileCheck %s
+// CHECK: ERROR: new name is not a valid identifier in C++17.
Index: test/clang-refactor/rename/FunctionWithClassFindByName.cpp
===================================================================
--- test/clang-refactor/rename/FunctionWithClassFindByName.cpp
+++ test/clang-refactor/rename/FunctionWithClassFindByName.cpp
@@ -9,4 +9,4 @@
   return 0;
 }
 
-// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename  -qualified-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
Index: test/clang-refactor/rename/FunctionOverride.cpp
===================================================================
--- test/clang-refactor/rename/FunctionOverride.cpp
+++ test/clang-refactor/rename/FunctionOverride.cpp
@@ -3,11 +3,11 @@
 class C : public B { void foo();  /* Test 3 */ }; // CHECK: class C : public B { void bar();
 
 // Test 1.
-// RUN: clang-rename -offset=23 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=23 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=116 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=116 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=209 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=209 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'foo.*' <file>
Index: test/clang-refactor/rename/FunctionMacro.cpp
===================================================================
--- test/clang-refactor/rename/FunctionMacro.cpp
+++ test/clang-refactor/rename/FunctionMacro.cpp
@@ -14,7 +14,7 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=68 -new-name=macro_function %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=68 -new-name=macro_function %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'foo.*' <file>
Index: test/clang-refactor/rename/Field.cpp
===================================================================
--- test/clang-refactor/rename/Field.cpp
+++ test/clang-refactor/rename/Field.cpp
@@ -7,9 +7,9 @@
 Baz::Baz() : Foo(0) /* Test 2 */ {}  // CHECK: Baz::Baz() : Bar(0)
 
 // Test 1.
-// RUN: clang-rename -offset=18 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=18 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=89 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=89 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/DeclRefExpr.cpp
===================================================================
--- test/clang-refactor/rename/DeclRefExpr.cpp
+++ test/clang-refactor/rename/DeclRefExpr.cpp
@@ -14,11 +14,11 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=31 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=31 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=152 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=152 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=271 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=271 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/CtorInitializer.cpp
===================================================================
--- test/clang-refactor/rename/CtorInitializer.cpp
+++ test/clang-refactor/rename/CtorInitializer.cpp
@@ -9,9 +9,9 @@
 Qux::Qux() : Foo() /* Test 2 */ {}    // CHECK: Qux::Qux() : Bar() /* Test 2 */ {}
 
 // Test 1.
-// RUN: clang-rename -offset=33 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=33 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=118 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=118 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/Ctor.cpp
===================================================================
--- test/clang-refactor/rename/Ctor.cpp
+++ test/clang-refactor/rename/Ctor.cpp
@@ -6,9 +6,9 @@
 Foo::Foo()  /* Test 2 */ {}   // CHECK: Bar::Bar()  /* Test 2 */ {}
 
 // Test 1.
-// RUN: clang-rename -offset=62 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=62 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=116 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=116 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/ComplicatedClassType.cpp
===================================================================
--- test/clang-refactor/rename/ComplicatedClassType.cpp
+++ test/clang-refactor/rename/ComplicatedClassType.cpp
@@ -45,19 +45,19 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=30 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=30 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=155 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=155 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=1133 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=1133 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
 // Test 4.
-// RUN: clang-rename -offset=1266 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=1266 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
 // Test 5.
-// RUN: clang-rename -offset=1402 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=1402 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
 // Test 6.
-// RUN: clang-rename -offset=1533 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=1533 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
 // Test 7.
-// RUN: clang-rename -offset=1665 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=1665 -new-name=Bar %s -- -frtti | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/ComplexFunctionOverride.cpp
===================================================================
--- test/clang-refactor/rename/ComplexFunctionOverride.cpp
+++ test/clang-refactor/rename/ComplexFunctionOverride.cpp
@@ -33,15 +33,15 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=26 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=26 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=109 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=109 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 3.
-// RUN: clang-rename -offset=201 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=201 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 4.
-// RUN: clang-rename -offset=293 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=293 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 5.
-// RUN: clang-rename -offset=385 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=385 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'foo.*' <file>
Index: test/clang-refactor/rename/ClassTestMultiByNameYAML.cpp
===================================================================
--- /dev/null
+++ test/clang-refactor/rename/ClassTestMultiByNameYAML.cpp
@@ -0,0 +1,10 @@
+class Foo1 { // CHECK: class Bar1
+};
+
+class Foo2 { // CHECK: class Bar2
+};
+
+// Test 1.
+// RUN: clang-refactor rename  -input %S/Inputs/ClassTestMultiByNameYAMLRenameAll.yaml %s -- | sed 's,//.*,,' | FileCheck %s
+// Test 2.
+// RUN: clang-refactor rename  -input %S/Inputs/ClassTestMultiByNameYAMLRenameAt.yaml %s -- | sed 's,//.*,,' | FileCheck %s
Index: test/clang-refactor/rename/ClassTestMultiByName.cpp
===================================================================
--- /dev/null
+++ test/clang-refactor/rename/ClassTestMultiByName.cpp
@@ -0,0 +1,8 @@
+class Foo1 { // CHECK: class Bar1
+};
+
+class Foo2 { // CHECK: class Bar2
+};
+
+// Test 1.
+// RUN: clang-refactor rename -qualified-name=Foo1 -new-name=Bar1 -qualified-name=Foo2 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s
Index: test/clang-refactor/rename/ClassTestMulti.cpp
===================================================================
--- test/clang-refactor/rename/ClassTestMulti.cpp
+++ test/clang-refactor/rename/ClassTestMulti.cpp
@@ -5,7 +5,7 @@
 };
 
 // Test 1.
-// RUN: clang-rename rename-all -offset=6 -new-name=Bar1 -offset=76 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename  -offset=6 -new-name=Bar1 -offset=76 -new-name=Bar2 %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/ClassSimpleRenaming.cpp
===================================================================
--- test/clang-refactor/rename/ClassSimpleRenaming.cpp
+++ test/clang-refactor/rename/ClassSimpleRenaming.cpp
@@ -6,9 +6,9 @@
 void Foo::foo(int x) /* Test 2 */ {}  // CHECK: void Bar::foo(int x) /* Test 2 */ {}
 
 // Test 1.
-// RUN: clang-rename -offset=6 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=6 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=109 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=109 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/clang-refactor/rename/ClassReplacements.cpp
===================================================================
--- test/clang-refactor/rename/ClassReplacements.cpp
+++ test/clang-refactor/rename/ClassReplacements.cpp
@@ -1,7 +1,7 @@
 // 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-refactor rename -offset=273 -new-name=Bar -export-fixes=%t/fixes/clang-refactor-rename.yaml %t.cpp --
 // RUN: clang-apply-replacements %t
 // RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
Index: test/clang-refactor/rename/ClassFindByName.cpp
===================================================================
--- test/clang-refactor/rename/ClassFindByName.cpp
+++ test/clang-refactor/rename/ClassFindByName.cpp
@@ -7,4 +7,4 @@
 }
 
 // Test 1.
-// RUN: clang-rename rename-all -old-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -qualified-name=Foo -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
Index: test/clang-refactor/rename/ClassAsTemplateArgument.cpp
===================================================================
--- test/clang-refactor/rename/ClassAsTemplateArgument.cpp
+++ test/clang-refactor/rename/ClassAsTemplateArgument.cpp
@@ -13,9 +13,9 @@
 }
 
 // Test 1.
-// RUN: clang-rename -offset=7 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=7 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 // Test 2.
-// RUN: clang-rename -offset=215 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
+// RUN: clang-refactor rename -offset=215 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s
 
 // To find offsets after modifying the file, use:
 //   grep -Ubo 'Foo.*' <file>
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt
+++ test/CMakeLists.txt
@@ -44,7 +44,7 @@
   clang-apply-replacements
   clang-include-fixer
   clang-query
-  clang-rename
+  clang-refactor
   clang-reorder-fields
   clang-tidy
   find-all-symbols
Index: docs/index.rst
===================================================================
--- docs/index.rst
+++ docs/index.rst
@@ -24,7 +24,7 @@
    include-fixer
    modularize
    pp-trace
-   clang-rename
+   clang-refactor/index
 
 
 Doxygen Documentation
Index: docs/clang-rename.rst
===================================================================
--- docs/clang-rename.rst
+++ /dev/null
@@ -1,193 +0,0 @@
-============
-Clang-Rename
-============
-
-.. contents::
-
-See also:
-
-.. toctree::
-   :maxdepth: 1
-
-
-:program:`clang-rename` is a C++ refactoring tool. Its purpose is to perform
-efficient renaming actions in large-scale projects such as renaming classes,
-functions, variables, arguments, namespaces etc.
-
-The tool is in a very early development stage, so you might encounter bugs and
-crashes. Submitting reports with information about how to reproduce the issue
-to `the LLVM bugtracker <https://llvm.org/bugs>`_ will definitely help the
-project. If you have any ideas or suggestions, you might want to put a feature
-request there.
-
-Using Clang-Rename
-==================
-
-:program:`clang-rename` is a `LibTooling
-<http://clang.llvm.org/docs/LibTooling.html>`_-based tool, and it's easier to
-work with if you set up a compile command database for your project (for an
-example of how to do this see `How To Setup Tooling For LLVM
-<http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html>`_). You can also
-specify compilation options on the command line after `--`:
-
-.. code-block:: console
-
-  $ clang-rename -offset=42 -new-name=foo test.cpp -- -Imy_project/include -DMY_DEFINES ...
-
-
-To get an offset of a symbol in a file run
-
-.. code-block:: console
-
-  $ grep -FUbo 'foo' file.cpp
-
-
-The tool currently supports renaming actions inside a single translation unit
-only. It is planned to extend the tool's functionality to support multi-TU
-renaming actions in the future.
-
-:program:`clang-rename` also aims to be easily integrated into popular text
-editors, such as Vim and Emacs, and improve the workflow of users.
-
-Although a command line interface exists, it is highly recommended to use the
-text editor interface instead for better experience.
-
-You can also identify one or more symbols to be renamed by giving the fully qualified
-name:
-
-.. code-block:: console
-
-  $ clang-rename rename-all -old-name=foo -new-name=bar test.cpp
-
-
-Alternatively, old name / new name pairs can be put into a YAML file:
-
-.. code-block:: yaml
-
-  ---
-  - OldName:        foo
-    NewName:        bar
-  ...
-
-
-That way you can avoid spelling out all the names as command line arguments:
-
-.. code-block:: console
-
-  $ clang-rename rename-all -input=test.yaml test.cpp
-
-
-The YAML file also supports offsets:
-
-.. code-block:: yaml
-
-  ---
-  - Offset:         42
-    NewName:        foo
-  ...
-
-
-:program:`clang-rename` offers the following options:
-
-.. code-block:: console
-
-  $ clang-rename -help
-  Usage: clang-rename {rename-at|rename-all} [OPTION]...
-
-  A tool to rename symbols in C/C++ code.
-
-  Subcommands:
-    rename-at:  Perform rename off of a location in a file. (This is the default.)
-    rename-all: Perform rename of all symbols matching one or more fully qualified names.
-
-
-.. code-block:: console
-
-  $ clang-rename rename-at -help
-  OVERVIEW: A tool to rename symbols in C/C++ code.
-  clang-rename renames every occurrence of a symbol found at <offset> in
-  <source0>. If -i is specified, the edited files are overwritten to disk.
-  Otherwise, the results are written to stdout.
-  
-  USAGE: clang-rename rename-at [subcommand] [options] <source0> [... <sourceN>]
-  
-  OPTIONS:
-  
-  Generic Options:
-  
-    -help                      - Display available options (-help-hidden for more)
-    -help-list                 - Display list of available options (-help-list-hidden for more)
-    -version                   - Display the version of this program
-
-  clang-rename rename-at options:
-
-    -export-fixes=<filename>   - YAML file to store suggested fixes in.
-    -extra-arg=<string>        - Additional argument to append to the compiler command line.
-    -extra-arg-before=<string> - Additional argument to prepend to the compiler command line.
-    -i                         - Overwrite edited <file>s.
-    -new-name=<string>         - The new name to change the symbol to.
-    -offset=<uint>             - Locates the symbol by offset as opposed to <line>:<column>.
-    -p=<string>                - Build path.
-    -pl                        - Print the locations affected by renaming to stderr.
-    -pn                        - Print the found symbol's name prior to renaming to stderr.
-
-
-.. code-block:: console
-
-  $ clang-rename rename-all -help
-  OVERVIEW: A tool to rename symbols in C/C++ code.
-  clang-rename renames every occurrence of a symbol named <old-name>.
-
-  USAGE: clang-rename rename-all [subcommand] [options] <source0> [... <sourceN>]
-
-  OPTIONS:
-
-  Generic Options:
-
-    -help                      - Display available options (-help-hidden for more).
-    -help-list                 - Display list of available options (-help-list-hidden for more).
-    -version                   - Display the version of this program.
-
-  clang-rename rename-all options:
-
-    -export-fixes=<filename>   - YAML file to store suggested fixes in.
-    -extra-arg=<string>        - Additional argument to append to the compiler command line.
-    -extra-arg-before=<string> - Additional argument to prepend to the compiler command line.
-    -i                         - Overwrite edited <file>s.
-    -input=<string>            - YAML file to load oldname-newname pairs from.
-    -new-name=<string>         - The new name to change the symbol to.
-    -offset=<uint>             - Locates the symbol by offset as opposed to <line>:<column>.
-    -old-name=<string>         - The fully qualified name of the symbol, if -offset is not used.
-    -p=<string>                - Build path.
-
-
-Vim Integration
-===============
-
-You can call :program:`clang-rename` directly from Vim! To set up
-:program:`clang-rename` integration for Vim see
-`clang-rename/tool/clang-rename.py
-<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-rename/tool/clang-rename.py>`_.
-
-Please note that **you have to save all buffers, in which the replacement will
-happen before running the tool**.
-
-Once installed, you can point your cursor to symbols you want to rename, press
-`<leader>cr` and type new desired name. The `<leader> key
-<http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_3)#Map_leader>`_
-is a reference to a specific key defined by the mapleader variable and is bound
-to backslash by default.
-
-Emacs Integration
-=================
-
-You can also use :program:`clang-rename` while using Emacs! To set up
-:program:`clang-rename` integration for Emacs see
-`clang-rename/tool/clang-rename.el
-<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-rename/tool/clang-rename.el>`_.
-
-Once installed, you can point your cursor to symbols you want to rename, press
-`M-X`, type `clang-rename` and new desired name.
-
-Please note that **you have to save all buffers, in which the replacement will
-happen before running the tool**.
Index: docs/clang-refactor/rename.rst
===================================================================
--- /dev/null
+++ docs/clang-refactor/rename.rst
@@ -0,0 +1,112 @@
+======
+Rename
+======
+
+.. contents::
+
+See also:
+
+.. toctree::
+   :maxdepth: 1
+
+
+`rename` is a module of `clang-refactor`, a C++ "master" refactoring tool. Its
+purpose is to perform efficient renaming actions in large-scale projects such as
+renaming classes, functions, variables, arguments, namespaces etc.
+
+The tool is in a very early development stage, so you might encounter bugs and
+crashes. Submitting reports with information about how to reproduce the issue
+to `the LLVM bugtracker <https://llvm.org/bugs>`_ will definitely help the
+project. If you have any ideas or suggestions, you might want to put a feature
+request there.
+
+Using Rename module
+===================
+
+:program:`clang-refactor` is a `LibTooling
+<http://clang.llvm.org/docs/LibTooling.html>`_-based tool, and it's easier to
+work with if you set up a compile command database for your project (for an
+example of how to do this see `How To Setup Tooling For LLVM
+<http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html>`_). You can also
+specify compilation options on the command line after `--`:
+
+.. code-block:: console
+
+  $ clang-refactor rename -offset=42 -new-name=foo test.cpp -- -Imy_project/include -DMY_DEFINES ...
+
+
+To get an offset of a symbol in a file run
+
+.. code-block:: console
+
+  $ grep -FUbo 'foo' file.cpp
+
+
+The tool currently supports renaming actions inside a single translation unit
+only. It is planned to extend the tool's functionality to support multi-TU
+renaming actions in the future.
+
+:program:`clang-refactor` also aims to be easily integrated into popular text
+editors, such as Vim and Emacs, and improve the workflow of users.
+
+Although a command line interface exists, it is highly recommended to use the
+text editor interface instead for better experience.
+
+You can also identify one or more symbols to be renamed by giving the fully
+qualified name:
+
+.. code-block:: console
+
+  $ clang-refactor rename-old-name=foo -new-name=bar test.cpp
+
+
+Alternatively, { offset | old name } -> new name pairs can be put into a YAML
+file:
+
+.. code-block:: yaml
+
+  ---
+  - OldName:        foo
+    NewName:        bar
+  - Offset:         42
+    NewName:        baz
+  ...
+
+
+That way you can avoid spelling out all the names as command line arguments:
+
+.. code-block:: console
+
+  $ clang-refactor rename -input=test.yaml test.cpp
+
+
+Vim Integration
+===============
+
+You can call :program:`clang-refactor rename` directly from Vim! To set up
+:program:`clang-refactor-rename` integration for Vim see
+`clang-refactor/editor-integrations/clang-refactor-rename.py
+<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-refactor/editor-integrations/clang-refactor-rename.py>`_.
+
+Please note that **you have to save all buffers, in which the replacement will
+happen before running the tool**.
+
+Once installed, you can point your cursor to symbols you want to rename, press
+`<leader>cr` and type new desired name. The `<leader> key
+<http://vim.wikia.com/wiki/Mapping_keys_in_Vim_-_Tutorial_(Part_3)#Map_leader>`_
+is a reference to a specific key defined by the mapleader variable and is bound
+to backslash by default.
+
+Emacs Integration
+=================
+
+You can also use :program:`clang-refactor` while using Emacs! To set up
+:program:`clang-refactor rename` integration for Emacs see
+`clang-refactor/editor-integrations/clang-refactor-rename.el
+<http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/clang-refactor/editor-integrations/clang-refactor-rename.el>`_.
+
+Once installed, you can point your cursor to symbols you want to rename, press
+`M-X`, type `clang-refactor rename` and new desired name.
+
+Please note that **you have to save all buffers, in which the replacement will
+happen before running the tool**.
Index: docs/clang-refactor/index.rst
===================================================================
--- /dev/null
+++ docs/clang-refactor/index.rst
@@ -0,0 +1,32 @@
+==============
+Clang-Refactor
+==============
+
+.. contents::
+
+See also:
+
+.. toctree::
+   :maxdepth: 1
+
+:program:`clang-refactor` is a Clang-based refactoring "master" tool. It is home
+for refactoring submodules, such as `rename`. :program:`clang-refactor` is only
+a prototype at the moment and most of its parts may significantly change.
+
+.. code-block:: console
+
+  $ clang-refactor --help
+
+  USAGE: clang-refactor [subcommand] [options] <source0> [... <sourceN>]
+
+  Subcommands:
+    rename: rename the symbol found at <offset>s or by <qualified-name>s in <source0>.
+
+=======
+Modules
+=======
+
+.. toctree::
+   :maxdepth: 1
+
+   rename.rst
Index: clang-rename/tool/ClangRename.cpp
===================================================================
--- clang-rename/tool/ClangRename.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-//===--- tools/extra/clang-rename/ClangRename.cpp - Clang rename tool -----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file implements a clang-rename tool that automatically finds and
-/// renames symbols in C++ code.
-///
-//===----------------------------------------------------------------------===//
-
-#include "../RenamingAction.h"
-#include "../USRFindingAction.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Tooling/CommonOptionsParser.h"
-#include "clang/Tooling/Refactoring.h"
-#include "clang/Tooling/ReplacementsYaml.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/YAMLTraits.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdlib>
-#include <string>
-#include <system_error>
-
-using namespace llvm;
-
-using namespace clang;
-
-cl::OptionCategory ClangRenameAtCategory("clang-rename rename-at options");
-cl::OptionCategory ClangRenameAllCategory("clang-rename rename-all options");
-
-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";
-
-const char RenameAllUsage[] = "A tool to rename symbols in C/C++ code.\n\
-clang-rename performs renaming given pairs {offset | old-name} -> new-name.\n";
-
-static int renameAtMain(int argc, const char *argv[]);
-static int renameAllMain(int argc, const char *argv[]);
-static int helpMain(int argc, const char *argv[]);
-
-/// \brief An oldname -> newname rename.
-struct RenameAllInfo {
-  std::string OldName;
-  unsigned Offset = 0;
-  std::string NewName;
-};
-
-LLVM_YAML_IS_SEQUENCE_VECTOR(RenameAllInfo)
-
-namespace llvm {
-namespace yaml {
-
-/// \brief Specialized MappingTraits to describe how a RenameAllInfo is
-/// (de)serialized.
-template <> struct MappingTraits<RenameAllInfo> {
-  static void mapping(IO &IO, RenameAllInfo &Info) {
-    IO.mapOptional("OldName", Info.OldName);
-    IO.mapOptional("Offset", Info.Offset);
-    IO.mapRequired("NewName", Info.NewName);
-  }
-};
-
-} // end namespace yaml
-} // end namespace llvm
-
-int main(int argc, const char **argv) {
-  if (argc > 1) {
-    using MainFunction = std::function<int(int, const char *[])>;
-    MainFunction Func = StringSwitch<MainFunction>(argv[1])
-                            .Case("rename-at", renameAtMain)
-                            .Case("rename-all", renameAllMain)
-                            .Cases("-help", "--help", helpMain)
-                            .Default(nullptr);
-
-    if (Func) {
-      std::string Invocation = std::string(argv[0]) + " " + argv[1];
-      argv[1] = Invocation.c_str();
-      return Func(argc - 1, argv + 1);
-    } else {
-      return renameAtMain(argc, argv);
-    }
-  }
-
-  helpMain(argc, argv);
-  return 1;
-}
-
-int subcommandMain(bool isRenameAll, int argc, const char **argv) {
-  cl::OptionCategory *Category = nullptr;
-  const char *Usage = nullptr;
-  if (isRenameAll) {
-    Category = &ClangRenameAllCategory;
-    Usage = RenameAllUsage;
-  } else {
-    Category = &ClangRenameAtCategory;
-    Usage = RenameAtUsage;
-  }
-
-  cl::list<std::string> NewNames(
-      "new-name", cl::desc("The new name to change the symbol to."),
-      (isRenameAll ? cl::ZeroOrMore : cl::Required), cl::cat(*Category));
-  cl::list<unsigned> SymbolOffsets(
-      "offset",
-      cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
-      (isRenameAll ? cl::ZeroOrMore : cl::Required), cl::cat(*Category));
-  cl::list<std::string> OldNames(
-      "old-name",
-      cl::desc(
-          "The fully qualified name of the symbol, if -offset is not used."),
-      (isRenameAll ? cl::ZeroOrMore : cl::Optional),
-      cl::cat(ClangRenameAllCategory));
-  cl::opt<bool> Inplace("i", cl::desc("Overwrite edited <file>s."),
-                        cl::cat(*Category));
-  cl::opt<bool> PrintName(
-      "pn",
-      cl::desc("Print the found symbol's name prior to renaming to stderr."),
-      cl::cat(ClangRenameAtCategory));
-  cl::opt<bool> PrintLocations(
-      "pl", cl::desc("Print the locations affected by renaming to stderr."),
-      cl::cat(ClangRenameAtCategory));
-  cl::opt<std::string> ExportFixes(
-      "export-fixes", cl::desc("YAML file to store suggested fixes in."),
-      cl::value_desc("filename"), cl::cat(*Category));
-  cl::opt<std::string> Input(
-      "input", cl::desc("YAML file to load oldname-newname pairs from."),
-      cl::Optional, cl::cat(ClangRenameAllCategory));
-
-  tooling::CommonOptionsParser OP(argc, argv, *Category, Usage);
-
-  if (!Input.empty()) {
-    // Populate OldNames and NewNames from a YAML file.
-    ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
-        llvm::MemoryBuffer::getFile(Input);
-    if (!Buffer) {
-      errs() << "clang-rename: failed to read " << Input << ": "
-             << Buffer.getError().message() << "\n";
-      return 1;
-    }
-
-    std::vector<RenameAllInfo> Infos;
-    llvm::yaml::Input YAML(Buffer.get()->getBuffer());
-    YAML >> Infos;
-    for (const auto &Info : Infos) {
-      if (!Info.OldName.empty())
-        OldNames.push_back(Info.OldName);
-      else
-        SymbolOffsets.push_back(Info.Offset);
-      NewNames.push_back(Info.NewName);
-    }
-  }
-
-  // Check the arguments for correctness.
-
-  if (NewNames.empty()) {
-    errs() << "clang-rename: either -new-name or -input is required.\n\n";
-    exit(1);
-  }
-
-  // Check if NewNames is a valid identifier in C++17.
-  for (const auto &NewName : NewNames) {
-    LangOptions Options;
-    Options.CPlusPlus = true;
-    Options.CPlusPlus1z = true;
-    IdentifierTable Table(Options);
-    auto NewNameTokKind = Table.get(NewName).getTokenID();
-    if (!tok::isAnyIdentifier(NewNameTokKind)) {
-      errs() << "ERROR: new name is not a valid identifier in C++17.\n\n";
-      exit(1);
-    }
-  }
-
-  if (!OldNames.empty() && OldNames.size() != NewNames.size()) {
-    errs() << "clang-rename: number of old names (" << OldNames.size()
-           << ") do not equal to number of new names (" << NewNames.size()
-           << ").\n\n";
-    cl::PrintHelpMessage();
-    exit(1);
-  }
-
-  if (!SymbolOffsets.empty() && SymbolOffsets.size() != NewNames.size()) {
-    errs() << "clang-rename: number of symbol offsets (" << SymbolOffsets.size()
-           << ") do not equal to number of new names (" << NewNames.size()
-           << ").\n\n";
-    cl::PrintHelpMessage();
-    exit(1);
-  }
-
-  std::vector<std::vector<std::string>> USRList;
-  std::vector<std::string> PrevNames;
-  auto Files = OP.getSourcePathList();
-  tooling::RefactoringTool Tool(OP.getCompilations(), Files);
-  unsigned Count = OldNames.size() ? OldNames.size() : SymbolOffsets.size();
-  for (unsigned I = 0; I < Count; ++I) {
-    unsigned SymbolOffset = SymbolOffsets.empty() ? 0 : SymbolOffsets[I];
-    const std::string &OldName = OldNames.empty() ? std::string() : OldNames[I];
-
-    // Get the USRs.
-    rename::USRFindingAction USRAction(SymbolOffset, OldName);
-
-    // Find the USRs.
-    Tool.run(tooling::newFrontendActionFactory(&USRAction).get());
-    const auto &USRs = USRAction.getUSRs();
-    USRList.push_back(USRs);
-    const auto &PrevName = USRAction.getUSRSpelling();
-    PrevNames.push_back(PrevName);
-
-    if (PrevName.empty()) {
-      // An error should have already been printed.
-      exit(1);
-    }
-
-    if (PrintName) {
-      errs() << "clang-rename: found name: " << PrevName << '\n';
-    }
-  }
-
-  // Perform the renaming.
-  rename::RenamingAction RenameAction(NewNames, PrevNames, USRList,
-                                      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);
-      if (EC) {
-        llvm::errs() << "Error opening output file: " << EC.message() << '\n';
-        exit(1);
-      }
-
-      // Export replacements.
-      tooling::TranslationUnitReplacements TUR;
-      const auto &FileToReplacements = Tool.getReplacements();
-      for (const auto &Entry : FileToReplacements)
-        TUR.Replacements.insert(TUR.Replacements.end(), Entry.second.begin(),
-                                Entry.second.end());
-
-      yaml::Output YAML(OS);
-      YAML << TUR;
-      OS.close();
-      exit(0);
-    }
-
-    // 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);
-}
-
-/// \brief Top level help.
-/// FIXME It would be better if this could be auto-generated.
-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. (This "
-            "is the default.)\n"
-            "  rename-all: Perform rename of all symbols matching one or more "
-            "fully qualified names.\n";
-  return 0;
-}
-
-static int renameAtMain(int argc, const char *argv[]) {
-  return subcommandMain(false, argc, argv);
-}
-
-static int renameAllMain(int argc, const char *argv[]) {
-  return subcommandMain(true, argc, argv);
-}
Index: clang-rename/tool/CMakeLists.txt
===================================================================
--- clang-rename/tool/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-add_clang_executable(clang-rename ClangRename.cpp)
-
-target_link_libraries(clang-rename
-  clangBasic
-  clangFrontend
-  clangRename
-  clangRewrite
-  clangTooling
-  clangToolingCore
-  )
-
-install(TARGETS clang-rename RUNTIME DESTINATION bin)
-
-install(PROGRAMS clang-rename.py
-  DESTINATION share/clang
-  COMPONENT clang-rename)
-install(PROGRAMS clang-rename.el
-  DESTINATION share/clang
-  COMPONENT clang-rename)
Index: clang-rename/USRFindingAction.h
===================================================================
--- clang-rename/USRFindingAction.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//===--- tools/extra/clang-rename/USRFindingAction.h - Clang rename tool --===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Provides an action to find all relevant USRs at a point.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H
-
-#include "clang/Frontend/FrontendAction.h"
-
-namespace clang {
-class ASTConsumer;
-class CompilerInstance;
-class NamedDecl;
-
-namespace rename {
-
-struct USRFindingAction {
-  USRFindingAction(unsigned Offset, const std::string &Name)
-      : SymbolOffset(Offset), OldName(Name) {}
-  std::unique_ptr<ASTConsumer> newASTConsumer();
-
-  // \brief get the spelling of the USR(s) as it would appear in source files.
-  const std::string &getUSRSpelling() { return SpellingName; }
-
-  const std::vector<std::string> &getUSRs() { return USRs; }
-
-private:
-  unsigned SymbolOffset;
-  std::string OldName;
-  std::string SpellingName;
-  std::vector<std::string> USRs;
-};
-
-} // namespace rename
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDING_ACTION_H
Index: clang-refactor/modules/rename/RenamingAction.h
===================================================================
--- clang-refactor/modules/rename/RenamingAction.h
+++ clang-refactor/modules/rename/RenamingAction.h
@@ -1,4 +1,4 @@
-//===--- tools/extra/clang-rename/RenamingAction.h - Clang rename tool ----===//
+//===--- tools/extra/clang-refactor/RenamingAction.h ----------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -21,7 +21,8 @@
 class ASTConsumer;
 class CompilerInstance;
 
-namespace rename {
+namespace clang_refactor {
+namespace rename_module {
 
 class RenamingAction {
 public:
@@ -41,7 +42,9 @@
   std::map<std::string, tooling::Replacements> &FileToReplaces;
   bool PrintLocations;
 };
-}
-}
+
+} // namespace rename_module
+} // namespace clang_refactor
+} // namespace clang
 
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_RENAMING_ACTION_H
Index: clang-refactor/modules/rename/RenamingAction.cpp
===================================================================
--- clang-refactor/modules/rename/RenamingAction.cpp
+++ clang-refactor/modules/rename/RenamingAction.cpp
@@ -1,4 +1,4 @@
-//===--- tools/extra/clang-rename/RenamingAction.cpp - Clang rename tool --===//
+//===--- tools/extra/clang-refactor/RenamingAction.cpp --------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -30,7 +30,8 @@
 using namespace llvm;
 
 namespace clang {
-namespace rename {
+namespace clang_refactor {
+namespace rename_module {
 
 class RenamingASTConsumer : public ASTConsumer {
 public:
@@ -65,8 +66,9 @@
     for (const auto &Loc : RenamingCandidates) {
       if (PrintLocations) {
         FullSourceLoc FullLoc(Loc, SourceMgr);
-        errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc)
-               << ":" << FullLoc.getSpellingLineNumber() << ":"
+        errs() << "clang-refactor rename: renamed at: "
+               << SourceMgr.getFilename(Loc) << ":"
+               << FullLoc.getSpellingLineNumber() << ":"
                << FullLoc.getSpellingColumnNumber() << "\n";
       }
       // FIXME: better error handling.
@@ -90,5 +92,6 @@
                                                 FileToReplaces, PrintLocations);
 }
 
-} // namespace rename
+} // namespace rename_module
+} // namespace clang_refactor
 } // namespace clang
Index: clang-refactor/modules/rename/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-refactor/modules/rename/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(LLVM_LINK_COMPONENTS Support)
+
+add_clang_library(clangRefactorRenameModule
+  RenamingAction.cpp
+
+  LINK_LIBS
+  clangAST
+  clangBasic
+  clangFrontend
+  clangToolingCore
+
+  clangRefactorUSREngine
+  )
Index: clang-refactor/modules/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-refactor/modules/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(rename)
Index: clang-refactor/editor-integrations/clang-refactor-rename.py
===================================================================
--- clang-refactor/editor-integrations/clang-refactor-rename.py
+++ clang-refactor/editor-integrations/clang-refactor-rename.py
@@ -1,15 +1,16 @@
 '''
-Minimal clang-rename integration with Vim.
+Minimal clang-refactor rename integration with Vim.
 
 Before installing make sure one of the following is satisfied:
 
-* clang-rename is in your PATH
-* `g:clang_rename_path` in ~/.vimrc points to valid clang-rename executable
-* `binary` in clang-rename.py points to valid to clang-rename executable
+* clang-refactor is in your PATH
+* `g:clang_rename_path` in ~/.vimrc points to valid clang-refactor executable
+* `binary` in clang-refactor rename.py points to valid to clang-refactor
+executable
 
 To install, simply put this into your ~/.vimrc
 
-    noremap <leader>cr :pyf <path-to>/clang-rename.py<cr>
+    noremap <leader>cr :pyf <path-to>/clang-refactor-rename.py<cr>
 
 IMPORTANT NOTE: Before running the tool, make sure you saved the file.
 
@@ -23,11 +24,11 @@
 import sys
 
 def main():
-    binary = 'clang-rename'
+    binary = 'clang-refactor'
     if vim.eval('exists("g:clang_rename_path")') == "1":
         binary = vim.eval('g:clang_rename_path')
 
-    # Get arguments for clang-rename binary.
+    # Get arguments for clang-refactor binary.
     offset = int(vim.eval('line2byte(line("."))+col(".")')) - 2
     if offset < 0:
         print >> sys.stderr, '''Couldn\'t determine cursor position.
@@ -38,9 +39,10 @@
     new_name_request_message = 'type new name:'
     new_name = vim.eval("input('{}\n')".format(new_name_request_message))
 
-    # Call clang-rename.
+    # Call clang-refactor rename module.
     command = [binary,
                filename,
+               'rename',
                '-i',
                '-offset', str(offset),
                '-new-name', str(new_name)]
Index: clang-refactor/editor-integrations/clang-refactor-rename.el
===================================================================
--- clang-refactor/editor-integrations/clang-refactor-rename.el
+++ clang-refactor/editor-integrations/clang-refactor-rename.el
@@ -1,44 +1,44 @@
-;;; clang-rename.el --- Renames every occurrence of a symbol found at <offset>.
+;;; clang-refactor-rename.el --- Renames symbols found at <offset>.
 
 ;; Keywords: tools, c
 
 ;;; Commentary:
 
-;; To install clang-rename.el make sure the directory of this file is in your
-;; 'load-path' and add
+;; To install clang-refactor-rename.el make sure the directory of this file is
+;; in your 'load-path' and add
 ;;
-;;   (require 'clang-rename)
+;;   (require 'clang-refactor-rename)
 ;;
 ;; to your .emacs configuration.
 
 ;;; Code:
 
-(defcustom clang-rename-binary "clang-rename"
-  "Path to clang-rename executable."
+(defcustom clang-refactor "clang-refactor"
+  "Path to clang-refactor executable."
   :type 'hook
   :options '(turn-on-auto-fill flyspell-mode)
   :group 'wp)
 
-(defun clang-rename (new-name)
-  "Rename all instances of the symbol at the point using clang-rename"
+(defun clang-refactor-rename (new-name)
+  "Rename all instances of the symbol at the point using clang-refactor rename"
   (interactive "sEnter a new name: ")
   (let (;; Emacs offset is 1-based.
         (offset (- (point) 1))
         (orig-buf (current-buffer))
         (file-name (buffer-file-name)))
 
     (let ((rename-command
           (format "bash -f -c '%s -offset=%s -new-name=%s -i %s'"
-                               clang-rename-binary offset new-name file-name)))
-          (message (format "Running clang-rename command %s" rename-command))
-          ;; Run clang-rename via bash.
+                               clang-refactor-binary offset new-name file-name)))
+          (message (format "Running clang-refactor command %s" rename-command))
+          ;; Run clang-refactor via bash.
           (shell-command rename-command)
           ;; Reload buffer.
           (revert-buffer t t)
     )
   )
 )
 
-(provide 'clang-rename)
+(provide 'clang-refactor)
 
-;;; clang-rename.el ends here
+;;; clang-refactor.el ends here
Index: clang-refactor/editor-integrations/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-refactor/editor-integrations/CMakeLists.txt
@@ -0,0 +1,6 @@
+install(PROGRAMS clang-refactor-rename.py
+  DESTINATION share/clang
+  COMPONENT clang-refactor)
+install(PROGRAMS clang-refactor-rename.el
+  DESTINATION share/clang
+  COMPONENT clang-refactor)
Index: clang-refactor/driver/Rename.h
===================================================================
--- /dev/null
+++ clang-refactor/driver/Rename.h
@@ -0,0 +1,203 @@
+//===--- tools/extra/clang-refactor/Rename.h - rename module driver -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements driver of rename module of clang-refactor.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_RENAME_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_RENAME_H
+
+#include "USRFindingAction.h"
+#include "rename/RenamingAction.h"
+#include "ClangRefactorOptions.h"
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/ReplacementsYaml.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdlib>
+#include <string>
+#include <system_error>
+
+using namespace llvm;
+using namespace clang;
+
+/// \brief An oldname -> newname rename.
+struct RenameAllInfo {
+  unsigned Offset = 0;
+  std::string OldName;
+  std::string NewName;
+};
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(RenameAllInfo)
+
+namespace llvm {
+namespace yaml {
+
+/// \brief Specialized MappingTraits to describe how a RenameAllInfo is
+/// (de)serialized.
+template <> struct MappingTraits<RenameAllInfo> {
+  static void mapping(IO &IO, RenameAllInfo &Info) {
+    IO.mapOptional("Offset", Info.Offset);
+    IO.mapOptional("OldName", Info.OldName);
+    IO.mapRequired("NewName", Info.NewName);
+  }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+namespace clang {
+namespace clang_refactor {
+namespace rename_module {
+
+int RenameModuleMain(int argc, const char **argv) {
+  tooling::CommonOptionsParser OP(argc, argv, ClangRefactorRenameCategory);
+
+  if (!Input.empty()) {
+    // Populate QualifiedNames and NewNames from a YAML file.
+    ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
+        llvm::MemoryBuffer::getFile(Input);
+    if (!Buffer) {
+      errs() << "clang-refactor rename: failed to read " << Input << ": "
+             << Buffer.getError().message() << "\n";
+      return 1;
+    }
+
+    std::vector<RenameAllInfo> Infos;
+    llvm::yaml::Input YAML(Buffer.get()->getBuffer());
+    YAML >> Infos;
+    for (const auto &Info : Infos) {
+      if (!Info.OldName.empty())
+        QualifiedNames.push_back(Info.OldName);
+      else
+        SymbolOffsets.push_back(Info.Offset);
+      NewNames.push_back(Info.NewName);
+    }
+  }
+
+  // Check the arguments for correctness.
+  if (NewNames.empty()) {
+    errs() << "clang-refactor rename: -new-name or -input is required.\n\n";
+    exit(1);
+  }
+
+  // Check if NewNames is a valid identifier in C++17.
+  LangOptions Options;
+  Options.CPlusPlus = true;
+  Options.CPlusPlus1z = true;
+  IdentifierTable Table(Options);
+  for (const auto &NewName : NewNames) {
+    auto NewNameTokKind = Table.get(NewName).getTokenID();
+    if (!tok::isAnyIdentifier(NewNameTokKind)) {
+      errs() << "ERROR: new name is not a valid identifier in C++17.\n\n";
+      exit(1);
+    }
+  }
+
+  if (SymbolOffsets.size() + QualifiedNames.size() != NewNames.size()) {
+    errs() << "clang-refactor rename: number of symbol offsets("
+           << SymbolOffsets.size() << ") + number of qualified names ("
+           << QualifiedNames.size() << ") must be equal to number of new names("
+           << NewNames.size() << ").\n\n";
+    cl::PrintHelpMessage();
+    exit(1);
+  }
+
+  auto Files = OP.getSourcePathList();
+  tooling::RefactoringTool Tool(OP.getCompilations(), Files);
+  USRFindingAction FindingAction(SymbolOffsets, QualifiedNames);
+  Tool.run(tooling::newFrontendActionFactory(&FindingAction).get());
+  const std::vector<std::vector<std::string>> &USRList =
+      FindingAction.getUSRList();
+  const std::vector<std::string> &PrevNames = FindingAction.getUSRSpellings();
+  if (PrintName) {
+    for (const auto &PrevName : PrevNames) {
+      outs() << "clang-refactor rename found name: " << PrevName << '\n';
+    }
+  }
+
+  // Perform the renaming.
+  RenamingAction RenameAction(NewNames, PrevNames, USRList,
+                              Tool.getReplacements(), PrintLocations);
+  std::unique_ptr<tooling::FrontendActionFactory> 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);
+      if (EC) {
+        llvm::errs() << "Error opening output file: " << EC.message() << '\n';
+        exit(1);
+      }
+
+      // Export replacements.
+      tooling::TranslationUnitReplacements TUR;
+      const auto &FileToReplacements = Tool.getReplacements();
+      for (const auto &Entry : FileToReplacements)
+        TUR.Replacements.insert(TUR.Replacements.end(), Entry.second.begin(),
+                                Entry.second.end());
+
+      yaml::Output YAML(OS);
+      YAML << TUR;
+      OS.close();
+      exit(0);
+    }
+
+    // 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);
+}
+
+} // namespace rename_module
+} // namespace clang_refactor
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_RENAME_H
Index: clang-refactor/driver/Driver.cpp
===================================================================
--- /dev/null
+++ clang-refactor/driver/Driver.cpp
@@ -0,0 +1,53 @@
+//===---- tools/extra/clang-refactor/Driver.cpp - clang-refactor driver ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  \file This file implements clang-refactor driver.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Rename.h"
+
+#include "llvm/ADT/StringSwitch.h"
+
+#include <functional>
+#include <string>
+
+using namespace clang;
+using namespace llvm;
+
+const char HelpMessage[] =
+    "USAGE: clang-refactor [subcommand] [options] <source0> [... <sourceN>]\n"
+    "\n"
+    "Subcommands:\n"
+    "  rename: rename the symbol found at <offset>s or by <qualified-name>s in "
+    "<source0>.\n";
+
+static int printHelpMessage(int argc, const char *argv[]) {
+  outs() << HelpMessage;
+  return 0;
+}
+
+int main(int argc, const char **argv) {
+  if (argc > 1) {
+    using MainFunction = std::function<int(int, const char *[])>;
+    MainFunction Func =
+        StringSwitch<MainFunction>(argv[1])
+            .Cases("-help", "--help", printHelpMessage)
+            .Case("rename", clang_refactor::rename_module::RenameModuleMain)
+            .Default(nullptr);
+    if (Func) {
+      std::string Invocation = std::string(argv[0]) + " " + argv[1];
+      argv[1] = Invocation.c_str();
+      return Func(argc - 1, argv + 1);
+    }
+  }
+
+  printHelpMessage(argc, argv);
+  return 0;
+}
Index: clang-refactor/driver/ClangRefactorOptions.h
===================================================================
--- /dev/null
+++ clang-refactor/driver/ClangRefactorOptions.h
@@ -0,0 +1,67 @@
+//===--- tools/extra/clang-refactor/ClangRefactorOptions.h ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines common options for clang-refactor subtools.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/CommonOptionsParser.h"
+
+#ifndef CLANG_REFACTOR_OPTIONS_H
+#define CLANG_REFACTOR_OPTIONS_H
+
+using namespace llvm;
+
+namespace clang {
+namespace clang_refactor {
+
+// FIXME: Adjust libTooling so that these options would be displayed, too.
+static cl::OptionCategory
+    ClangRefactorCommonOptions("clang-refactor common options");
+
+static cl::list<unsigned> SymbolOffsets(
+    "offset",
+    cl::desc("Locates the symbol by offset as opposed to <line>:<column>."),
+    cl::ZeroOrMore, cl::cat(ClangRefactorCommonOptions));
+static cl::opt<bool> Inplace("i", cl::desc("Overwrite edited <file>s."),
+                      cl::cat(ClangRefactorCommonOptions));
+static cl::list<std::string>
+    QualifiedNames("qualified-name",
+                   cl::desc("The fully qualified name of the symbol."),
+                   cl::ZeroOrMore, cl::cat(ClangRefactorCommonOptions));
+
+namespace rename_module {
+
+static cl::OptionCategory
+    ClangRefactorRenameCategory("clang-refactor rename options");
+
+static cl::list<std::string>
+    NewNames("new-name", cl::desc("The new name to change the symbol to."),
+             cl::ZeroOrMore, cl::cat(ClangRefactorRenameCategory));
+static cl::opt<bool> PrintName(
+    "pn",
+    cl::desc("Print the found symbol's name prior to renaming to stderr."),
+    cl::cat(ClangRefactorRenameCategory));
+static cl::opt<bool> PrintLocations(
+    "pl", cl::desc("Print the locations affected by renaming to stderr."),
+    cl::cat(ClangRefactorRenameCategory));
+static cl::opt<std::string> ExportFixes(
+    "export-fixes", cl::desc("YAML file to store suggested fixes in."),
+    cl::value_desc("filename"), cl::cat(ClangRefactorRenameCategory));
+static cl::opt<std::string>
+    Input("input", cl::desc("YAML file to load oldname-newname pairs from."),
+          cl::Optional, cl::cat(ClangRefactorRenameCategory));
+
+} // namespace rename_module
+
+} // namespace clang_refactor
+} // namespace clang
+
+#endif // CLANG_REFACTOR_OPTIONS_H
Index: clang-refactor/driver/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-refactor/driver/CMakeLists.txt
@@ -0,0 +1,18 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+add_clang_executable(clang-refactor
+  Driver.cpp
+  )
+
+target_link_libraries(clang-refactor
+  clangAST
+  clangBasic
+  clangFrontend
+  clangTooling
+
+  clangRefactorRenameModule
+
+  clangRefactorUSREngine
+  )
Index: clang-refactor/USREngine/USRLocFinder.h
===================================================================
--- clang-refactor/USREngine/USRLocFinder.h
+++ clang-refactor/USREngine/USRLocFinder.h
@@ -1,4 +1,4 @@
-//===--- tools/extra/clang-rename/USRLocFinder.h - Clang rename tool ------===//
+//===--- tools/extra/clang-refactor/USRLocFinder.h - USREngine ------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -22,14 +22,14 @@
 #include <vector>
 
 namespace clang {
-namespace rename {
+namespace clang_refactor {
 
 // FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
 std::vector<SourceLocation>
 getLocationsOfUSRs(const std::vector<std::string> &USRs,
                    llvm::StringRef PrevName, Decl *Decl);
 
-} // namespace rename
+} // namespace clang_refactor
 } // namespace clang
 
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_LOC_FINDER_H
Index: clang-refactor/USREngine/USRLocFinder.cpp
===================================================================
--- clang-refactor/USREngine/USRLocFinder.cpp
+++ clang-refactor/USREngine/USRLocFinder.cpp
@@ -1,4 +1,4 @@
-//===--- tools/extra/clang-rename/USRLocFinder.cpp - Clang rename tool ----===//
+//===--- tools/extra/clang-refactor/USRLocFinder.cpp - USREngine ----------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -26,7 +26,7 @@
 using namespace llvm;
 
 namespace clang {
-namespace rename {
+namespace clang_refactor {
 
 namespace {
 // \brief This visitor recursively searches for all instances of a USR in a
@@ -44,23 +44,20 @@
 
   bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
     for (const auto *Initializer : ConstructorDecl->inits()) {
-      if (!Initializer->isWritten()) {
+      if (!Initializer->isWritten())
         // Ignore implicit initializers.
         continue;
-      }
       if (const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
-        if (USRSet.find(getUSRForDecl(FieldDecl)) != USRSet.end()) {
+        if (USRSet.find(getUSRForDecl(FieldDecl)) != USRSet.end())
           LocationsFound.push_back(Initializer->getSourceLocation());
-        }
       }
     }
     return true;
   }
 
   bool VisitNamedDecl(const NamedDecl *Decl) {
-    if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end()) {
+    if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end())
       checkAndAddLocation(Decl->getLocation());
-    }
     return true;
   }
 
@@ -92,15 +89,14 @@
 
   bool VisitTypeLoc(const TypeLoc Loc) {
     if (USRSet.find(getUSRForDecl(Loc.getType()->getAsCXXRecordDecl())) !=
-        USRSet.end()) {
+        USRSet.end())
       checkAndAddLocation(Loc.getBeginLoc());
-    }
+
     if (const auto *TemplateTypeParm =
             dyn_cast<TemplateTypeParmType>(Loc.getType())) {
       if (USRSet.find(getUSRForDecl(TemplateTypeParm->getDecl())) !=
-          USRSet.end()) {
+          USRSet.end())
         checkAndAddLocation(Loc.getBeginLoc());
-      }
     }
     return true;
   }
@@ -118,9 +114,8 @@
     while (NameLoc) {
       const NamespaceDecl *Decl =
           NameLoc.getNestedNameSpecifier()->getAsNamespace();
-      if (Decl && USRSet.find(getUSRForDecl(Decl)) != USRSet.end()) {
+      if (Decl && USRSet.find(getUSRForDecl(Decl)) != USRSet.end())
         checkAndAddLocation(NameLoc.getLocalBeginLoc());
-      }
       NameLoc = NameLoc.getPrefix();
     }
   }
@@ -134,11 +129,10 @@
         Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),
                              Context.getSourceManager(), Context.getLangOpts());
     size_t Offset = TokenName.find(PrevName);
-    if (Offset != StringRef::npos) {
+    if (Offset != StringRef::npos)
       // The token of the source location we find actually has the old
       // name.
       LocationsFound.push_back(BeginLoc.getLocWithOffset(Offset));
-    }
   }
 
   const std::set<std::string> USRSet;
@@ -154,11 +148,10 @@
   USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());
   Visitor.TraverseDecl(Decl);
   NestedNameSpecifierLocFinder Finder(Decl->getASTContext());
-  for (const auto &Location : Finder.getNestedNameSpecifierLocations()) {
+  for (const auto &Location : Finder.getNestedNameSpecifierLocations())
     Visitor.handleNestedNameSpecifierLoc(Location);
-  }
   return Visitor.getLocationsFound();
 }
 
-} // namespace rename
+} // namespace clang_refactor
 } // namespace clang
Index: clang-refactor/USREngine/USRFindingAction.h
===================================================================
--- /dev/null
+++ clang-refactor/USREngine/USRFindingAction.h
@@ -0,0 +1,50 @@
+//===--- tools/extra/clang-refactor/USRFindingAction.h - USREngine --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Provides an action to find all relevant USRs at a point.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_USRENGINE_USRFINDINGACTION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_USRENGINE_USRFINDINGACTION_H
+
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/Frontend/FrontendAction.h"
+
+#include <string>
+#include <vector>
+
+namespace clang {
+class ASTConsumer;
+class CompilerInstance;
+class NamedDecl;
+
+namespace clang_refactor {
+
+struct USRFindingAction {
+  USRFindingAction(ArrayRef<unsigned> SymbolOffsets,
+                   ArrayRef<std::string> QualifiedNames)
+      : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames) {}
+  std::unique_ptr<ASTConsumer> newASTConsumer();
+
+  const std::vector<std::string> &getUSRSpellings() { return SpellingNames; }
+  const std::vector<std::vector<std::string>> &getUSRList() { return USRList; }
+
+private:
+  std::vector<unsigned> SymbolOffsets;
+  std::vector<std::string> QualifiedNames;
+  std::vector<std::string> SpellingNames;
+  std::vector<std::vector<std::string>> USRList;
+};
+
+} // namespace clang_refactor
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REFACTOR_USRENGINE_USRFINDINGACTION_H
Index: clang-refactor/USREngine/USRFindingAction.cpp
===================================================================
--- clang-refactor/USREngine/USRFindingAction.cpp
+++ clang-refactor/USREngine/USRFindingAction.cpp
@@ -1,4 +1,4 @@
-//===--- tools/extra/clang-rename/USRFindingAction.cpp - Clang rename tool ===//
+//===--- tools/extra/clang-refactor/USRFindingAction.cpp - USREngine ------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -18,6 +18,7 @@
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/FileManager.h"
@@ -30,50 +31,44 @@
 #include "clang/Tooling/Tooling.h"
 #include <algorithm>
 #include <set>
-#include <string>
-#include <vector>
 
 using namespace llvm;
 
 namespace clang {
-namespace rename {
+namespace clang_refactor {
 
 namespace {
 // \brief NamedDeclFindingConsumer should delegate finding USRs of given Decl to
 // AdditionalUSRFinder. AdditionalUSRFinder adds USRs of ctor and dtor if given
 // Decl refers to class and adds USRs of all overridden methods if Decl refers
 // to virtual method.
 class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
 public:
-  explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context,
-                               std::vector<std::string> *USRs)
-      : FoundDecl(FoundDecl), Context(Context), USRs(USRs) {}
+  explicit AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context)
+      : FoundDecl(FoundDecl), Context(Context) {}
 
-  void Find() {
+  std::vector<std::string> Find() {
     // Fill OverriddenMethods and PartialSpecs storages.
     TraverseDecl(Context.getTranslationUnitDecl());
     if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
       addUSRsOfOverridenFunctions(MethodDecl);
-      for (const auto &OverriddenMethod : OverriddenMethods) {
-        if (checkIfOverriddenFunctionAscends(OverriddenMethod)) {
+      for (const auto &OverriddenMethod : OverriddenMethods)
+        if (checkIfOverriddenFunctionAscends(OverriddenMethod))
           USRSet.insert(getUSRForDecl(OverriddenMethod));
-        }
-      }
     } else if (const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
       handleCXXRecordDecl(RecordDecl);
     } else if (const auto *TemplateDecl =
                    dyn_cast<ClassTemplateDecl>(FoundDecl)) {
       handleClassTemplateDecl(TemplateDecl);
     } else {
       USRSet.insert(getUSRForDecl(FoundDecl));
     }
-    USRs->insert(USRs->end(), USRSet.begin(), USRSet.end());
+    return std::vector<std::string>(USRSet.begin(), USRSet.end());
   }
 
   bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
-    if (MethodDecl->isVirtual()) {
+    if (MethodDecl->isVirtual())
       OverriddenMethods.push_back(MethodDecl);
-    }
     return true;
   }
 
@@ -87,117 +82,126 @@
   void handleCXXRecordDecl(const CXXRecordDecl *RecordDecl) {
     RecordDecl = RecordDecl->getDefinition();
     if (const auto *ClassTemplateSpecDecl =
-            dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl)) {
+            dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl))
       handleClassTemplateDecl(ClassTemplateSpecDecl->getSpecializedTemplate());
-    }
+
     addUSRsOfCtorDtors(RecordDecl);
   }
 
   void handleClassTemplateDecl(const ClassTemplateDecl *TemplateDecl) {
-    for (const auto *Specialization : TemplateDecl->specializations()) {
+    for (const auto *Specialization : TemplateDecl->specializations())
       addUSRsOfCtorDtors(Specialization);
-    }
-    for (const auto *PartialSpec : PartialSpecs) {
-      if (PartialSpec->getSpecializedTemplate() == TemplateDecl) {
+
+    for (const auto *PartialSpec : PartialSpecs)
+      if (PartialSpec->getSpecializedTemplate() == TemplateDecl)
         addUSRsOfCtorDtors(PartialSpec);
-      }
-    }
     addUSRsOfCtorDtors(TemplateDecl->getTemplatedDecl());
   }
 
   void addUSRsOfCtorDtors(const CXXRecordDecl *RecordDecl) {
     RecordDecl = RecordDecl->getDefinition();
-    for (const auto *CtorDecl : RecordDecl->ctors()) {
+    for (const auto *CtorDecl : RecordDecl->ctors())
       USRSet.insert(getUSRForDecl(CtorDecl));
-    }
     USRSet.insert(getUSRForDecl(RecordDecl->getDestructor()));
     USRSet.insert(getUSRForDecl(RecordDecl));
   }
 
   void addUSRsOfOverridenFunctions(const CXXMethodDecl *MethodDecl) {
     USRSet.insert(getUSRForDecl(MethodDecl));
-    for (const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
+    for (const auto &OverriddenMethod : MethodDecl->overridden_methods())
       // Recursively visit each OverridenMethod.
       addUSRsOfOverridenFunctions(OverriddenMethod);
-    }
   }
 
   bool checkIfOverriddenFunctionAscends(const CXXMethodDecl *MethodDecl) {
     for (const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
-      if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end()) {
+      if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end())
         return true;
-      }
       return checkIfOverriddenFunctionAscends(OverriddenMethod);
     }
     return false;
   }
 
   const Decl *FoundDecl;
   ASTContext &Context;
-  std::vector<std::string> *USRs;
   std::set<std::string> USRSet;
   std::vector<const CXXMethodDecl *> OverriddenMethods;
   std::vector<const ClassTemplatePartialSpecializationDecl *> PartialSpecs;
 };
 } // namespace
 
-struct NamedDeclFindingConsumer : public ASTConsumer {
-  void HandleTranslationUnit(ASTContext &Context) override {
-    const SourceManager &SourceMgr = Context.getSourceManager();
-    // The file we look for the USR in will always be the main source file.
+class NamedDeclFindingConsumer : public ASTConsumer {
+public:
+  explicit NamedDeclFindingConsumer(
+      ArrayRef<unsigned> SymbolOffsets, ArrayRef<std::string> QualifiedNames,
+      std::vector<std::string> &SpellingNames,
+      std::vector<std::vector<std::string>> &USRList)
+      : SymbolOffsets(SymbolOffsets), QualifiedNames(QualifiedNames),
+        SpellingNames(SpellingNames), USRList(USRList) {
+  }
+
+private:
+  void FindSymbol(ASTContext &Context, const SourceManager &SourceMgr,
+                  unsigned SymbolOffset, const std::string &QualifiedName) {
     const SourceLocation Point =
         SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID())
             .getLocWithOffset(SymbolOffset);
+
     if (!Point.isValid())
       return;
     const NamedDecl *FoundDecl = nullptr;
-    if (OldName.empty()) {
+
+    if (QualifiedName.empty())
       FoundDecl = getNamedDeclAt(Context, Point);
-    } else {
-      FoundDecl = getNamedDeclFor(Context, OldName);
-    }
+    else
+      FoundDecl = getNamedDeclFor(Context, QualifiedName);
+
     if (FoundDecl == nullptr) {
-      if (OldName.empty()) {
+      if (QualifiedName.empty()) {
         FullSourceLoc FullLoc(Point, SourceMgr);
-        errs() << "clang-rename: could not find symbol at "
+        errs() << "clang-refactor rename: could not find symbol at "
                << SourceMgr.getFilename(Point) << ":"
                << FullLoc.getSpellingLineNumber() << ":"
                << FullLoc.getSpellingColumnNumber() << " (offset "
                << SymbolOffset << ").\n";
-      } else
-        errs() << "clang-rename: could not find symbol " << OldName << ".\n";
+        exit(1);
+      } else {
+        errs() << "USREngine: could not find symbol " << QualifiedName << ".\n";
+        exit(1);
+      }
       return;
     }
 
-    // If FoundDecl is a constructor or destructor, we want to instead take the
-    // Decl of the corresponding class.
-    if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl)) {
+    // If FoundDecl is a constructor or destructor, we want to instead take
+    // the Decl of the corresponding class.
+    if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(FoundDecl))
       FoundDecl = CtorDecl->getParent();
-    } else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl)) {
+    else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(FoundDecl))
       FoundDecl = DtorDecl->getParent();
-    }
-    *SpellingName = FoundDecl->getNameAsString();
 
-    AdditionalUSRFinder Finder(FoundDecl, Context, USRs);
-    Finder.Find();
+    SpellingNames.push_back(FoundDecl->getNameAsString());
+    AdditionalUSRFinder Finder(FoundDecl, Context);
+    USRList.push_back(Finder.Find());
+  }
+
+  void HandleTranslationUnit(ASTContext &Context) override {
+    const SourceManager &SourceMgr = Context.getSourceManager();
+    for (unsigned Offset : SymbolOffsets)
+      FindSymbol(Context, SourceMgr, Offset, "");
+    for (const std::string &QualifiedName : QualifiedNames)
+      FindSymbol(Context, SourceMgr, 0, QualifiedName);
   }
 
-  unsigned SymbolOffset;
-  std::string OldName;
-  std::string *SpellingName;
-  std::vector<std::string> *USRs;
+  ArrayRef<unsigned> SymbolOffsets;
+  ArrayRef<std::string> QualifiedNames;
+  std::vector<std::string> &SpellingNames;
+  std::vector<std::vector<std::string>> &USRList;
 };
 
 std::unique_ptr<ASTConsumer> USRFindingAction::newASTConsumer() {
-  std::unique_ptr<NamedDeclFindingConsumer> Consumer(
-      new NamedDeclFindingConsumer);
-  SpellingName = "";
-  Consumer->SymbolOffset = SymbolOffset;
-  Consumer->OldName = OldName;
-  Consumer->USRs = &USRs;
-  Consumer->SpellingName = &SpellingName;
-  return std::move(Consumer);
+  return llvm::make_unique<NamedDeclFindingConsumer>(
+      SymbolOffsets, QualifiedNames, SpellingNames, USRList);
 }
 
-} // namespace rename
+} // namespace clang_refactor
 } // namespace clang
Index: clang-refactor/USREngine/USRFinder.h
===================================================================
--- clang-refactor/USREngine/USRFinder.h
+++ clang-refactor/USREngine/USRFinder.h
@@ -1,4 +1,4 @@
-//===--- tools/extra/clang-rename/USRFinder.h - Clang rename tool ---------===//
+//===--- tools/extra/clang-refactor/USRFinder.h - USREngine ---------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -12,6 +12,7 @@
 /// code.
 ///
 //===----------------------------------------------------------------------===//
+
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_RENAME_USR_FINDER_H
 
@@ -29,7 +30,7 @@
 class SourceLocation;
 class NamedDecl;
 
-namespace rename {
+namespace clang_refactor {
 
 // Given an AST context and a point, returns a NamedDecl identifying the symbol
 // at the point. Returns null if nothing is found at the point.
Index: clang-refactor/USREngine/USRFinder.cpp
===================================================================
--- clang-refactor/USREngine/USRFinder.cpp
+++ clang-refactor/USREngine/USRFinder.cpp
@@ -1,4 +1,4 @@
-//===--- tools/extra/clang-rename/USRFinder.cpp - Clang rename tool -------===//
+//===--- tools/extra/clang-refactor/USRFinder.cpp - USREngine -------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -23,7 +23,7 @@
 using namespace llvm;
 
 namespace clang {
-namespace rename {
+namespace clang_refactor {
 
 // NamedDeclFindingASTVisitor recursively visits each AST node to find the
 // symbol underneath the cursor.
@@ -78,32 +78,28 @@
     const SourceLocation TypeEndLoc = Lexer::getLocForEndOfToken(
         TypeBeginLoc, 0, Context.getSourceManager(), Context.getLangOpts());
     if (const auto *TemplateTypeParm =
-            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
+            dyn_cast<TemplateTypeParmType>(Loc.getType()))
       return setResult(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc);
-    }
     if (const auto *TemplateSpecType =
-            dyn_cast<TemplateSpecializationType>(Loc.getType())) {
+            dyn_cast<TemplateSpecializationType>(Loc.getType()))
       return setResult(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
                        TypeBeginLoc, TypeEndLoc);
-    }
     return setResult(Loc.getType()->getAsCXXRecordDecl(), TypeBeginLoc,
                      TypeEndLoc);
   }
 
   bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
     for (const auto *Initializer : ConstructorDecl->inits()) {
-      if (!Initializer->isWritten()) {
+      if (!Initializer->isWritten())
         // Ignore implicit initializers.
         continue;
-      }
       if (const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
         const SourceLocation InitBeginLoc = Initializer->getSourceLocation(),
                              InitEndLoc = Lexer::getLocForEndOfToken(
                                  InitBeginLoc, 0, Context.getSourceManager(),
                                  Context.getLangOpts());
-        if (!setResult(FieldDecl, InitBeginLoc, InitEndLoc)) {
+        if (!setResult(FieldDecl, InitBeginLoc, InitEndLoc))
           return false;
-        }
       }
     }
     return true;
@@ -129,20 +125,17 @@
   // \returns false on success.
   bool setResult(const NamedDecl *Decl, SourceLocation Start,
                  SourceLocation End) {
-    if (!Decl) {
+    if (!Decl)
       return true;
-    }
     if (Name.empty()) {
       // Offset is used to find the declaration.
       if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
-          !End.isFileID() || !isPointWithin(Start, End)) {
+          !End.isFileID() || !isPointWithin(Start, End))
         return true;
-      }
     } else {
       // Fully qualified name is used to find the declaration.
-      if (Name != Decl->getQualifiedNameAsString()) {
+      if (Name != Decl->getQualifiedNameAsString())
         return true;
-      }
     }
     Result = Decl;
     return false;
@@ -182,15 +175,13 @@
     const SourceLocation FileLoc = CurrDecl->getLocStart();
     StringRef FileName = Context.getSourceManager().getFilename(FileLoc);
     // FIXME: Add test.
-    if (FileName == SearchFile) {
+    if (FileName == SearchFile)
       Visitor.TraverseDecl(CurrDecl);
-    }
   }
 
   NestedNameSpecifierLocFinder Finder(const_cast<ASTContext &>(Context));
-  for (const auto &Location : Finder.getNestedNameSpecifierLocations()) {
+  for (const auto &Location : Finder.getNestedNameSpecifierLocations())
     Visitor.handleNestedNameSpecifierLoc(Location);
-  }
 
   return Visitor.getNamedDecl();
 }
@@ -213,5 +204,5 @@
   return std::string(Buff.data(), Buff.size());
 }
 
-} // namespace rename
+} // namespace clang_refactor
 } // namespace clang
Index: clang-refactor/USREngine/CMakeLists.txt
===================================================================
--- clang-refactor/USREngine/CMakeLists.txt
+++ clang-refactor/USREngine/CMakeLists.txt
@@ -1,18 +1,14 @@
-set(LLVM_LINK_COMPONENTS support)
+set(LLVM_LINK_COMPONENTS Support)
 
-add_clang_library(clangRename
+add_clang_library(clangRefactorUSREngine
   USRFinder.cpp
   USRFindingAction.cpp
   USRLocFinder.cpp
-  RenamingAction.cpp
 
   LINK_LIBS
   clangAST
   clangASTMatchers
   clangBasic
   clangIndex
   clangLex
-  clangToolingCore
   )
-
-add_subdirectory(tool)
Index: clang-refactor/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-refactor/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(
+  USREngine
+  modules
+  )
+
+add_subdirectory(driver)
+add_subdirectory(USREngine)
+add_subdirectory(modules)
+add_subdirectory(editor-integrations)
Index: TemplatedClassFunction.cpp
===================================================================
--- /dev/null
+++ TemplatedClassFunction.cpp
@@ -0,0 +1,22 @@
+template <typename T>
+class A {
+public:
+  void foo() /* Test 1 */ {}  // CHECK: void bar() /* Test 1 */ {}
+};
+
+int main(int argc, char **argv) {
+  A<int> a;
+  a.foo();   /* Test 2 */     // CHECK: a.bar()   /* Test 2 */
+  return 0;
+}
+
+// Test 1.
+// RUN: clang-refactor rename -offset=48 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+// Test 2.
+// RUN: clang-refactor rename -offset=162 -new-name=bar %s -- | sed 's,//.*,,' | FileCheck %s
+//
+// Currently unsupported test.
+// XFAIL: *
+
+// To find offsets after modifying the file, use:
+//   grep -Ubo 'foo.*' <file>
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -1,5 +1,5 @@
 add_subdirectory(clang-apply-replacements)
-add_subdirectory(clang-rename)
+add_subdirectory(clang-refactor)
 add_subdirectory(clang-reorder-fields)
 add_subdirectory(modularize)
 if(CLANG_ENABLE_STATIC_ANALYZER)
@@ -23,4 +23,3 @@
 if( CLANG_TOOLS_EXTRA_INCLUDE_DOCS )
   add_subdirectory(docs)
 endif()
-
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to