This is an archive of the discontinued LLVM Phabricator instance.

[clangd] Add support for within-file rename of complicated fields
ClosedPublic

Authored by kbobyrev on Nov 23 2020, 2:59 AM.

Details

Summary

This was originally a part of D71880 but is separated for simplicity and ease
of reviewing.

Fixes: https://github.com/clangd/clangd/issues/582

Diff Detail

Event Timeline

kbobyrev created this revision.Nov 23 2020, 2:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 23 2020, 2:59 AM
kbobyrev requested review of this revision.Nov 23 2020, 2:59 AM

I assume this fixes https://github.com/clangd/clangd/issues/582?

can you check the static members in template classes etc? I think the AST is different.

clang-tools-extra/clangd/refactor/Rename.cpp
131

yeah, this is a bit unfortunate, I don't have a better solution (extending the AST is one option, but it may be not easy). I think we can live with the heuristic.

137

nit: I think we can simplify the code a bit more:

const auto* Template = Field->getParent()->getTemplateInstantiationPattern();
if (!Template)
  return...;
142

I think we could also check the equality of their names.

143

this assertion seems too strong to me -- this is a heuristics, it may have false positives. I think we can remove it.

149

use elog?

clang-tools-extra/clangd/unittests/RenameTests.cpp
545

I think this is a normal rename-field case, it should already work prior to the patch.

575

Another seems to be not needed. I'd suggest removing it to make the testcase as tense as possible.

kbobyrev edited the summary of this revision. (Show Details)Nov 24 2020, 4:23 AM
kbobyrev updated this revision to Diff 307317.Nov 24 2020, 4:46 AM
kbobyrev marked 4 inline comments as done.

Resolve most actionable comments.

kbobyrev planned changes to this revision.Nov 24 2020, 4:55 AM
template<typename T>
struct Foo {
  static T [[Var^iable]];
};

template <>
int Foo<int>::[[Variable^]] = 42;

template <>
bool Foo<bool>::[[Variable^]] = true;

void foo() {
  int LocalInt = Foo<int>::[[Variable^]];
  bool LocalBool = Foo<bool>::[[Variable^]];
}

This doesn't work yet, need to investigate.

clang-tools-extra/clangd/refactor/Rename.cpp
131

Yes, I thought about that but realized it might be too much effort, maybe I should put a FIXME here.

142

Yes, that is what @sammccall proposed too, but names not simple unsigned numbers, checking for that is just more expensive.

clang-tools-extra/clangd/unittests/RenameTests.cpp
575

In this case there is only one field and I'd be happy to check that the correct field gets renamed in case there are two of them (this is when the index comparison is checked). Otherwise this would pass without the index checking (there is one field, we don't check if it's actually the one we need and it gets renamed regardless).

kbobyrev updated this revision to Diff 307327.Nov 24 2020, 6:09 AM

Added support for static templated fields. Ready for the review again.

hokein added inline comments.Nov 25 2020, 1:12 AM
clang-tools-extra/clangd/refactor/Rename.cpp
134

sorry, I thought Field->getParent() returns a CXXRecordDecl.

I think this is dangerous for C, getParent returns a RecordDecl, then dyn_cast returns null, and we will access a nullptr.

142

I think I meant to use Field->getDeclName() == Candidate->getDeclName(), DeclarationName comparison is cheap, just comparing with the underlying pointer -- clang will unique all identifiers in the IdentifierTable.

clang-tools-extra/clangd/unittests/RenameTests.cpp
575

I see, for index comparison. this makes sense.

613

can you add a template partial testcase? something like

template <typename T, typename U> struct Foo { static T Variable; };

template <typename T> struct Foo<T, bool> {
  static T Variable;
};

void test() {
  Foo<int, bool>::Variable = 5;
}
kbobyrev updated this revision to Diff 307818.Nov 26 2020, 3:55 AM
kbobyrev marked 6 inline comments as done.

Resolve remaining comments.

hokein accepted this revision.Nov 26 2020, 4:33 AM
hokein added inline comments.
clang-tools-extra/clangd/refactor/Rename.cpp
132

not sure the FIXME is useful here, we may never do that, I'd just drop it.

138

nit: this if branch is not necessary, because the if below already handles that.

150

nit: we can inline the OriginalVD declaration into the if.

This revision is now accepted and ready to land.Nov 26 2020, 4:33 AM
kbobyrev updated this revision to Diff 307834.Nov 26 2020, 4:57 AM
kbobyrev marked 3 inline comments as done.

Resolve another round of comments.