kbobyrev updated this revision to Diff 308008. kbobyrev added a comment. Add comments and a check to ensure proper behavior.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D92220/new/ https://reviews.llvm.org/D92220 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 @@ -627,6 +627,30 @@ bool LocalBool = Foo<bool>::[[Var^iable]]; } )cpp", + R"cpp( + template <typename T, typename U> struct Foo { static T Variable; }; + + template <typename T> struct Foo<T, bool> { + static T [[Var^iable]]; + }; + + void test() { + Foo<int, bool>::[[Var^iable]] = 5; + } + )cpp", + R"cpp( + template <typename T, typename U> struct Foo { + static T [[Var^iable]]; + }; + + template <typename T> struct Foo<T, bool> { + static T Variable; + }; + + void test() { + Foo<int, int>::[[Var^iable]] = 5; + } + )cpp", // Template parameters. R"cpp( Index: clang-tools-extra/clangd/refactor/Rename.cpp =================================================================== --- clang-tools-extra/clangd/refactor/Rename.cpp +++ clang-tools-extra/clangd/refactor/Rename.cpp @@ -17,6 +17,7 @@ #include "support/Trace.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Tooling/Syntax/Tokens.h" #include "llvm/ADT/None.h" @@ -141,10 +142,25 @@ return Candidate->getCanonicalDecl(); elog("FieldParent should have field with the same name as Field."); } + // This handles static fields - it's similar to FieldDecl handling above but + // the AST looks different for static fields (starting with the node type + // being VarDecl). if (const auto *VD = dyn_cast<VarDecl>(D)) { if (const VarDecl *OriginalVD = VD->getInstantiatedFromStaticDataMember()) VD = OriginalVD; - return VD->getCanonicalDecl(); + VD = VD->getCanonicalDecl(); + const auto *Context = VD->getDeclContext()->getParent(); + // VarDecl is not instantiation of static field. + if (!dyn_cast_or_null<ClassTemplateSpecializationDecl>( + VD->getDeclContext()) || + !Context || Context->getDeclKind() != Decl::Kind::CXXRecord) + return VD; + const auto LookupResult = Context->lookup(D->getDeclName()); + if (LookupResult.size() != 1) + return VD; + if (const auto *Result = dyn_cast<VarDecl>(LookupResult.front())) + return Result->getCanonicalDecl(); + return VD; } return dyn_cast<NamedDecl>(D->getCanonicalDecl()); }
Index: clang-tools-extra/clangd/unittests/RenameTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/RenameTests.cpp +++ clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -627,6 +627,30 @@ bool LocalBool = Foo<bool>::[[Var^iable]]; } )cpp", + R"cpp( + template <typename T, typename U> struct Foo { static T Variable; }; + + template <typename T> struct Foo<T, bool> { + static T [[Var^iable]]; + }; + + void test() { + Foo<int, bool>::[[Var^iable]] = 5; + } + )cpp", + R"cpp( + template <typename T, typename U> struct Foo { + static T [[Var^iable]]; + }; + + template <typename T> struct Foo<T, bool> { + static T Variable; + }; + + void test() { + Foo<int, int>::[[Var^iable]] = 5; + } + )cpp", // Template parameters. R"cpp( Index: clang-tools-extra/clangd/refactor/Rename.cpp =================================================================== --- clang-tools-extra/clangd/refactor/Rename.cpp +++ clang-tools-extra/clangd/refactor/Rename.cpp @@ -17,6 +17,7 @@ #include "support/Trace.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Tooling/Syntax/Tokens.h" #include "llvm/ADT/None.h" @@ -141,10 +142,25 @@ return Candidate->getCanonicalDecl(); elog("FieldParent should have field with the same name as Field."); } + // This handles static fields - it's similar to FieldDecl handling above but + // the AST looks different for static fields (starting with the node type + // being VarDecl). if (const auto *VD = dyn_cast<VarDecl>(D)) { if (const VarDecl *OriginalVD = VD->getInstantiatedFromStaticDataMember()) VD = OriginalVD; - return VD->getCanonicalDecl(); + VD = VD->getCanonicalDecl(); + const auto *Context = VD->getDeclContext()->getParent(); + // VarDecl is not instantiation of static field. + if (!dyn_cast_or_null<ClassTemplateSpecializationDecl>( + VD->getDeclContext()) || + !Context || Context->getDeclKind() != Decl::Kind::CXXRecord) + return VD; + const auto LookupResult = Context->lookup(D->getDeclName()); + if (LookupResult.size() != 1) + return VD; + if (const auto *Result = dyn_cast<VarDecl>(LookupResult.front())) + return Result->getCanonicalDecl(); + return VD; } 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