diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -133,6 +133,10 @@ if (const VarDecl *OriginalVD = VD->getInstantiatedFromStaticDataMember()) return canonicalRenameDecl(OriginalVD); } + if (const auto *UD = dyn_cast(D)) { + if (const auto* TargetDecl = UD->getTargetDecl()) + return canonicalRenameDecl(TargetDecl); + } return dyn_cast(D->getCanonicalDecl()); } @@ -157,6 +161,23 @@ return Result; } +// For something like +// namespace ns { void foo(); } +// void bar() { using ns::foo; f^oo(); } +// locateDeclAt() will return a BaseUsingDecl and foo's actual declaration. +// For renaming, we're only interested in foo's declaration, so drop the other one +void filterBaseUsingDecl(llvm::DenseSet& Decls) { + if (Decls.size() == 2) { + auto FirstDecl = Decls.begin(); + auto SecondDecl = std::next(Decls.begin()); + + if (llvm::isa(*FirstDecl)) + Decls.erase(FirstDecl); + else if (llvm::isa(*SecondDecl)) + Decls.erase(SecondDecl); + } +} + // By default, we exclude symbols from system headers and protobuf symbols as // renaming these symbols would change system/generated files which are unlikely // to be good candidates for modification. @@ -737,6 +758,7 @@ return makeError(ReasonToReject::UnsupportedSymbol); auto DeclsUnderCursor = locateDeclAt(AST, IdentifierToken->location()); + filterBaseUsingDecl(DeclsUnderCursor); if (DeclsUnderCursor.empty()) return makeError(ReasonToReject::NoSymbolFound); if (DeclsUnderCursor.size() > 1) diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -817,6 +817,18 @@ char [[da^ta]]; } @end )cpp", + + // Issue 170: Rename symbol introduced by UsingDecl + R"cpp( + namespace ns { void [[f^oo]](); } + + using ns::[[f^oo]]; + + void f() { + [[f^oo]](); + auto p = &[[f^oo]]; + } + )cpp", }; llvm::StringRef NewName = "NewName"; for (llvm::StringRef T : Tests) {