zyounan created this revision.
zyounan added reviewers: nridge, tom-anders, sammccall.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
zyounan added a comment.
zyounan updated this revision to Diff 540687.
zyounan published this revision for review.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.
Changing the code completion string to `RK_Pattern` makes the completion
clearer, in a way that showing candidates with signatures in the completion
items if `FunctionCanBeCall` while a mere name otherwise.
F28256820: image.png <https://reviews.llvm.org/F28256820>
F28256841: image.png <https://reviews.llvm.org/F28256841>
(Comparing to that we always show signatures even if no parameters are produced
when hit the item.)
F28256859: image.png <https://reviews.llvm.org/F28256859> -> F28256863:
image.png <https://reviews.llvm.org/F28256863>
---
P.S. Despite the fact that I changed many associated tests, I still hope people
don't rely on the former behavior so that this patch could be marked as NFC. :D
I discovered that patch when trying to figure out why clangd doesn't complete
function parameters for members in global scope while it produces parameters
when I'm inside a call expression. Regard to the heuristic itself, it's
currently a bit inconvenient that I have to switch headers and sources back and
forth and do copy-pastes when I'm writing member function definitions outside
of a class. I think we could be more lenient here e.g., don't set the flag on
if we're in the global scope. What do you guys think? (I'm working on another
follow-up patch to address this, although it is not strightforward to tell
which scope the building Declarator is in inside Sema. )
zyounan added a comment.
Format
This tries to avoid extra calculations in D137040
<https://reviews.llvm.org/D137040>.
In that patch the extra completion strings were dropped at the client
site, after function parameters became available, to implement the
heuristic. However, we can make the process a bit more terse. In the
context where a call isn't required, we could teach the Sema to emit
the completion string without additional parameters by changing the Decl
to a Pattern with the function name.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D155370
Files:
clang-tools-extra/clangd/CodeComplete.cpp
clang/lib/Sema/SemaCodeComplete.cpp
clang/test/CodeCompletion/member-access.cpp
clang/test/Index/complete-qualified.cpp
clang/unittests/Sema/CodeCompleteTest.cpp
Index: clang/unittests/Sema/CodeCompleteTest.cpp
===================================================================
--- clang/unittests/Sema/CodeCompleteTest.cpp
+++ clang/unittests/Sema/CodeCompleteTest.cpp
@@ -59,14 +59,12 @@
unsigned NumResults) override {
for (unsigned I = 0; I < NumResults; ++I) {
auto R = Results[I];
- if (R.Kind == CodeCompletionResult::RK_Declaration) {
- if (const auto *FD = llvm::dyn_cast<FunctionDecl>(R.getDeclaration())) {
- CompletedFunctionDecl D;
- D.Name = FD->getNameAsString();
- D.CanBeCall = R.FunctionCanBeCall;
- D.IsStatic = FD->isStatic();
- CompletedFuncDecls.emplace_back(std::move(D));
- }
+ if (const auto *FD = llvm::dyn_cast<FunctionDecl>(R.getDeclaration())) {
+ CompletedFunctionDecl D;
+ D.Name = FD->getNameAsString();
+ D.CanBeCall = R.FunctionCanBeCall;
+ D.IsStatic = FD->isStatic();
+ CompletedFuncDecls.emplace_back(std::move(D));
}
}
}
Index: clang/test/Index/complete-qualified.cpp
===================================================================
--- clang/test/Index/complete-qualified.cpp
+++ clang/test/Index/complete-qualified.cpp
@@ -16,5 +16,6 @@
// RUN: c-index-test -code-completion-at=%s:14:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: FieldDecl:{ResultType C<Foo, class Bar>}{TypedText c} (35)
// CHECK-CC1: ClassDecl:{TypedText Foo} (35)
-// CHECK-CC1: CXXMethod:{ResultType Foo &}{TypedText operator=}{LeftParen (}{Placeholder const Foo &}{RightParen )}
-// CHECK-CC1: CXXDestructor:{ResultType void}{TypedText ~Foo}{LeftParen (}{RightParen )} (80)
+// CHECK-CC1: CXXMethod:{TypedText operator=} (50)
+// CHECK-CC1: CXXMethod:{TypedText operator=} (50)
+// CHECK-CC1: CXXMethod:{TypedText ~Foo} (50)
Index: clang/test/CodeCompletion/member-access.cpp
===================================================================
--- clang/test/CodeCompletion/member-access.cpp
+++ clang/test/CodeCompletion/member-access.cpp
@@ -171,7 +171,7 @@
template<typename T>
void dependentColonColonCompletion() {
Template<T>::staticFn();
-// CHECK-CC7: function : [#void#]function()
+// CHECK-CC7: Pattern : function
// CHECK-CC7: Nested : Nested
// CHECK-CC7: o1 : [#BaseTemplate<int>#]o1
// CHECK-CC7: o2 : [#BaseTemplate<T>#]o2
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -1211,6 +1211,13 @@
R.InBaseClass = true;
}
+static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
+ const NamedDecl *ND,
+ CodeCompletionBuilder &Result);
+
+static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
+ const Preprocessor &PP);
+
enum class OverloadCompare { BothViable, Dominates, Dominated };
// Will Candidate ever be called on the object, when overloaded with Incumbent?
// Returns Dominates if Candidate is always called, Dominated if Incumbent is
@@ -1400,10 +1407,29 @@
return nullptr;
}();
- R.FunctionCanBeCall =
+ bool FunctionCanBeCall =
CurrentClassScope &&
(CurrentClassScope == Method->getParent() ||
CurrentClassScope->isDerivedFrom(Method->getParent()));
+
+ // Instead of doing calculation for parameters later whose results would
+ // be dropped eventually, we only emit the function name.
+ if (!FunctionCanBeCall) {
+ CodeCompletionBuilder Builder(getAllocator(),
+ getCodeCompletionTUInfo());
+ auto &ASTContext = SemaRef.getASTContext();
+ AddTypedNameChunk(
+ ASTContext,
+ getCompletionPrintingPolicy(ASTContext, SemaRef.getPreprocessor()),
+ Method, Builder);
+ Result R(Builder.TakeString(), /*Priority=*/CCP_Declaration,
+ /*CursorKind=*/CXCursor_CXXMethod,
+ /*Availability=*/CXAvailability_Available,
+ /*D=*/Method);
+ R.FunctionCanBeCall = false;
+ AddResult(std::move(R));
+ return;
+ }
}
}
Index: clang-tools-extra/clangd/CodeComplete.cpp
===================================================================
--- clang-tools-extra/clangd/CodeComplete.cpp
+++ clang-tools-extra/clangd/CodeComplete.cpp
@@ -438,8 +438,6 @@
if (C.SemaResult) {
getSignature(*SemaCCS, &S.Signature, &S.SnippetSuffix, C.SemaResult->Kind,
C.SemaResult->CursorKind, &Completion.RequiredQualifier);
- if (!C.SemaResult->FunctionCanBeCall)
- S.SnippetSuffix.clear();
S.ReturnType = getReturnType(*SemaCCS);
} else if (C.IndexResult) {
S.Signature = std::string(C.IndexResult->Signature);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits