kbobyrev updated this revision to Diff 322321.
kbobyrev added a comment.

Implement constructors handling.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96324/new/

https://reviews.llvm.org/D96324

Files:
  clang-tools-extra/clangd/refactor/Rename.cpp
  clang-tools-extra/clangd/unittests/RenameTests.cpp

Index: clang-tools-extra/clangd/unittests/RenameTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/RenameTests.cpp
+++ clang-tools-extra/clangd/unittests/RenameTests.cpp
@@ -678,6 +678,61 @@
         }
       )cpp",
 
+      // Function argument.
+      R"cpp(
+        // Main.cpp
+        void foo(int [[Bar^]]);
+
+        void foo(int [[Bar^]]) {}
+
+        // Forward declarations somewhere else.
+        void foo(int [[Bar^]]);
+        void foo(int /*Bar*/);
+      )cpp",
+
+      // Template function argument.
+      R"cpp(
+        template <typename T>
+        void foo(T [[Bar^]]);
+
+        template <typename T>
+        void foo(T [[Bar^]]) {}
+      )cpp",
+      R"cpp(
+        template <typename T>
+        void foo(T [[Bar^]]);
+
+        template <typename T>
+        void foo(T [[Bar^]]) {}
+
+        template <>
+        void foo(int [[Bar^]]) {}
+      )cpp",
+
+      // Constructor argument.
+      R"cpp(
+        class Foo {
+          Foo(int [[Bar^]]);
+        };
+        Foo::Foo(int [[Bar^]]) {}
+      )cpp",
+      R"cpp(
+        class Foo {
+          template <typename T, typename U>
+          Foo(T Something, U [[Bar^]]);
+
+          Foo();
+        };
+
+        template <typename T, typename U>
+        Foo::Foo(T Something, U [[Bar^]]) {}
+
+        template <>
+        Foo::Foo(int Something, int [[Bar^]]) {}
+        template <>
+        Foo::Foo(bool Something, bool [[Bar^]]) {}
+      )cpp",
+
       // Namespace alias.
       R"cpp(
         namespace a { namespace b { void foo(); } }
Index: clang-tools-extra/clangd/refactor/Rename.cpp
===================================================================
--- clang-tools-extra/clangd/refactor/Rename.cpp
+++ clang-tools-extra/clangd/refactor/Rename.cpp
@@ -100,7 +100,8 @@
 //
 // Here, both partial (2) and full (3) specializations are canonicalized to (1)
 // which ensures all three of them are renamed.
-const NamedDecl *canonicalRenameDecl(const NamedDecl *D) {
+const NamedDecl *canonicalRenameDecl(const NamedDecl *D,
+                                     bool CanonicalizeCtorsToType = false) {
   if (const auto *VarTemplate = dyn_cast<VarTemplateSpecializationDecl>(D))
     return canonicalRenameDecl(
         VarTemplate->getSpecializedTemplate()->getTemplatedDecl());
@@ -113,9 +114,17 @@
         ClassTemplateSpecialization->getSpecializedTemplate()
             ->getTemplatedDecl());
   if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) {
-    if (Method->getDeclKind() == Decl::Kind::CXXConstructor ||
+    // By default ctors and dtors are canonicalized to the returned type but
+    // when CanonicalizeCtorsToType is set, we should still retrieve the
+    // canonical method.
+    if ((Method->getDeclKind() == Decl::Kind::CXXConstructor &&
+         !CanonicalizeCtorsToType) ||
         Method->getDeclKind() == Decl::Kind::CXXDestructor)
       return canonicalRenameDecl(Method->getParent());
+    if (const FunctionTemplateDecl *Template = Method->getPrimaryTemplate())
+      if (const auto *TemplatedDecl =
+              dyn_cast<CXXMethodDecl>(Template->getTemplatedDecl()))
+        Method = TemplatedDecl;
     if (const FunctionDecl *InstantiatedMethod =
             Method->getInstantiatedFromMemberFunction())
       Method = cast<CXXMethodDecl>(InstantiatedMethod);
@@ -151,6 +160,18 @@
   if (const auto *VD = dyn_cast<VarDecl>(D)) {
     if (const VarDecl *OriginalVD = VD->getInstantiatedFromStaticDataMember())
       VD = OriginalVD;
+    // Arguments are canonicalized to their canonical function's arguments.
+    if (const auto *Argument = dyn_cast<ParmVarDecl>(VD)) {
+      if (const auto *Function =
+              dyn_cast<FunctionDecl>(Argument->getDeclContext())) {
+        const auto *Canonical = dyn_cast<FunctionDecl>(
+            canonicalRenameDecl(Function, /*SameType=*/true));
+        assert(Canonical && "canonicalRenameDecl should return the declaration "
+                            "of the same type with SameType=true.");
+        return Canonical->getParamDecl(Argument->getFunctionScopeIndex())
+            ->getCanonicalDecl();
+      }
+    }
     return VD->getCanonicalDecl();
   }
   return dyn_cast<NamedDecl>(D->getCanonicalDecl());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to