[clang-tools-extra] 01a30fa - [clangd] Trivial setter support when moving items to fields

Nathan James via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 29 13:51:29 PDT 2020


Author: Nathan James
Date: 2020-09-29T21:51:15+01:00
New Revision: 01a30fa6787d8375e1df573150f9927561b0a0f1

URL: https://github.com/llvm/llvm-project/commit/01a30fa6787d8375e1df573150f9927561b0a0f1
DIFF: https://github.com/llvm/llvm-project/commit/01a30fa6787d8375e1df573150f9927561b0a0f1.diff

LOG: [clangd] Trivial setter support when moving items to fields

Extend the Trivial setter documentation to support cases where the value is moved into a field using `std::move`.

Reviewed By: sammccall, kadircet

Differential Revision: https://reviews.llvm.org/D88297

Added: 
    

Modified: 
    clang-tools-extra/clangd/Hover.cpp
    clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index ef9bb536005f..9da8a9c9af57 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -413,6 +413,8 @@ llvm::Optional<StringRef> getterVariableName(const CXXMethodDecl *CMD) {
 // If CMD is one of the forms:
 //   void foo(T arg) { FieldName = arg; }
 //   R foo(T arg) { FieldName = arg; return *this; }
+//   void foo(T arg) { FieldName = std::move(arg); }
+//   R foo(T arg) { FieldName = std::move(arg); return *this; }
 // then returns "FieldName"
 llvm::Optional<StringRef> setterVariableName(const CXXMethodDecl *CMD) {
   assert(CMD->hasBody());
@@ -455,6 +457,18 @@ llvm::Optional<StringRef> setterVariableName(const CXXMethodDecl *CMD) {
   } else {
     return llvm::None;
   }
+
+  // Detect the case when the item is moved into the field.
+  if (auto *CE = llvm::dyn_cast<CallExpr>(RHS->IgnoreCasts())) {
+    if (CE->getNumArgs() != 1)
+      return llvm::None;
+    auto *ND = llvm::dyn_cast<NamedDecl>(CE->getCalleeDecl());
+    if (!ND || !ND->getIdentifier() || ND->getName() != "move" ||
+        !ND->isInStdNamespace())
+      return llvm::None;
+    RHS = CE->getArg(0);
+  }
+
   auto *DRE = llvm::dyn_cast<DeclRefExpr>(RHS->IgnoreCasts());
   if (!DRE || DRE->getDecl() != Arg)
     return llvm::None;

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 636e5d99be52..48c0fef45ab8 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -698,6 +698,26 @@ class Foo {})cpp";
          HI.Parameters->back().Name = "v";
          HI.AccessSpecifier = "public";
        }},
+      {// Setter (move)
+       R"cpp(
+          namespace std { template<typename T> T&& move(T&& t); }
+          struct X { int Y; void [[^setY]](float v) { Y = std::move(v); } };
+          )cpp",
+       [](HoverInfo &HI) {
+         HI.Name = "setY";
+         HI.Kind = index::SymbolKind::InstanceMethod;
+         HI.NamespaceScope = "";
+         HI.Definition = "void setY(float v)";
+         HI.LocalScope = "X::";
+         HI.Documentation = "Trivial setter for `Y`.";
+         HI.Type = "void (float)";
+         HI.ReturnType = "void";
+         HI.Parameters.emplace();
+         HI.Parameters->emplace_back();
+         HI.Parameters->back().Type = "float";
+         HI.Parameters->back().Name = "v";
+         HI.AccessSpecifier = "public";
+       }},
       {// Field type initializer.
        R"cpp(
           struct X { int x = 2; };
@@ -802,8 +822,8 @@ class Foo {})cpp";
          HI.Type = "int";
          HI.AccessSpecifier = "public";
        }},
-       {// No crash on InitListExpr.
-        R"cpp(
+      {// No crash on InitListExpr.
+       R"cpp(
           struct Foo {
             int a[10];
           };


        


More information about the cfe-commits mailing list