Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-21 Thread Haojian Wu via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL282070: [clang-move] A prototype tool for moving class 
definition to new file. (authored by hokein).

Changed prior to commit:
  https://reviews.llvm.org/D24243?vs=72031&id=72033#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D24243

Files:
  clang-tools-extra/trunk/CMakeLists.txt
  clang-tools-extra/trunk/clang-move/CMakeLists.txt
  clang-tools-extra/trunk/clang-move/ClangMove.cpp
  clang-tools-extra/trunk/clang-move/ClangMove.h
  clang-tools-extra/trunk/clang-move/tool/CMakeLists.txt
  clang-tools-extra/trunk/clang-move/tool/ClangMoveMain.cpp
  clang-tools-extra/trunk/unittests/CMakeLists.txt
  clang-tools-extra/trunk/unittests/clang-move/CMakeLists.txt
  clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp

Index: clang-tools-extra/trunk/CMakeLists.txt
===
--- clang-tools-extra/trunk/CMakeLists.txt
+++ clang-tools-extra/trunk/CMakeLists.txt
@@ -9,6 +9,7 @@
 
 add_subdirectory(change-namespace)
 add_subdirectory(clang-query)
+add_subdirectory(clang-move)
 add_subdirectory(include-fixer)
 add_subdirectory(pp-trace)
 add_subdirectory(tool-template)
Index: clang-tools-extra/trunk/unittests/CMakeLists.txt
===
--- clang-tools-extra/trunk/unittests/CMakeLists.txt
+++ clang-tools-extra/trunk/unittests/CMakeLists.txt
@@ -7,6 +7,7 @@
 
 add_subdirectory(change-namespace)
 add_subdirectory(clang-apply-replacements)
+add_subdirectory(clang-move)
 add_subdirectory(clang-query)
 add_subdirectory(clang-tidy)
 add_subdirectory(include-fixer)
Index: clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp
===
--- clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp
+++ clang-tools-extra/trunk/unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,226 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "  static int b;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "void Foo::f() { f1(); }\n"
+  "\n"
+  "int Foo::b = 2;\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespac

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-21 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 72031.
hokein added a comment.

Improve the way of detecting whether #include in old_header.


https://reviews.llvm.org/D24243

Files:
  CMakeLists.txt
  clang-move/CMakeLists.txt
  clang-move/ClangMove.cpp
  clang-move/ClangMove.h
  clang-move/tool/CMakeLists.txt
  clang-move/tool/ClangMoveMain.cpp
  unittests/CMakeLists.txt
  unittests/clang-move/CMakeLists.txt
  unittests/clang-move/ClangMoveTests.cpp

