https://github.com/16bit-ykiko updated https://github.com/llvm/llvm-project/pull/107982
>From fedea9e4fd57b618fe341e0c30982bff0f098c52 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Tue, 10 Sep 2024 14:59:10 +0800 Subject: [PATCH 01/16] add co_return, co_await, co_yield, consteval, constinit, concept, requires, char8_t. --- clang/lib/Sema/SemaCodeComplete.cpp | 61 +++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 88d4732c7d5c6a..d8f6b1dada942a 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1837,6 +1837,11 @@ 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)); + Results.AddResult(Result("concept", CCP_Keyword)); + } } else Results.AddResult(Result("__auto_type", CCP_Type)); @@ -1889,6 +1894,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 +1921,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: @@ -2487,6 +2499,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 +2727,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) { >From 36a0db2b827baaabe17c5cd7b576802be586c69c Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Tue, 10 Sep 2024 15:50:04 +0800 Subject: [PATCH 02/16] make concept and requires more sensitive to context. --- clang/lib/Sema/SemaCodeComplete.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index d8f6b1dada942a..4647d65430b8c3 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1840,7 +1840,6 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, if(LangOpts.CPlusPlus20){ Results.AddResult(Result("char8_t", CCP_Type)); - Results.AddResult(Result("concept", CCP_Keyword)); } } else Results.AddResult(Result("__auto_type", CCP_Type)); @@ -2266,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 > @@ -2278,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; >From 326892aa58340be0de3085a6d2bf3cc886a4b0f2 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Tue, 10 Sep 2024 16:50:34 +0800 Subject: [PATCH 03/16] format. --- clang/lib/Sema/SemaCodeComplete.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 4647d65430b8c3..1c815d170cdfb0 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1838,7 +1838,7 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Results.AddResult(Result(Builder.TakeString())); } - if(LangOpts.CPlusPlus20){ + if (LangOpts.CPlusPlus20) { Results.AddResult(Result("char8_t", CCP_Type)); } } else @@ -2265,8 +2265,9 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, [[fallthrough]]; case SemaCodeCompletion::PCC_Template: - if (SemaRef.getLangOpts().CPlusPlus20 && CCC == SemaCodeCompletion::PCC_Template) - Results.AddResult(Result("concept", CCP_Keyword)); + if (SemaRef.getLangOpts().CPlusPlus20 && + CCC == SemaCodeCompletion::PCC_Template) + Results.AddResult(Result("concept", CCP_Keyword)); [[fallthrough]]; case SemaCodeCompletion::PCC_MemberTemplate: @@ -2282,7 +2283,8 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, } if(SemaRef.getLangOpts().CPlusPlus20 && - (CCC == SemaCodeCompletion::PCC_Template || CCC == SemaCodeCompletion::PCC_MemberTemplate)) { + (CCC == SemaCodeCompletion::PCC_Template || + CCC == SemaCodeCompletion::PCC_MemberTemplate)) { Results.AddResult(Result("requires", CCP_Keyword)); } @@ -2738,14 +2740,12 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, 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"); @@ -2766,9 +2766,8 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, Builder.AddChunk(CodeCompletionString::CK_RightBrace); Results.AddResult(Result(Builder.TakeString())); - if(llvm::isa<clang::RequiresExprBodyDecl>(SemaRef.CurContext)){ + if (llvm::isa<clang::RequiresExprBodyDecl>(SemaRef.CurContext)) { // requires expression ; - Builder.AddResultTypeChunk(""); Builder.AddTypedTextChunk("requires"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("expression"); >From c8e555f7454a913346fa90dec213e2a26f70a1ba Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Tue, 10 Sep 2024 17:13:56 +0800 Subject: [PATCH 04/16] format and add test. --- clang/lib/Sema/SemaCodeComplete.cpp | 8 ++--- clang/test/CodeCompletion/keywords-cxx20.cpp | 35 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeCompletion/keywords-cxx20.cpp diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 1c815d170cdfb0..710287e8ce5e5c 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2265,7 +2265,7 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, [[fallthrough]]; case SemaCodeCompletion::PCC_Template: - if (SemaRef.getLangOpts().CPlusPlus20 && + if (SemaRef.getLangOpts().CPlusPlus20 && CCC == SemaCodeCompletion::PCC_Template) Results.AddResult(Result("concept", CCP_Keyword)); [[fallthrough]]; @@ -2282,9 +2282,9 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword)); } - if(SemaRef.getLangOpts().CPlusPlus20 && - (CCC == SemaCodeCompletion::PCC_Template || - CCC == SemaCodeCompletion::PCC_MemberTemplate)) { + if (SemaRef.getLangOpts().CPlusPlus20 && + (CCC == SemaCodeCompletion::PCC_Template || + CCC == SemaCodeCompletion::PCC_MemberTemplate)) { Results.AddResult(Result("requires", CCP_Keyword)); } diff --git a/clang/test/CodeCompletion/keywords-cxx20.cpp b/clang/test/CodeCompletion/keywords-cxx20.cpp new file mode 100644 index 00000000000000..6cc236388437cc --- /dev/null +++ b/clang/test/CodeCompletion/keywords-cxx20.cpp @@ -0,0 +1,35 @@ +const char8_t x = 1; + +template<typename T> requires true +const int y = requires { typename T::type; requires T::value; }; + +int f(){ co_await 1; } + +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:1:3 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s +// CHECK-TOP-LEVEL: const +// CHECK-TOP-LEVEL: consteval +// CHECK-TOP-LEVEL: constexpr +// CHECK-TOP-LEVEL: constinit + +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:1:12 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s +// CHECK-TOP-LEVEL: char8_t + +// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:4:3 %s | FileCheck --check-prefix=CHECK-REQUIRES %s +// CHECK-REQUIRES: concept +// CHECK-REQUIRES: const +// CHECK-REQUIRES: consteval +// CHECK-REQUIRES: constexpr +// CHECK-REQUIRES: constinit + +// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:3:27 %s | FileCheck --check-prefix=CHECK-REQUIRES %s +// CHECK-REQUIRES: requires + +// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:4:20 %s | FileCheck -check-prefix=CHECK-CC1 %s +// CHECK-CC1-NEXT: COMPLETION: Pattern: [#bool#]requires (<#parameters#>) { +// CHECK-CC1-NEXT: <#requirements#> +// CHECK-CC1-NEXT: } + +// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:6:13 %s | FileCheck --check-prefix=CHECK-COAWAIT %s +// CHECK-COAWAIT: Pattern : co_await <#expression#> +// CHECK-COAWAIT: Pattern : co_return <#expression#>; +// CHECK-COAWAIT: Pattern : co_yield <#expression#> \ No newline at end of file >From 0375e5281c0748fd4903f091568909ef49aafc08 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Tue, 10 Sep 2024 17:22:28 +0800 Subject: [PATCH 05/16] fix. --- clang/lib/Sema/SemaCodeComplete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 710287e8ce5e5c..9194e91a370b31 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2766,7 +2766,7 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, Builder.AddChunk(CodeCompletionString::CK_RightBrace); Results.AddResult(Result(Builder.TakeString())); - if (llvm::isa<clang::RequiresExprBodyDecl>(SemaRef.CurContext)) { + if (SemaRef.CurContext->isRequiresExprBody()) { // requires expression ; Builder.AddTypedTextChunk("requires"); Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); >From d9c641342db0b714604281681309233ee321f877 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Tue, 10 Sep 2024 18:19:26 +0800 Subject: [PATCH 06/16] add newline in eof. --- clang/test/CodeCompletion/keywords-cxx20.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CodeCompletion/keywords-cxx20.cpp b/clang/test/CodeCompletion/keywords-cxx20.cpp index 6cc236388437cc..c968e289a5d943 100644 --- a/clang/test/CodeCompletion/keywords-cxx20.cpp +++ b/clang/test/CodeCompletion/keywords-cxx20.cpp @@ -32,4 +32,4 @@ int f(){ co_await 1; } // RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:6:13 %s | FileCheck --check-prefix=CHECK-COAWAIT %s // CHECK-COAWAIT: Pattern : co_await <#expression#> // CHECK-COAWAIT: Pattern : co_return <#expression#>; -// CHECK-COAWAIT: Pattern : co_yield <#expression#> \ No newline at end of file +// CHECK-COAWAIT: Pattern : co_yield <#expression#> >From 37647823895b29914a27ba93321b3fbd4200cb11 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Mon, 23 Sep 2024 22:53:18 +0800 Subject: [PATCH 07/16] add module keyword and Char8. --- clang/lib/Sema/SemaCodeComplete.cpp | 41 ++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 9194e91a370b31..0b558b79218800 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1838,7 +1838,7 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Results.AddResult(Result(Builder.TakeString())); } - if (LangOpts.CPlusPlus20) { + if (LangOpts.Char8 || LangOpts.CPlusPlus20) { Results.AddResult(Result("char8_t", CCP_Type)); } } else @@ -2198,6 +2198,45 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, } else { Results.AddResult(Result("template", CodeCompletionResult::RK_Keyword)); } + + if (SemaRef.getLangOpts().CPlusPlus20 && + SemaRef.getLangOpts().CPlusPlusModules) { + // export + Results.AddResult(Result("export", CodeCompletionResult::RK_Keyword)); + + if (SemaRef.CurContext->isTranslationUnit()) { + // module; + Builder.AddTypedTextChunk("module"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Results.AddResult(Result(Builder.TakeString())); + + // 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())); + + // 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 module; + Builder.AddTypedTextChunk("import"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddPlaceholderChunk("module"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); + Results.AddResult(Result(Builder.TakeString())); + } + } } if (SemaRef.getLangOpts().ObjC) >From 2d7f4761605c620e1e841a395f836392212f7ddf Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Thu, 10 Oct 2024 22:26:58 +0800 Subject: [PATCH 08/16] Update ReleaseNote. --- clang-tools-extra/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 3f7bcde1eb3014..f1243cf731d85e 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -71,6 +71,8 @@ Hover Code completion ^^^^^^^^^^^^^^^ +- Added completion for C++20 keywords. + Code actions ^^^^^^^^^^^^ >From d48932797aecc43f8f5578094bd3a020e223ff68 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Fri, 11 Oct 2024 14:24:27 +0800 Subject: [PATCH 09/16] Remove extra braces. --- clang/lib/Sema/SemaCodeComplete.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index bc1fdfd0fdaaf9..7e7649ab2991e8 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1837,9 +1837,8 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, Results.AddResult(Result(Builder.TakeString())); } - if (LangOpts.Char8 || LangOpts.CPlusPlus20) { + if (LangOpts.Char8 || LangOpts.CPlusPlus20) Results.AddResult(Result("char8_t", CCP_Type)); - } } else Results.AddResult(Result("__auto_type", CCP_Type)); @@ -1893,9 +1892,8 @@ AddStorageSpecifiers(SemaCodeCompletion::ParserCompletionContext CCC, Results.AddResult(Result("thread_local")); } - if (LangOpts.CPlusPlus20) { + if (LangOpts.CPlusPlus20) Results.AddResult(Result("constinit")); - } } static void >From 5cc6a8f5a36d3e797375d7b227cfeed68093a3c0 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Fri, 11 Oct 2024 15:03:13 +0800 Subject: [PATCH 10/16] Update test file. --- clang/test/CodeCompletion/keywords-cxx20.cpp | 61 ++++++++++++-------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/clang/test/CodeCompletion/keywords-cxx20.cpp b/clang/test/CodeCompletion/keywords-cxx20.cpp index c968e289a5d943..1f98128c65c5e0 100644 --- a/clang/test/CodeCompletion/keywords-cxx20.cpp +++ b/clang/test/CodeCompletion/keywords-cxx20.cpp @@ -1,35 +1,50 @@ +module; + +export module M; + const char8_t x = 1; template<typename T> requires true const int y = requires { typename T::type; requires T::value; }; -int f(){ co_await 1; } +class co_test {}; + +int f(){ co_test test; return 1; } -// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:1:3 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s -// CHECK-TOP-LEVEL: const -// CHECK-TOP-LEVEL: consteval -// CHECK-TOP-LEVEL: constexpr -// CHECK-TOP-LEVEL: constinit +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:1:3 %s | FileCheck --check-prefix=CHECK-MODULE %s +// CHECK-MODULE: module; +// CHECK-MODULE: module: private; +// CHECK-MODULE: module <#name#>; -// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:1:12 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s -// CHECK-TOP-LEVEL: char8_t +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:3:3 %s | FileCheck --check-prefix=CHECK-EXPORT %s +// CHECK-EXPORT: export -// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:4:3 %s | FileCheck --check-prefix=CHECK-REQUIRES %s -// CHECK-REQUIRES: concept -// CHECK-REQUIRES: const -// CHECK-REQUIRES: consteval -// CHECK-REQUIRES: constexpr -// CHECK-REQUIRES: constinit +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:5:3 %s | FileCheck --check-prefix=CHECK-CONST %s +// CHECK-CONST: const +// CHECK-CONST: consteval +// CHECK-CONST: constexpr +// CHECK-CONST: constinit -// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:3:27 %s | FileCheck --check-prefix=CHECK-REQUIRES %s +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:5:12 %s | FileCheck --check-prefix=CHECK-CHAR %s +// CHECK-CHAR: char8_t + +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:8:3 %s | FileCheck --check-prefix=CHECK-CONSTRAINT %s +// CHECK-CONSTRAINT: concept +// CHECK-CONSTRAINT: const +// CHECK-CONSTRAINT: consteval +// CHECK-CONSTRAINT: constexpr +// CHECK-CONSTRAINT: constinit + +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:7:27 %s | FileCheck --check-prefix=CHECK-REQUIRES %s // CHECK-REQUIRES: requires -// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:4:20 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1-NEXT: COMPLETION: Pattern: [#bool#]requires (<#parameters#>) { -// CHECK-CC1-NEXT: <#requirements#> -// CHECK-CC1-NEXT: } +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:8:20 %s | FileCheck -check-prefix=CHECK-REQUIRE %s +// CHECK-REQUIRE: [#bool#]requires (<#parameters#>) { +// CHECK-REQUIRE: <#requirements#> +// CHECK-REQUIRE: } + +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:12:13 %s | FileCheck --check-prefix=CHECK-COROUTINE %s +// CHECK-COROUTINE: co_await <#expression#> +// CHECK-COROUTINE: co_return <#expression#>; +// CHECK-COROUTINE: co_yield <#expression#> -// RUN: %clang-cc1 -std=c++20 -code-completion-at=%s:6:13 %s | FileCheck --check-prefix=CHECK-COAWAIT %s -// CHECK-COAWAIT: Pattern : co_await <#expression#> -// CHECK-COAWAIT: Pattern : co_return <#expression#>; -// CHECK-COAWAIT: Pattern : co_yield <#expression#> >From 74b7c749705a62380a58746ead5f7a4cbff74fae Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Fri, 11 Oct 2024 15:51:44 +0800 Subject: [PATCH 11/16] Fix test. --- clang/test/CodeCompletion/keywords-cxx20.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeCompletion/keywords-cxx20.cpp b/clang/test/CodeCompletion/keywords-cxx20.cpp index 1f98128c65c5e0..567949204970e0 100644 --- a/clang/test/CodeCompletion/keywords-cxx20.cpp +++ b/clang/test/CodeCompletion/keywords-cxx20.cpp @@ -35,8 +35,8 @@ int f(){ co_test test; return 1; } // CHECK-CONSTRAINT: constexpr // CHECK-CONSTRAINT: constinit -// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:7:27 %s | FileCheck --check-prefix=CHECK-REQUIRES %s -// CHECK-REQUIRES: requires +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:7:27 %s | FileCheck --check-prefix=CHECK-REQUIRES2 %s +// CHECK-REQUIRES2: requires // RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:8:20 %s | FileCheck -check-prefix=CHECK-REQUIRE %s // CHECK-REQUIRE: [#bool#]requires (<#parameters#>) { >From cc758c5472967c5106fc345e97e4324385a38317 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Fri, 11 Oct 2024 17:52:08 +0800 Subject: [PATCH 12/16] Remove extra brace. --- clang/lib/Sema/SemaCodeComplete.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 7e7649ab2991e8..6bb388c6efacdc 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2320,9 +2320,8 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, if (SemaRef.getLangOpts().CPlusPlus20 && (CCC == SemaCodeCompletion::PCC_Template || - CCC == SemaCodeCompletion::PCC_MemberTemplate)) { + CCC == SemaCodeCompletion::PCC_MemberTemplate)) Results.AddResult(Result("requires", CCP_Keyword)); - } AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results); AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results); >From 15f6982f79fcace95637977ec3e86b1d8a150a98 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Fri, 11 Oct 2024 21:22:32 +0800 Subject: [PATCH 13/16] Make completion for module keyword more context sensitive. --- clang/lib/Sema/SemaCodeComplete.cpp | 84 +++++++++++++------- clang/test/CodeCompletion/keywords-cxx20.cpp | 12 ++- 2 files changed, 62 insertions(+), 34 deletions(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 6bb388c6efacdc..94883554f719f2 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2198,41 +2198,65 @@ AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC, if (SemaRef.getLangOpts().CPlusPlus20 && SemaRef.getLangOpts().CPlusPlusModules) { - // export - Results.AddResult(Result("export", CodeCompletionResult::RK_Keyword)); - + clang::Module *CurrentModule = SemaRef.getCurrentModule(); if (SemaRef.CurContext->isTranslationUnit()) { - // module; - Builder.AddTypedTextChunk("module"); - Builder.AddChunk(CodeCompletionString::CK_SemiColon); - Builder.AddChunk(CodeCompletionString::CK_VerticalSpace); - Results.AddResult(Result(Builder.TakeString())); + /// 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())); + } - // 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())); + /// 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())); + } - // 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())); + } - // import module; - Builder.AddTypedTextChunk("import"); - Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); - Builder.AddPlaceholderChunk("module"); - 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)); } } diff --git a/clang/test/CodeCompletion/keywords-cxx20.cpp b/clang/test/CodeCompletion/keywords-cxx20.cpp index 567949204970e0..b8ffb6f618260f 100644 --- a/clang/test/CodeCompletion/keywords-cxx20.cpp +++ b/clang/test/CodeCompletion/keywords-cxx20.cpp @@ -11,10 +11,14 @@ class co_test {}; int f(){ co_test test; return 1; } -// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:1:3 %s | FileCheck --check-prefix=CHECK-MODULE %s -// CHECK-MODULE: module; -// CHECK-MODULE: module: private; -// CHECK-MODULE: module <#name#>; +module: private; + +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:1:3 %s | FileCheck --check-prefix=CHECK-MODULE1 %s +// CHECK-MODULE1: module; +// CHECK-MODULE1: module <#name#>; + +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:14:3 %s | FileCheck --check-prefix=CHECK-MODULE3 %s +// CHECK-MODULE3: module: private; // RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:3:3 %s | FileCheck --check-prefix=CHECK-EXPORT %s // CHECK-EXPORT: export >From b6218b6356cfaaddcc313d3b236b0f5666ec2c74 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Sat, 12 Oct 2024 18:25:01 +0800 Subject: [PATCH 14/16] Fix unexpected compiler error when code complete in `export mod^`. --- .clangd | 2 ++ clang/lib/Parse/ParseDeclCXX.cpp | 12 ++++++++++++ clang/test/CodeCompletion/keywords-cxx20.cpp | 9 ++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 .clangd diff --git a/.clangd b/.clangd new file mode 100644 index 00000000000000..7058e79de5e5ac --- /dev/null +++ b/.clangd @@ -0,0 +1,2 @@ +CompileFlags: + Add: [-std=c++20] \ No newline at end of file diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 6f0f5a0311bc18..caeadeb46c73ed 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -460,6 +460,18 @@ Decl *Parser::ParseExportDeclaration() { assert(Tok.is(tok::kw_export)); SourceLocation ExportLoc = ConsumeToken(); + if (Tok.is(tok::code_completion)) { + cutOffParsing(); + SemaCodeCompletion::ParserCompletionContext PCC; + if (PP.isIncrementalProcessingEnabled()) { + PCC = SemaCodeCompletion::PCC_TopLevelOrExpression; + } else { + PCC = SemaCodeCompletion::PCC_Namespace; + }; + Actions.CodeCompletion().CodeCompleteOrdinaryName(getCurScope(), PCC); + return nullptr; + } + ParseScope ExportScope(this, Scope::DeclScope); Decl *ExportDecl = Actions.ActOnStartExportDecl( getCurScope(), ExportLoc, diff --git a/clang/test/CodeCompletion/keywords-cxx20.cpp b/clang/test/CodeCompletion/keywords-cxx20.cpp index b8ffb6f618260f..612c3c0045e394 100644 --- a/clang/test/CodeCompletion/keywords-cxx20.cpp +++ b/clang/test/CodeCompletion/keywords-cxx20.cpp @@ -2,7 +2,7 @@ module; export module M; -const char8_t x = 1; +export const char8_t x = 1; template<typename T> requires true const int y = requires { typename T::type; requires T::value; }; @@ -17,19 +17,22 @@ module: private; // CHECK-MODULE1: module; // CHECK-MODULE1: module <#name#>; +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:3:11 %s | FileCheck --check-prefix=CHECK-MODULE2 %s +// CHECK-MODULE2: module <#name#>; + // RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:14:3 %s | FileCheck --check-prefix=CHECK-MODULE3 %s // CHECK-MODULE3: module: private; // RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:3:3 %s | FileCheck --check-prefix=CHECK-EXPORT %s // CHECK-EXPORT: export -// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:5:3 %s | FileCheck --check-prefix=CHECK-CONST %s +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:5:11 %s | FileCheck --check-prefix=CHECK-CONST %s // CHECK-CONST: const // CHECK-CONST: consteval // CHECK-CONST: constexpr // CHECK-CONST: constinit -// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:5:12 %s | FileCheck --check-prefix=CHECK-CHAR %s +// RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:5:19 %s | FileCheck --check-prefix=CHECK-CHAR %s // CHECK-CHAR: char8_t // RUN: %clang_cc1 -std=c++20 -code-completion-at=%s:8:3 %s | FileCheck --check-prefix=CHECK-CONSTRAINT %s >From 75bb471f087645f1262c1e297e400ca649118408 Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Sat, 12 Oct 2024 18:29:50 +0800 Subject: [PATCH 15/16] Remove `.clangd`. --- .clangd | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 .clangd diff --git a/.clangd b/.clangd deleted file mode 100644 index 7058e79de5e5ac..00000000000000 --- a/.clangd +++ /dev/null @@ -1,2 +0,0 @@ -CompileFlags: - Add: [-std=c++20] \ No newline at end of file >From 68cd2926c6c0333dd8ee1fc9ac35ab492eedd59c Mon Sep 17 00:00:00 2001 From: ykiko <ykikoykikoyk...@gmail.com> Date: Sat, 12 Oct 2024 18:35:34 +0800 Subject: [PATCH 16/16] Some format. --- clang/lib/Parse/ParseDeclCXX.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index caeadeb46c73ed..aa164a7260e0bc 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -462,13 +462,10 @@ Decl *Parser::ParseExportDeclaration() { if (Tok.is(tok::code_completion)) { cutOffParsing(); - SemaCodeCompletion::ParserCompletionContext PCC; - if (PP.isIncrementalProcessingEnabled()) { - PCC = SemaCodeCompletion::PCC_TopLevelOrExpression; - } else { - PCC = SemaCodeCompletion::PCC_Namespace; - }; - Actions.CodeCompletion().CodeCompleteOrdinaryName(getCurScope(), PCC); + Actions.CodeCompletion().CodeCompleteOrdinaryName( + getCurScope(), PP.isIncrementalProcessingEnabled() + ? SemaCodeCompletion::PCC_TopLevelOrExpression + : SemaCodeCompletion::PCC_Namespace); return nullptr; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits