[clang] Add code completion for C++20 keywords. (PR #107982)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 10 02:14:33 PDT 2024
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 <ykikoykikoykiko at gmail.com>
Date: Tue, 10 Sep 2024 14:59:10 +0800
Subject: [PATCH 1/4] 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 <ykikoykikoykiko at gmail.com>
Date: Tue, 10 Sep 2024 15:50:04 +0800
Subject: [PATCH 2/4] 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 <ykikoykikoykiko at gmail.com>
Date: Tue, 10 Sep 2024 16:50:34 +0800
Subject: [PATCH 3/4] 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 <ykikoykikoykiko at gmail.com>
Date: Tue, 10 Sep 2024 17:13:56 +0800
Subject: [PATCH 4/4] 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
More information about the cfe-commits
mailing list