forked from OSchip/llvm-project
[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
This commit is contained in:
parent
155d2d5300
commit
01a30fa678
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue