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

https://reviews.llvm.org/D22465

Files:
  clang-rename/RenamingAction.cpp
  clang-rename/USRFinder.cpp
  clang-rename/USRLocFinder.cpp
  test/clang-rename/ClassNameInFunctionDefenition.cpp
  test/clang-rename/ComplicatedClassType.cpp
  test/clang-rename/ComplicatedClassTypeInCustomNamespace.cpp
  test/clang-rename/NestedNamespace.cpp
  test/clang-rename/TemplateTypename.cpp
  test/clang-rename/UserDefinedConversion.cpp
  test/clang-rename/UserDefinedConversionFindByConversion.cpp
  test/clang-rename/UserDefinedConversionFindByTypeDeclaration.cpp

Index: test/clang-rename/UserDefinedConversionFindByTypeDeclaration.cpp
===================================================================
--- test/clang-rename/UserDefinedConversionFindByTypeDeclaration.cpp
+++ test/clang-rename/UserDefinedConversionFindByTypeDeclaration.cpp
@@ -1,7 +1,6 @@
-// Currently unsupported test.
 // RUN: cat %s > %t.cpp
-// FIXME: while renaming class/struct clang-rename should be able to change
-// this type name corresponding user-defined conversions, too.
+// RUN: clang-rename -offset=136 -new-name=Bar %t.cpp -i --
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {                         // CHECK: class Bar {
 //    ^ offset must be here
Index: test/clang-rename/UserDefinedConversionFindByConversion.cpp
===================================================================
--- test/clang-rename/UserDefinedConversionFindByConversion.cpp
+++ test/clang-rename/UserDefinedConversionFindByConversion.cpp
@@ -1,11 +1,10 @@
-// Currently unsupported test.
 // RUN: cat %s > %t.cpp
-// FIXME: clang-rename should handle conversions from a class type to another
-// type.
+// RUN: clang-rename -offset=136 -new-name=Bar %t.cpp -i --
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
 class Foo {};             // CHECK: class Bar {};
 
-class Baz {               // CHECK: class Bar {
+class Baz {
   operator Foo() const {  // CHECK: operator Bar() const {
     Foo foo;              // CHECK: Bar foo;
     return foo;
Index: test/clang-rename/TemplateTypename.cpp
===================================================================
--- test/clang-rename/TemplateTypename.cpp
+++ test/clang-rename/TemplateTypename.cpp
@@ -1,12 +1,20 @@
-// Currently unsupported test.
 // RUN: cat %s > %t.cpp
+// RUN: clang-rename -offset=270 -new-name=U %t.cpp -i --
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
+
+// Currently unsupported test.
 // FIXME: clang-rename should be able to rename template parameters correctly.
+// XFAIL: *
 
-template <typename T>
-T foo(T arg, T& ref, T* ptr) {
-  T value;
+template <typename T>             // CHECK: template <typename U>
+class Foo {
+T foo(T arg, T& ref, T* ptr) {    // CHECK: U foo(U arg, U& ref, U* ptr) {
+  T value;                        // CHECK: U value;
   int number = 42;
-  value = (T)number;
-  value = static_cast<T>(number);
+  value = (T)number;              // CHECK: value = (U)number;
+  value = static_cast<T>(number); // CHECK: value = static_cast<U>(number);
   return value;
 }
+
+T member;                         // CHECK: U member;
+};
Index: test/clang-rename/NestedNamespace.cpp
===================================================================
--- /dev/null
+++ test/clang-rename/NestedNamespace.cpp
@@ -0,0 +1,42 @@
+// RUN: cat %s > %t.cpp
+// RUN: clang-rename -offset=274 -new-name=Bar %t.cpp -i --
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
+
+// Currently unsupported test.
+// FIXME: Teach clang-rename to rename namespace in nested constructions.
+// XFAIL: *
+
+namespace Baz {
+namespace Foo {                         // CHECK: namespace Bar {
+class A {
+public:
+  static int aFunction() { return 0; }
+};
+int FooFunction() { return 0; }
+namespace Qux {
+class B {
+public:
+  static int bFunction() { return 0; }
+};
+int QuxFunction() { return 0; }
+} // namespace Qux
+} // namespace Foo
+} // namespace Baz
+
+int main() {
+
+  // Variable type tests.
+  Baz::Foo::A a;                          // CHECK: Baz::Bar::A a;
+  Baz::Foo::Qux::B b;                     // CHECK: Baz::Bar::Qux::B b;
+  unsigned i = 42;
+  for (Baz::Foo::A c; i < 100; i++);      // CHECK: for (Baz::Bar::A c; i < 100; i++);
+  for (Baz::Foo::Qux::B d; i < 200; i++); // CHECK: for (Baz::Bar::Qux::B d; i < 200; i++);
+
+  // Function tests.
+  int x = Baz::Foo::A::aFunction();       // CHECK: int x = Baz::Bar::A::aFunction();
+  x = Baz::Foo::FooFunction();            // CHECK: x = Baz::Bar::FooFunction();
+  x = Baz::Foo::Qux::B::bFunction();      // CHECK: x = Baz::Bar::Qux::B::bFunction();
+  x = Baz::Foo::Qux::QuxFunction();       // CHECK: x = Baz::Bar::Qux::QuxFunction();
+
+  return 0;
+}
Index: test/clang-rename/ComplicatedClassTypeInCustomNamespace.cpp
===================================================================
--- /dev/null
+++ test/clang-rename/ComplicatedClassTypeInCustomNamespace.cpp
@@ -0,0 +1,37 @@
+// RUN: cat %s > %t.cpp
+// RUN: clang-rename -offset=241 -new-name=Bar %t.cpp -i --
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
+
+namespace baz {
+
+// Forward declaration.
+class Foo;                                // CHECK: class Bar;
+
+class Foo {                               // CHECK: class Bar {
+ public:
+  Foo(int value = 0) : x(value) {}        // CHECK: Bar(int value = 0) : x(value) {}
+
+  Foo &operator++(int) {                  // CHECK: Bar &operator++(int) {
+    x++;
+    return *this;
+  }
+
+  bool operator<(Foo const &rhs) {        // CHECK: bool operator<(Bar const &rhs) {
+    return this->x < rhs.x;
+  }
+
+ private:
+  int x;
+};
+
+Foo Instance;                              // CHECK: Bar Instance;
+
+}
+
+int main() {
+  baz::Foo *Pointer = 0;                   // CHECK: baz::Bar *Pointer = 0;
+  baz::Foo Variable = baz::Foo(10);        // CHECK: baz::Bar Variable = baz::Bar(10);
+  for (baz::Foo it; it < Variable; it++) { // CHECK: for (baz::Bar it; it < Variable; it++) {}
+  }
+  return 0;
+}
Index: test/clang-rename/ComplicatedClassType.cpp
===================================================================
--- test/clang-rename/ComplicatedClassType.cpp
+++ test/clang-rename/ComplicatedClassType.cpp
@@ -1,30 +1,31 @@
-// Unsupported test.
 // RUN: cat %s > %t.cpp
-// FIXME: This test contains very simple constructions likely to be seen in any
-// project and therefore passing this test is a slight sign of success.
-// Currently, the test fails badly.
+// RUN: clang-rename -offset=220 -new-name=Bar %t.cpp -i --
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
+
+// Forward declaration.
+class Foo;                            // CHECK: class Bar;
 
 class Foo {                           // CHECK: class Bar {
- public:
-  Foo(int value = 0) : x(value) {}    // Bar(int value=0) : x(value) {}
+public:
+  Foo(int value = 0) : x(value) {}    // CHECK: Bar(int value = 0) : x(value) {}
 
-  Foo& operator++(int) {              // Bar& operator++(int) {
+  Foo &operator++(int) {              // CHECK: Bar &operator++(int) {
     x++;
     return *this;
   }
 
-  bool operator<(Foo const& rhs) {    // bool operator<(Bar const &rhs) {
+  bool operator<(Foo const &rhs) {    // CHECK: bool operator<(Bar const &rhs) {
     return this->x < rhs.x;
   }
 
- private:
+private:
   int x;
 };
 
 int main() {
-  Foo* Pointer = 0;                   // CHECK: Bar *Pointer = 0;
+  Foo *Pointer = 0;                   // CHECK: Bar *Pointer = 0;
   Foo Variable = Foo(10);             // CHECK: Bar Variable = Bar(10);
-  for (Foo it; it < Variable; it++) { // for (Bar it; it < Variable; it++) {}
+  for (Foo it; it < Variable; it++) { // CHECK: for (Bar it; it < Variable; it++) {
   }
   return 0;
 }
Index: test/clang-rename/ClassNameInFunctionDefenition.cpp
===================================================================
--- test/clang-rename/ClassNameInFunctionDefenition.cpp
+++ test/clang-rename/ClassNameInFunctionDefenition.cpp
@@ -1,17 +1,10 @@
-// Currently unsupported test.
 // RUN: cat %s > %t.cpp
-// FIXME: clang-rename doesn't recognize symbol in class function definition.
+// RUN: clang-rename -offset=136 -new-name=Bar %t.cpp -i --
+// RUN: sed 's,//.*,,' %t.cpp | FileCheck %s
 
-class Foo {
+class Foo {             // CHECK: class Bar {
 public:
   void foo(int x);
 };
 
-void Foo::foo(int x) {}
-//   ^ this one
-
-int main() {
-  Foo obj;
-  obj.foo(0);
-  return 0;
-}
+void Foo::foo(int x) {} // CHECK: void Bar::foo(int x) {}
Index: clang-rename/USRLocFinder.cpp
===================================================================
--- clang-rename/USRLocFinder.cpp
+++ clang-rename/USRLocFinder.cpp
@@ -136,17 +136,6 @@
     return true;
   }
 
-  bool VisitCXXConstructExpr(const CXXConstructExpr *Expr) {
-    CXXConstructorDecl *Decl = Expr->getConstructor();
-
-    if (getUSRForDecl(Decl) == USR) {
-      // This takes care of 'new <name>' expressions.
-      LocationsFound.push_back(Expr->getLocation());
-    }
-
-    return true;
-  }
-
   bool VisitCXXStaticCastExpr(clang::CXXStaticCastExpr *Expr) {
     return handleCXXNamedCastExpr(Expr);
   }
@@ -163,6 +152,18 @@
     return handleCXXNamedCastExpr(Expr);
   }
 
+  // Other visitors:
+
+  // FIXME: Given "clang::TypeLoc" this currently pushes "clang::" location to
+  // the LocationsFound storage while it should push "TypeLoc" location. I don't
+  // know how to address it yet, but it should fix quite many bugs.
+  bool VisitTypeLoc(const TypeLoc Loc) {
+    if (getUSRForDecl(Loc.getType()->getAsCXXRecordDecl()) == USR) {
+      LocationsFound.push_back(Loc.getLocStart());
+    }
+    return true;
+  }
+
   // Non-visitors:
 
   // \brief Returns a list of unique locations. Duplicate or overlapping
Index: clang-rename/USRFinder.cpp
===================================================================
--- clang-rename/USRFinder.cpp
+++ clang-rename/USRFinder.cpp
@@ -77,6 +77,13 @@
                      Decl->getNameAsString().length());
   }
 
+  // FIXME: This currently points anything from "my::namespace::Class" to the
+  // Class declaration, which is not correct in general.
+  bool VisitTypeLoc(const TypeLoc Loc) {
+    return setResult(Loc.getType()->getAsCXXRecordDecl(),
+                     Loc.getBeginLoc(), Loc.getEndLoc());
+  }
+
   // Other:
 
   const NamedDecl *getNamedDecl() {
Index: clang-rename/RenamingAction.cpp
===================================================================
--- clang-rename/RenamingAction.cpp
+++ clang-rename/RenamingAction.cpp
@@ -57,19 +57,16 @@
     }
 
     auto PrevNameLen = PrevName.length();
-    if (PrintLocations)
-      for (const auto &Loc : RenamingCandidates) {
+    for (const auto &Loc : RenamingCandidates) {
+      if (PrintLocations) {
         FullSourceLoc FullLoc(Loc, SourceMgr);
         errs() << "clang-rename: renamed at: " << SourceMgr.getFilename(Loc)
                << ":" << FullLoc.getSpellingLineNumber() << ":"
                << FullLoc.getSpellingColumnNumber() << "\n";
-        Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
-                                             NewName));
       }
-    else
-      for (const auto &Loc : RenamingCandidates)
-        Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
-                                             NewName));
+      Replaces.insert(tooling::Replacement(SourceMgr, Loc, PrevNameLen,
+                                           NewName));
+    }
   }
 
 private:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to