Index: unittests/clang-move/ClangMoveTests.cpp
===
--- /dev/null
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,226 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "  static int b;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "void Foo::f() { f1(); }\n"
+  "\n"
+  "int Foo::b = 2;\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedNewHeader[] = "namespace a {\n"
+ "class C1;\n"
+ "namespace b {\n"
+ "class Foo {\n"
+ "public:\n"
+ "  voi

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-21 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 72027.
hokein added a comment.

Update dependency.


https://reviews.llvm.org/D24243

Files:
  CMakeLists.txt
  clang-move/CMakeLists.txt
  clang-move/ClangMove.cpp
  clang-move/ClangMove.h
  clang-move/tool/CMakeLists.txt
  clang-move/tool/ClangMoveMain.cpp
  unittests/CMakeLists.txt
  unittests/clang-move/CMakeLists.txt
  unittests/clang-move/ClangMoveTests.cpp

Index: unittests/clang-move/ClangMoveTests.cpp
===
--- /dev/null
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,226 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "  static int b;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "void Foo::f() { f1(); }\n"
+  "\n"
+  "int Foo::b = 2;\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedNewHeader[] = "namespace a {\n"
+ "class C1;\n"
+ "namespace b {\n"
+ "class Foo {\n"
+ "public:\n"
+ "  void f();\n"
+   

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-16 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 71631.
hokein added a comment.

Support fully quailified name only.


https://reviews.llvm.org/D24243

Files:
  CMakeLists.txt
  clang-move/CMakeLists.txt
  clang-move/ClangMove.cpp
  clang-move/ClangMove.h
  clang-move/tool/CMakeLists.txt
  clang-move/tool/ClangMoveMain.cpp
  unittests/CMakeLists.txt
  unittests/clang-move/CMakeLists.txt
  unittests/clang-move/ClangMoveTests.cpp

Index: unittests/clang-move/ClangMoveTests.cpp
===
--- /dev/null
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,226 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "  static int b;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "void Foo::f() { f1(); }\n"
+  "\n"
+  "int Foo::b = 2;\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedNewHeader[] = "namespace a {\n"
+ "class C1;\n"
+ "namespace b {\n"
+ "class Foo {\n"
+ "public:\n"
+ "  void f();\n"
+  

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-16 Thread Eric Liu via cfe-commits
ioeric accepted this revision.
ioeric added a comment.
This revision is now accepted and ready to land.

lg



Comment at: unittests/clang-move/ClangMoveTests.cpp:122
@@ +121,3 @@
+
+const char ExpectedNewCC[] = "#include \"foo.h\"\n"
+ "namespace a {\n"

It's fine for this patch, but I think we also want to add newlines be between 
moved declarations, especially if there were newlines in the original code. 


https://reviews.llvm.org/D24243



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-15 Thread Haojian Wu via cfe-commits
hokein added inline comments.


Comment at: clang-move/ClangMove.cpp:104
@@ +103,3 @@
+  std::reverse(Namespaces.begin(), Namespaces.end());
+  return Namespaces;
+}

Aha, I see. I misused the `findLocationAfterToken` previously.


Comment at: clang-move/ClangMove.cpp:130
@@ +129,3 @@
+  // Add #Includes.
+  std::string AllIncludesString;
+  // FIXME: Filter out the old_header.h and add header guard.

For anonymous namespace, `getNamespaces` just makes it an empty string.
Apart from that, we have to deal with other exceptions, for instance:


```
namespace a {
void A::f() {}
}
```
What we want is namespace `a`, but `getQualifiedNameAsString` returns 
`a::A::f`. Thus, using `getQualifiedNameAsString` wouldn't simplify the code at 
the moment. 



https://reviews.llvm.org/D24243



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-15 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 71506.
hokein marked 2 inline comments as done.
hokein added a comment.
Herald added a subscriber: mgorny.

Address review comments.


https://reviews.llvm.org/D24243

Files:
  CMakeLists.txt
  clang-move/CMakeLists.txt
  clang-move/ClangMove.cpp
  clang-move/ClangMove.h
  clang-move/tool/CMakeLists.txt
  clang-move/tool/ClangMoveMain.cpp
  unittests/CMakeLists.txt
  unittests/clang-move/CMakeLists.txt
  unittests/clang-move/ClangMoveTests.cpp

Index: unittests/clang-move/ClangMoveTests.cpp
===
--- /dev/null
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,226 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "  static int b;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "void Foo::f() { f1(); }\n"
+  "\n"
+  "int Foo::b = 2;\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedNewHeader[] = "namespace a {\n"
+ "class C1;\n"
+ "namespace b {\n"
+ "class Foo {\n"
+ "public:\n"

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-07 Thread Eric Liu via cfe-commits
ioeric added inline comments.


Comment at: clang-move/ClangMove.cpp:103
@@ +102,3 @@
+ const clang::SourceManager *SM) {
+  // Gets the ending ";".
+  auto EndLoc = clang::Lexer::getLocForEndOfToken(D->getLocEnd(), 0, *SM,

hokein wrote:
> ioeric wrote:
> > Consider the code below to also include trailing comment.
> > clang::SourceLocation after_semi = clang::Lexer::findLocationAfterToken(
> > D->getLocEnd, clang::tok::semi, *SM,
> > result.Context->getLangOpts(),
> > /*SkipTrailingWhitespaceAndNewLine=*/true);
> > 
> But this code could not handle cases where the declaration definition has no 
> semi at the end, such as "void f() {}"
Please see the comment for `findLocationAfterToken`.



> If the token is not found or the location is inside a macro, the returned 
> source location will be invalid.





Comment at: clang-move/ClangMove.cpp:129
@@ +128,3 @@
+  for (const auto &MovedDecl : Decls) {
+std::vector DeclNamespaces = GetNamespaces(MovedDecl.Decl);
+auto CurrentIt = CurrentNamespaces.begin();

hokein wrote:
> ioeric wrote:
> > Is it possible to restrict all `MovedDecl.Decl` to NamedDecl so that we can 
> > use `getQualifiedNameAsString` instead of having a second implementation of 
> > retrieving namespaces. 
> > 
> > Also how is anonymous namespace handled here?
> > 
> > 
> Yeah, `getQualifiedNameAsString` looks like a simpler way, but it doesn't 
> suitable for our usage here.
> 
> The `getQualifiedNameAsString` includes the name of the class.  For instance, 
> a class method decl like `void A::f() {}` defined in global namespace, it 
> retruns `A::f` which is not intended. 
> 
> It handles anonymous namespace by wrapping like `namespace { ... } // 
> namespace`, see the test.
> 
I think it should be relatively easy to split the qualified name returned by 
`getQualifiedNameAsString `.

> It handles anonymous namespace by wrapping like namespace { ... } // 
> namespace, see the test.
I mean...wouldn't `getNamespaces` return something like "a::(anonymous)" for 
anonymous namespace? How do you handle this?



Comment at: clang-move/ClangMove.h:39
@@ +38,3 @@
+  struct MoveDefinitionSpec {
+std::string Name;
+std::string OldHeader;

hokein wrote:
> ioeric wrote:
> > Should the `Name` be fully qualified?
> It's not required. The name can be fully/partially qualified, e.g., 
> `::a::b::X`, `a::b::X`, `b::X`, `X`, which has the same behavior with 
> `hasName` ast matcher.
> 
> It the given name is partially qualified, it will match all the class whose 
> name ends with the given name.
> It the given name is partially qualified, it will match all the class whose 
> name ends with the given name.
In this case, all matched classes will be moved right? Might want to mention 
this in the comment.


Comment at: clang-move/ClangMove.h:65
@@ +64,3 @@
+
+  const MoveDefinitionSpec &Spec;
+  // The Key is file path, value is the replacements being applied to the file.

hokein wrote:
> ioeric wrote:
> > Is there any reason why you made this a reference?
> To avoid the cost of making a copy of the structure.
If the copy is not that expensive, I'd just make a copy so that I don't need to 
worry about the life-cycle of `Spec`.


https://reviews.llvm.org/D24243



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-07 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 70538.
hokein marked 19 inline comments as done.
hokein added a comment.
Herald added a subscriber: beanz.

- Address review comments.


https://reviews.llvm.org/D24243

Files:
  CMakeLists.txt
  clang-move/CMakeLists.txt
  clang-move/ClangMove.cpp
  clang-move/ClangMove.h
  clang-move/tool/CMakeLists.txt
  clang-move/tool/ClangMoveMain.cpp
  unittests/CMakeLists.txt
  unittests/clang-move/CMakeLists.txt
  unittests/clang-move/ClangMoveTests.cpp

Index: unittests/clang-move/ClangMoveTests.cpp
===
--- /dev/null
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,226 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "  static int b;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "void Foo::f() { f1(); }\n"
+  "\n"
+  "int Foo::b = 2;\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "int kConstInt1 = 0;\n"
+  "} // namespace\n"
+  "\n"
+  "static int kConstInt2 = 1;\n"
+  "\n"
+  "static int help() {\n"
+  "  int a = 0;\n"
+  "  return a;\n"
+  "}\n"
+  "\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedNewHeader[] = "namespace a {\n"
+ "class C1;\n"
+ "namespace b {\n"
+ "class Foo {\n"
+ "public:\n

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-07 Thread Haojian Wu via cfe-commits
hokein added inline comments.


Comment at: clang-move/ClangMove.cpp:38
@@ +37,3 @@
+  const clang::Module * /*Imported*/) override {
+if (const auto *FileEntry = SM.getFileEntryForID(SM.getFileID(HashLoc))) {
+  if (IsAngled) {

ioeric wrote:
> Might want to comment on how #include "old_header" is handled here?
Currently the old_header is also copied to new file.


Comment at: clang-move/ClangMove.cpp:103
@@ +102,3 @@
+ const clang::SourceManager *SM) {
+  // Gets the ending ";".
+  auto EndLoc = clang::Lexer::getLocForEndOfToken(D->getLocEnd(), 0, *SM,

ioeric wrote:
> Consider the code below to also include trailing comment.
> clang::SourceLocation after_semi = clang::Lexer::findLocationAfterToken(
> D->getLocEnd, clang::tok::semi, *SM,
> result.Context->getLangOpts(),
> /*SkipTrailingWhitespaceAndNewLine=*/true);
> 
But this code could not handle cases where the declaration definition has no 
semi at the end, such as "void f() {}"


Comment at: clang-move/ClangMove.cpp:125
@@ +124,3 @@
+
+  // Add moved class definition and its related declarations. All declarations
+  // in same namespace are grouped together.

ioeric wrote:
> If two declarations in the same namespace are not consecutive in the vector 
> (i.e. there is a decl in a different ns between them), will they be put into 
> two canonical namespace blocks?
Yes, only declarations which are consecutive in the vector and in the same 
namespace are put in one namespace block.


Comment at: clang-move/ClangMove.cpp:129
@@ +128,3 @@
+  for (const auto &MovedDecl : Decls) {
+std::vector DeclNamespaces = GetNamespaces(MovedDecl.Decl);
+auto CurrentIt = CurrentNamespaces.begin();

ioeric wrote:
> Is it possible to restrict all `MovedDecl.Decl` to NamedDecl so that we can 
> use `getQualifiedNameAsString` instead of having a second implementation of 
> retrieving namespaces. 
> 
> Also how is anonymous namespace handled here?
> 
> 
Yeah, `getQualifiedNameAsString` looks like a simpler way, but it doesn't 
suitable for our usage here.

The `getQualifiedNameAsString` includes the name of the class.  For instance, a 
class method decl like `void A::f() {}` defined in global namespace, it retruns 
`A::f` which is not intended. 

It handles anonymous namespace by wrapping like `namespace { ... } // 
namespace`, see the test.



Comment at: clang-move/ClangMove.cpp:199
@@ +198,3 @@
+
+  // Match functions defined in anonymous namespace.
+  Finder->addMatcher(

ioeric wrote:
> What about static functions?
Good catch, I missed it. Added.


Comment at: clang-move/ClangMove.cpp:210
@@ +209,3 @@
+  this);
+}
+

ioeric wrote:
> FIXME: support out-of-line member variable initializations etc? Or is it 
> already covered?
Add support now.


Comment at: clang-move/ClangMove.cpp:240
@@ +239,3 @@
+llvm::StringRef FileName) {
+  if (!Spec.OldHeader.empty() && FileName.endswith(Spec.OldHeader)) {
+HeaderIncludes.push_back(IncludeLine.str());

ioeric wrote:
> No braces.
> 
> Also, I am worrying if `endswith` is a safe way to compare files. For 
> example, what if `FileName` is relative path? 
The `FileName` is from the `PPCallbacks::InclusionDirective` APIs. From my 
experience, it seems always to be an absolute file path either I pass a 
relative file path or a absolute path to clang-move, but this is no guarantee 
in the document.

Using `endswith` is the most reliable way so far.




Comment at: clang-move/ClangMove.h:39
@@ +38,3 @@
+  struct MoveDefinitionSpec {
+std::string Name;
+std::string OldHeader;

ioeric wrote:
> Should the `Name` be fully qualified?
It's not required. The name can be fully/partially qualified, e.g., 
`::a::b::X`, `a::b::X`, `b::X`, `X`, which has the same behavior with `hasName` 
ast matcher.

It the given name is partially qualified, it will match all the class whose 
name ends with the given name.


Comment at: clang-move/ClangMove.h:65
@@ +64,3 @@
+
+  const MoveDefinitionSpec &Spec;
+  // The Key is file path, value is the replacements being applied to the file.

ioeric wrote:
> Is there any reason why you made this a reference?
To avoid the cost of making a copy of the structure.


Comment at: clang-move/ClangMove.h:83
@@ +82,3 @@
+public:
+  explicit ClangMoveAction(
+  const ClangMoveTool::MoveDefinitionSpec &spec,

Eugene.Zelenko wrote:
> Is explicit necessary?
The `explicit` keyword can prevent the copy-list-initialization like 
`ClangMoveAction a = {spec, file_to_replacement}`. I'm fine to remove it since 
it is trival.


Comment at: clang-move/tool/Cl

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-06 Thread Eric Liu via cfe-commits
ioeric added a comment.

NIce! Some initial comments.



Comment at: clang-move/ClangMove.cpp:38
@@ +37,3 @@
+  const clang::Module * /*Imported*/) override {
+if (const auto *FileEntry = SM.getFileEntryForID(SM.getFileID(HashLoc))) {
+  if (IsAngled) {

Might want to comment on how #include "old_header" is handled here?


Comment at: clang-move/ClangMove.cpp:39
@@ +38,3 @@
+if (const auto *FileEntry = SM.getFileEntryForID(SM.getFileID(HashLoc))) {
+  if (IsAngled) {
+MoveTool->addIncludes("#include <" + FileName.str() + ">\n",

Braces not needed.


Comment at: clang-move/ClangMove.cpp:103
@@ +102,3 @@
+ const clang::SourceManager *SM) {
+  // Gets the ending ";".
+  auto EndLoc = clang::Lexer::getLocForEndOfToken(D->getLocEnd(), 0, *SM,

Consider the code below to also include trailing comment.
clang::SourceLocation after_semi = clang::Lexer::findLocationAfterToken(
D->getLocEnd, clang::tok::semi, *SM,
result.Context->getLangOpts(),
/*SkipTrailingWhitespaceAndNewLine=*/true);



Comment at: clang-move/ClangMove.cpp:113
@@ +112,3 @@
+clang::tooling::Replacements
+createInsertedReplacements(const std::vector &Includes,
+   const std::vector &Decls,

Intuitively, it would be easier and more efficient if you construct the code as 
a string and then insert the code with one replacement.


Comment at: clang-move/ClangMove.cpp:119
@@ +118,3 @@
+  // Add #Includes.
+  // FIXME: Filter out  the old_header.h.
+  for (const auto &Include : Includes) {

FIXME: add header guard for new header file.


Comment at: clang-move/ClangMove.cpp:125
@@ +124,3 @@
+
+  // Add moved class definition and its related declarations. All declarations
+  // in same namespace are grouped together.

If two declarations in the same namespace are not consecutive in the vector 
(i.e. there is a decl in a different ns between them), will they be put into 
two canonical namespace blocks?


Comment at: clang-move/ClangMove.cpp:129
@@ +128,3 @@
+  for (const auto &MovedDecl : Decls) {
+std::vector DeclNamespaces = GetNamespaces(MovedDecl.Decl);
+auto CurrentIt = CurrentNamespaces.begin();

Is it possible to restrict all `MovedDecl.Decl` to NamedDecl so that we can use 
`getQualifiedNameAsString` instead of having a second implementation of 
retrieving namespaces. 

Also how is anonymous namespace handled here?




Comment at: clang-move/ClangMove.cpp:157
@@ +156,3 @@
+
+clang::tooling::Replacement InsertedReplacement(
+FileName, 0, 0, getDeclarationSourceText(MovedDecl.Decl, 
MovedDecl.SM));

FIXME: also consider comments for the declaration.


Comment at: clang-move/ClangMove.cpp:199
@@ +198,3 @@
+
+  // Match functions defined in anonymous namespace.
+  Finder->addMatcher(

What about static functions?


Comment at: clang-move/ClangMove.cpp:210
@@ +209,3 @@
+  this);
+}
+

FIXME: support out-of-line member variable initializations etc? Or is it 
already covered?


Comment at: clang-move/ClangMove.cpp:240
@@ +239,3 @@
+llvm::StringRef FileName) {
+  if (!Spec.OldHeader.empty() && FileName.endswith(Spec.OldHeader)) {
+HeaderIncludes.push_back(IncludeLine.str());

No braces.

Also, I am worrying if `endswith` is a safe way to compare files. For example, 
what if `FileName` is relative path? 


Comment at: clang-move/ClangMove.cpp:254
@@ +253,3 @@
+  MovedDecl.Decl->getLocEnd(), 0, *MovedDecl.SM, clang::LangOptions());
+  clang::tooling::Replacement RemovedReplacement(
+  *MovedDecl.SM, clang::CharSourceRange::getTokenRange(

nit: `RemovedReplacement` sounds like the replacement itself is being removed. 
`RemoveReplacement` would be better IMO.


Comment at: clang-move/ClangMove.h:39
@@ +38,3 @@
+  struct MoveDefinitionSpec {
+std::string Name;
+std::string OldHeader;

Should the `Name` be fully qualified?


Comment at: clang-move/ClangMove.h:52
@@ +51,3 @@
+
+  void registerMatchers(clang::ast_matchers::MatchFinder *match_finder);
+

Variable style. Here and some more below.


Comment at: clang-move/ClangMove.h:59
@@ +58,3 @@
+
+  void addIncludes(llvm::StringRef include_line, llvm::StringRef file_name);
+

A comment for what this function does would be appreciated.


Comment at: clang-move/ClangMove.h:65
@@ +64,3 @@
+
+  const MoveDefinitionSpec &Spec;
+  // The Key is file path, value is the replacements being applied to the file.
--

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-06 Thread Eugene Zelenko via cfe-commits
Eugene.Zelenko added a comment.

Probably old_source/new_source will be better, because different extensions are 
used for C++ files.


https://reviews.llvm.org/D24243



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-06 Thread Eugene Zelenko via cfe-commits
Eugene.Zelenko added inline comments.


Comment at: clang-move/ClangMove.h:13
@@ +12,3 @@
+
+#include 
+#include 

Isn't C++ headers should be after Clang headers?


https://reviews.llvm.org/D24243



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-06 Thread Eugene Zelenko via cfe-commits
Eugene.Zelenko added a subscriber: Eugene.Zelenko.


Comment at: clang-move/ClangMove.h:33
@@ +32,3 @@
+clang::SourceManager *SM;
+MovedDecl() : Decl(nullptr), SM(nullptr) {}
+MovedDecl(const clang::Decl *Decl, clang::SourceManager *SM)

Please add empty line before. Why don't use C++11 members initialization and = 
default?


Comment at: clang-move/ClangMove.h:83
@@ +82,3 @@
+public:
+  explicit ClangMoveAction(
+  const ClangMoveTool::MoveDefinitionSpec &spec,

Is explicit necessary?


Comment at: clang-move/ClangMove.h:106
@@ +105,3 @@
+  : Spec(Spec), FileToReplacements(FileToReplacements) {}
+  clang::FrontendAction *create() override {
+return new ClangMoveAction(Spec, FileToReplacements);

Please add empty line before.


https://reviews.llvm.org/D24243



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-06 Thread Kirill Bobyrev via cfe-commits
omtcyfz added inline comments.


Comment at: clang-move/ClangMove.h:25
@@ +24,3 @@
+
+// TODO(hokein): Make it support more types, e.g. function definitions.
+// Currently only support moving class definition.

`FIXME`?


https://reviews.llvm.org/D24243



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-06 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 70363.
hokein added a comment.

Fix function name style.


https://reviews.llvm.org/D24243

Files:
  CMakeLists.txt
  clang-move/CMakeLists.txt
  clang-move/ClangMove.cpp
  clang-move/ClangMove.h
  clang-move/tool/CMakeLists.txt
  clang-move/tool/ClangMoveMain.cpp
  unittests/CMakeLists.txt
  unittests/clang-move/CMakeLists.txt
  unittests/clang-move/ClangMoveTests.cpp

Index: unittests/clang-move/ClangMoveTests.cpp
===
--- /dev/null
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,198 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "} // namespace\n"
+  "void Foo::f() { f1(); }\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "} // namespace\n"
+  "\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedNewHeader[] = "namespace a {\n"
+ "class C1;\n"
+ "namespace b {\n"
+ "class Foo {\n"
+ "public:\n"
+ "  void f();\n"
+ "\n"
+ "private:\n"
+ "  C1 *c1;\n"
+ "};\n"
+ "} // namespace b\n"
+ "} // namespace a\n";
+
+const char ExpectedNewCC[] = "#include \"foo.h\"\n"
+ "namespace a {\n"
+ "namespace b {\n"
+ "namespace {\n"
+ "void f1() {}\n"
+ "} // namespace\n"
+ "void Foo::f() { f1(); }\n"
+ "} // namespace b\n"
+ "} // namespace a\n";
+
+std::map
+runClangMoveOnCode(const move::ClangMoveTool::MoveDefinitionSpec &Spec) {
+  clang::RewriterTestContext Con

Re: [PATCH] D24243: [clang-move] A prototype tool for moving class definition to new file.

2016-09-06 Thread Haojian Wu via cfe-commits
hokein updated this revision to Diff 70362.
hokein added a comment.

Minor cleanup.


https://reviews.llvm.org/D24243

Files:
  CMakeLists.txt
  clang-move/CMakeLists.txt
  clang-move/ClangMove.cpp
  clang-move/ClangMove.h
  clang-move/tool/CMakeLists.txt
  clang-move/tool/ClangMoveMain.cpp
  unittests/CMakeLists.txt
  unittests/clang-move/CMakeLists.txt
  unittests/clang-move/ClangMoveTests.cpp

Index: unittests/clang-move/ClangMoveTests.cpp
===
--- /dev/null
+++ unittests/clang-move/ClangMoveTests.cpp
@@ -0,0 +1,198 @@
+//===-- ClangMoveTest.cpp - clang-move unit tests -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ClangMove.h"
+#include "unittests/Tooling/RewriterTestContext.h"
+#include "clang/Format/Format.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactoring.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/StringRef.h"
+#include "gtest/gtest.h"
+#include 
+#include 
+
+namespace clang {
+namespace move {
+namespace {
+
+const char TestHeaderName[] = "foo.h";
+
+const char TestCCName[] = "foo.cc";
+
+const char TestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "class Foo {\n"
+  "public:\n"
+  "  void f();\n"
+  "\n"
+  "private:\n"
+  "  C1 *c1;\n"
+  "};\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char TestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "} // namespace\n"
+  "void Foo::f() { f1(); }\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestHeader[] = "namespace a {\n"
+  "class C1;\n"
+  "namespace b {\n"
+  "\n"
+  "class Foo2 {\n"
+  "public:\n"
+  "  int f();\n"
+  "};\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedTestCC[] = "#include \"foo.h\"\n"
+  "namespace a {\n"
+  "namespace b {\n"
+  "namespace {\n"
+  "void f1() {}\n"
+  "} // namespace\n"
+  "\n"
+  "int Foo2::f() {\n"
+  "  f1();\n"
+  "  return 1;\n"
+  "}\n"
+  "} // namespace b\n"
+  "} // namespace a\n";
+
+const char ExpectedNewHeader[] = "namespace a {\n"
+ "class C1;\n"
+ "namespace b {\n"
+ "class Foo {\n"
+ "public:\n"
+ "  void f();\n"
+ "\n"
+ "private:\n"
+ "  C1 *c1;\n"
+ "};\n"
+ "} // namespace b\n"
+ "} // namespace a\n";
+
+const char ExpectedNewCC[] = "#include \"foo.h\"\n"
+ "namespace a {\n"
+ "namespace b {\n"
+ "namespace {\n"
+ "void f1() {}\n"
+ "} // namespace\n"
+ "void Foo::f() { f1(); }\n"
+ "} // namespace b\n"
+ "} // namespace a\n";
+
+std::map
+runClangMoveOnCode(const move::ClangMoveTool::MoveDefinitionSpec &Spec) {
+  clang::RewriterTestContext Context;
+
+