-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Add code completion for C++20 keywords. #107982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: ykiko (16bit-ykiko) ChangesThis commit adds code completion for C++20 keywords.
Full diff: https://github.com/llvm/llvm-project/pull/107982.diff 1 Files Affected:
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 88d4732c7d5c6a..4647d65430b8c3 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -1837,6 +1837,10 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Builder.AddChunk(CodeCompletionString::CK_RightParen);
Results.AddResult(Result(Builder.TakeString()));
}
+
+ if(LangOpts.CPlusPlus20){
+ Results.AddResult(Result("char8_t", CCP_Type));
+ }
} else
Results.AddResult(Result("__auto_type", CCP_Type));
@@ -1889,6 +1893,10 @@ AddStorageSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC,
Results.AddResult(Result("constexpr"));
Results.AddResult(Result("thread_local"));
}
+
+ if (LangOpts.CPlusPlus20) {
+ Results.AddResult(Result("constinit"));
+ }
}
static void
@@ -1912,6 +1920,9 @@ AddFunctionSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC,
case SemaCodeCompletion::PCC_Template:
if (LangOpts.CPlusPlus || LangOpts.C99)
Results.AddResult(Result("inline"));
+
+ if (LangOpts.CPlusPlus20)
+ Results.AddResult(Result("consteval"));
break;
case SemaCodeCompletion::PCC_ObjCInstanceVariableList:
@@ -2254,6 +2265,10 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
[[fallthrough]];
case SemaCodeCompletion::PCC_Template:
+ if (SemaRef.getLangOpts().CPlusPlus20 && CCC == SemaCodeCompletion::PCC_Template)
+ Results.AddResult(Result("concept", CCP_Keyword));
+ [[fallthrough]];
+
case SemaCodeCompletion::PCC_MemberTemplate:
if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
// template < parameters >
@@ -2266,6 +2281,11 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword));
}
+ if(SemaRef.getLangOpts().CPlusPlus20 &&
+ (CCC == SemaCodeCompletion::PCC_Template || CCC == SemaCodeCompletion::PCC_MemberTemplate)) {
+ Results.AddResult(Result("requires", CCP_Keyword));
+ }
+
AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
break;
@@ -2487,6 +2507,14 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
Builder.AddPlaceholderChunk("expression");
Builder.AddChunk(CodeCompletionString::CK_SemiColon);
Results.AddResult(Result(Builder.TakeString()));
+ // "co_return expression ;" for coroutines(C++20).
+ if (SemaRef.getLangOpts().CPlusPlus20) {
+ Builder.AddTypedTextChunk("co_return");
+ Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Builder.AddPlaceholderChunk("expression");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
+ Results.AddResult(Result(Builder.TakeString()));
+ }
// When boolean, also add 'return true;' and 'return false;'.
if (ReturnType->isBooleanType()) {
Builder.AddTypedTextChunk("return true");
@@ -2707,6 +2735,47 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
Builder.AddChunk(CodeCompletionString::CK_RightParen);
Results.AddResult(Result(Builder.TakeString()));
}
+
+ if (SemaRef.getLangOpts().CPlusPlus20) {
+ // co_await expression
+ Builder.AddResultTypeChunk("");
+ Builder.AddTypedTextChunk("co_await");
+ Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Builder.AddPlaceholderChunk("expression");
+ Results.AddResult(Result(Builder.TakeString()));
+
+ // co_yield expression
+ Builder.AddResultTypeChunk("");
+ Builder.AddTypedTextChunk("co_yield");
+ Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Builder.AddPlaceholderChunk("expression");
+ Results.AddResult(Result(Builder.TakeString()));
+
+ // requires (parameters) { requirements }
+ Builder.AddResultTypeChunk("bool");
+ Builder.AddTypedTextChunk("requires");
+ Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+ Builder.AddPlaceholderChunk("parameters");
+ Builder.AddChunk(CodeCompletionString::CK_RightParen);
+ Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
+ Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+ Builder.AddPlaceholderChunk("requirements");
+ Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+ Builder.AddChunk(CodeCompletionString::CK_RightBrace);
+ Results.AddResult(Result(Builder.TakeString()));
+
+ if(llvm::isa<clang::RequiresExprBodyDecl>(SemaRef.CurContext)){
+ // requires expression ;
+ Builder.AddResultTypeChunk("");
+ Builder.AddTypedTextChunk("requires");
+ Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Builder.AddPlaceholderChunk("expression");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
+ Results.AddResult(Result(Builder.TakeString()));
+ }
+ }
}
if (SemaRef.getLangOpts().ObjC) {
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about module
, import
and export
?
Yes, I miss them and will add soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change needs a release note.
Please add an entry to clang/docs/ReleaseNotes.rst
in the section the most adapted to the change, and referencing any Github issue this change fixes. Thanks!
I an not sure which section I should add in |
Added, but I am not sure how to test them. Do I need a actual input module file or just use name started with |
@16bit-ykiko There is an individual file for clang-tools-extras (AFAICT, for a long time, clangd hasn't had a practice for updating its release notes whenever new features are implemented, but the situation is getting improved recently.) |
// export | ||
Results.AddResult(Result("export", CodeCompletionResult::RK_Keyword)); | ||
|
||
if (SemaRef.CurContext->isTranslationUnit()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we restrict that using getCurrentModule()->Kind
@ChuanqiXu9 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we can't do it here. Since we don't the kind of the current module before we see module declarations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, exactly.
If we haven't see module;
, we should propose module;
and export module
If we have seen module;
- we should not propose it again
If we have seem export module
, we should not propose import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I push a new commit and try to make completion for module related keywords more context-sensitive.
And found something strange: https://godbolt.org/z/YM9dhEKKe
module;
export module M;
^
If I try to run code completion at ^
, only get a compiler error.
<source>:3:1: error: export declaration can only be used within a module purview
3 | export mo<U+0000>dule M;
The error shouldn't occur, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It only happens during completion so there is probably a bug with that https://godbolt.org/z/7M8EPodoP
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some modification to ParseExportDeclaration
to fix the problem.
@cor3ntin Can we merge this PR? :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This commit adds code completion for C++20 keywords, fix #107868.
complete
concept
in template contexttemplate<typename T> conce^
->concept
conce^
complete
requires
template<typename T> requi^
->requires
int x = requ^
->requires (parameters) { requirements }
requires { requ^ }
->requires expression ;
complete coroutine keywords
co_await^
in expression:co_aw^
->co_await expression;
co_yield
in function body:co_yi^
->co_yield expression;
co_return
in function body:co_re^
->co_return expression;
specifiers:
char8_t
,consteval
,constinit