diff options
author | ykiko <ykikoykikoykiko@gmail.com> | 2024-11-26 20:03:39 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-26 13:03:39 +0100 |
commit | ec4c47d9490c90a98f2dda3fc9ff7c51782678f8 (patch) | |
tree | 544dd364bdeb56f0bcaceb2bc781947883125701 /clang/lib/Sema/SemaCodeComplete.cpp | |
parent | 486644723038555a224fd09d462bb5099e64809e (diff) | |
download | llvm-ec4c47d9490c90a98f2dda3fc9ff7c51782678f8.zip llvm-ec4c47d9490c90a98f2dda3fc9ff7c51782678f8.tar.gz llvm-ec4c47d9490c90a98f2dda3fc9ff7c51782678f8.tar.bz2 |
Add code completion for C++20 keywords. (#107982)
This commit adds code completion for C++20 keywords, fix
https://github.com/llvm/llvm-project/issues/107868.
1. complete `concept` in template context
- [x] `template<typename T> conce^` -> `concept`
- [ ] `conce^`
2. complete `requires`
- [x] constraints in template context: `template<typename T> requi^` ->
`requires`
- [x] requires expression: `int x = requ^` -> `requires (parameters) {
requirements }`
- [x] nested requirement: `requires { requ^ }` -> `requires expression
;`
3. complete coroutine keywords
- [x] `co_await^` in expression: `co_aw^` -> `co_await expression;`
- [x] `co_yield` in function body: `co_yi^` -> `co_yield expression;`
- [x] `co_return` in function body: `co_re^` -> `co_return expression;`
4. specifiers: `char8_t`, `consteval`, `constinit`
Diffstat (limited to 'clang/lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 12da3a2..60ea138 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1836,6 +1836,9 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Builder.AddChunk(CodeCompletionString::CK_RightParen); Results.AddResult(Result(Builder.TakeString())); } + + if (LangOpts.Char8 || LangOpts.CPlusPlus20) + Results.AddResult(Result("char8_t", CCP_Type)); } else Results.AddResult(Result("__auto_type", CCP_Type)); @@ -1888,6 +1891,9 @@ AddStorageSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC, Results.AddResult(Result("constexpr")); Results.AddResult(Result("thread_local")); } + + if (LangOpts.CPlusPlus20) + Results.AddResult(Result("constinit")); } static void @@ -1911,6 +1917,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: @@ -2186,6 +2195,69 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, } else { Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword)); } + + if (SemaRef.getLangOpts().CPlusPlus20 && + SemaRef.getLangOpts().CPlusPlusModules) { + clang::Module *CurrentModule = SemaRef.getCurrentModule(); + if (SemaRef.CurContext->isTranslationUnit()) { + /// Global module fragment can only be declared in the beginning of + /// the file. CurrentModule should be null in this case. + if (!CurrentModule) { + // module; + Builder.AddTypedTextChunk("module"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Results.AddResult(Result(Builder.TakeString())); + } + + /// Named module should be declared in the beginning of the file, + /// or after the global module fragment. + if (!CurrentModule || + CurrentModule->Kind == Module::ExplicitGlobalModuleFragment || + CurrentModule->Kind == Module::ImplicitGlobalModuleFragment) { + // export module; + // module name; + Builder.AddTypedTextChunk("module"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddPlaceholderChunk("name"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Results.AddResult(Result(Builder.TakeString())); + } + + /// Import can occur in non module file or after the named module + /// declaration. + if (!CurrentModule || + CurrentModule->Kind == Module::ModuleInterfaceUnit || + CurrentModule->Kind == Module::ModulePartitionInterface) { + // import name; + Builder.AddTypedTextChunk("import"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddPlaceholderChunk("name"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Results.AddResult(Result(Builder.TakeString())); + } + + if (CurrentModule && + (CurrentModule->Kind == Module::ModuleInterfaceUnit || + CurrentModule->Kind == Module::ModulePartitionInterface)) { + // module: private; + Builder.AddTypedTextChunk("module"); + Builder.AddChunk(CodeCompletionString::CK_Colon); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddTypedTextChunk("private"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Results.AddResult(Result(Builder.TakeString())); + } + } + + // export + if (!CurrentModule || + CurrentModule->Kind != Module::ModuleKind::PrivateModuleFragment) + Results.AddResult(Result("export", CodeCompletionResult::RK_Keyword)); + } } if (SemaRef.getLangOpts().ObjC) @@ -2253,6 +2325,11 @@ 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 > @@ -2265,6 +2342,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; @@ -2486,6 +2568,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"); @@ -2706,6 +2796,44 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, Builder.AddChunk(CodeCompletionString::CK_RightParen); Results.AddResult(Result(Builder.TakeString())); } + + if (SemaRef.getLangOpts().CPlusPlus20) { + // co_await expression + Builder.AddTypedTextChunk("co_await"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddPlaceholderChunk("expression"); + Results.AddResult(Result(Builder.TakeString())); + + // co_yield expression + 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 (SemaRef.CurContext->isRequiresExprBody()) { + // requires expression ; + 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) { |