Unverified Commit 9f6d8de2 authored by Kirill Bobyrev's avatar Kirill Bobyrev
Browse files

[clangd] Support renaming designated initializers

Summary:
Clangd does not find references of designated iniitializers yet and, as a
result, is unable to rename such references. This patch addresses this issue.

Resolves: https://github.com/clangd/clangd/issues/247

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: merge_guards_bot, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D72867
parent 5e1d7bb6
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -672,6 +672,17 @@ llvm::SmallVector<ReferenceLoc, 2> refInExpr(const Expr *E) {
          // Select the getter, setter, or @property depending on the call.
          explicitReferenceTargets(DynTypedNode::create(*E), {})});
    }

    void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {
      for (const DesignatedInitExpr::Designator &D : DIE->designators()) {
        if (!D.isFieldDesignator())
          continue;
        Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
                                    D.getFieldLoc(),
                                    /*IsDecl=*/false,
                                    {D.getField()}});
      }
    }
  };

  Visitor V;
+35 −1
Original line number Diff line number Diff line
@@ -1162,7 +1162,41 @@ TEST_F(FindExplicitReferencesTest, All) {
          )cpp",
           "0: targets = {f}\n"
           "1: targets = {I::x}\n"
           "2: targets = {I::setY:}\n"}};
           "2: targets = {I::setY:}\n"},
       // Designated initializers.
       {R"cpp(
            void foo() {
              struct $0^Foo {
                int $1^Bar;
              };
              $2^Foo $3^f { .$4^Bar = 42 };
            }
        )cpp",
        "0: targets = {Foo}, decl\n"
        "1: targets = {foo()::Foo::Bar}, decl\n"
        "2: targets = {Foo}\n"
        "3: targets = {f}, decl\n"
        "4: targets = {foo()::Foo::Bar}\n"},
       {R"cpp(
            void foo() {
              struct $0^Baz {
                int $1^Field;
              };
              struct $2^Bar {
                $3^Baz $4^Foo;
              };
              $5^Bar $6^bar { .$7^Foo.$8^Field = 42 };
            }
        )cpp",
        "0: targets = {Baz}, decl\n"
        "1: targets = {foo()::Baz::Field}, decl\n"
        "2: targets = {Bar}, decl\n"
        "3: targets = {Baz}\n"
        "4: targets = {foo()::Bar::Foo}, decl\n"
        "5: targets = {Bar}\n"
        "6: targets = {bar}, decl\n"
        "7: targets = {foo()::Bar::Foo}\n"
        "8: targets = {foo()::Baz::Field}\n"}};

  for (const auto &C : Cases) {
    llvm::StringRef ExpectedCode = C.first;
+29 −0
Original line number Diff line number Diff line
@@ -440,6 +440,35 @@ TEST(RenameTest, WithinFileRename) {
        template <template<typename> class Z> struct Bar { };
        template <> struct Bar<[[Foo]]> {};
      )cpp",

      // Designated initializer.
      R"cpp(
        struct Bar {
          int [[Fo^o]];
        };
        Bar bar { .[[^Foo]] = 42 };
      )cpp",

      // Nested designated initializer.
      R"cpp(
        struct Baz {
          int Field;
        };
        struct Bar {
          Baz [[Fo^o]];
        };
        // FIXME:    v selecting here results in renaming Field.
        Bar bar { .[[Foo]].Field = 42 };
      )cpp",
      R"cpp(
        struct Baz {
          int [[Fiel^d]];
        };
        struct Bar {
          Baz Foo;
        };
        Bar bar { .Foo.[[^Field]] = 42 };
      )cpp",
  };
  for (llvm::StringRef T : Tests) {
    SCOPED_TRACE(T);