[clang] Add code completion for C++20 keywords. (PR #107982)

via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 10 01:17:39 PDT 2024


https://github.com/16bit-ykiko created https://github.com/llvm/llvm-project/pull/107982

This commit adds code completion for C++20 keywords.

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`


>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/2] 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/2] 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;



More information about the cfe-commits mailing list