[clang] 009d362 - [clang][CodeComplete] Add code completion for if constexpr and consteval (#124315)

via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 16 23:45:22 PDT 2025


Author: Letu Ren
Date: 2025-03-17T02:45:19-04:00
New Revision: 009d36222cfdb59f49597e01d157ca4f65ac9295

URL: https://github.com/llvm/llvm-project/commit/009d36222cfdb59f49597e01d157ca4f65ac9295
DIFF: https://github.com/llvm/llvm-project/commit/009d36222cfdb59f49597e01d157ca4f65ac9295.diff

LOG: [clang][CodeComplete] Add code completion for if constexpr and consteval (#124315)

Code complete `constexpr` and `consteval` keywords after `if` in the
relevant language modes. If pattern completion is enabled, the
completions also include placeholders for the condition (in the case
of `constexpr`) and statement block.

Added: 
    clang/test/CodeCompletion/if-const.cpp

Modified: 
    clang/include/clang/Sema/SemaCodeCompletion.h
    clang/lib/Parse/ParseStmt.cpp
    clang/lib/Sema/SemaCodeComplete.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Sema/SemaCodeCompletion.h b/clang/include/clang/Sema/SemaCodeCompletion.h
index e931596c215d3..72159de3a6e72 100644
--- a/clang/include/clang/Sema/SemaCodeCompletion.h
+++ b/clang/include/clang/Sema/SemaCodeCompletion.h
@@ -152,6 +152,7 @@ class SemaCodeCompletion : public SemaBase {
   void CodeCompleteDesignator(const QualType BaseType,
                               llvm::ArrayRef<Expr *> InitExprs,
                               const Designation &D);
+  void CodeCompleteKeywordAfterIf(bool AfterExclaim) const;
   void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
 
   void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext,

diff  --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index cd4504630f871..623b4c799327c 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1552,6 +1552,11 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
                                           : diag::ext_consteval_if);
       IsConsteval = true;
       ConstevalLoc = ConsumeToken();
+    } else if (Tok.is(tok::code_completion)) {
+      cutOffParsing();
+      Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
+          NotLocation.isValid());
+      return StmtError();
     }
   }
   if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {

diff  --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index db467d76b5d32..2003701b65654 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6749,6 +6749,52 @@ void SemaCodeCompletion::CodeCompleteInitializer(Scope *S, Decl *D) {
   CodeCompleteExpression(S, Data);
 }
 
+void SemaCodeCompletion::CodeCompleteKeywordAfterIf(bool AfterExclaim) const {
+  ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
+                        CodeCompletionContext::CCC_Other);
+  CodeCompletionBuilder Builder(Results.getAllocator(),
+                                Results.getCodeCompletionTUInfo());
+  if (getLangOpts().CPlusPlus17) {
+    if (!AfterExclaim) {
+      if (Results.includeCodePatterns()) {
+        Builder.AddTypedTextChunk("constexpr");
+        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+        Builder.AddPlaceholderChunk("condition");
+        Builder.AddChunk(CodeCompletionString::CK_RightParen);
+        Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+        Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
+        Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+        Builder.AddPlaceholderChunk("statements");
+        Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+        Builder.AddChunk(CodeCompletionString::CK_RightBrace);
+        Results.AddResult({Builder.TakeString()});
+      } else {
+        Results.AddResult({"constexpr"});
+      }
+    }
+  }
+  if (getLangOpts().CPlusPlus23) {
+    if (Results.includeCodePatterns()) {
+      Builder.AddTypedTextChunk("consteval");
+      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
+      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Builder.AddPlaceholderChunk("statements");
+      Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+      Builder.AddChunk(CodeCompletionString::CK_RightBrace);
+      Results.AddResult({Builder.TakeString()});
+    } else {
+      Results.AddResult({"consteval"});
+    }
+  }
+
+  HandleCodeCompleteResults(&SemaRef, CodeCompleter,
+                            Results.getCompletionContext(), Results.data(),
+                            Results.size());
+}
+
 void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
   ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(),

diff  --git a/clang/test/CodeCompletion/if-const.cpp b/clang/test/CodeCompletion/if-const.cpp
new file mode 100644
index 0000000000000..4839798faf719
--- /dev/null
+++ b/clang/test/CodeCompletion/if-const.cpp
@@ -0,0 +1,30 @@
+template <bool Flag>
+void test() {
+  if constexpr (Flag) {
+    return;
+  }
+  // RUN: %clang_cc1 -fsyntax-only -std=c++17 -code-completion-at=%s:3:7 %s | FileCheck -check-prefix=CHECK-CXX17 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++17 -code-completion-patterns -code-completion-at=%s:3:7 %s | FileCheck -check-prefix=CHECK-PATTERN-CXX17 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++23 -code-completion-at=%s:3:7 %s | FileCheck -check-prefix=CHECK-CXX23 %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++23 -code-completion-patterns -code-completion-at=%s:3:7 %s | FileCheck -check-prefix=CHECK-PATTERN-CXX23 %s
+  // CHECK-CXX17: COMPLETION: constexpr
+  // CHECK-PATTERN-CXX17: COMPLETION: Pattern : constexpr (<#condition#>) {
+  // CHECK-PATTERN-CXX17: <#statements#>
+  // CHECK-PATTERN-CXX17: }
+  // CHECK-CXX23: COMPLETION: consteval
+  // CHECK-CXX23: COMPLETION: constexpr
+  // CHECK-PATTERN-CXX23: COMPLETION: Pattern : consteval {
+  // CHECK-PATTERN-CXX23: <#statements#>
+  // CHECK-PATTERN-CXX23: }
+  // CHECK-PATTERN-CXX23: COMPLETION: Pattern : constexpr (<#condition#>) {
+  // CHECK-PATTERN-CXX23: <#statements#>
+  // CHECK-PATTERN-CXX23: }
+  if !c
+  // RUN: %clang_cc1 -fsyntax-only -std=c++23 -code-completion-at=%s:22:8 %s -o - | FileCheck -check-prefix=CHECK-CXX23-EXCLAIM %s
+  // RUN: %clang_cc1 -fsyntax-only -std=c++23 -code-completion-patterns -code-completion-at=%s:22:8 %s -o - | FileCheck -check-prefix=CHECK-PATTERN-CXX23-EXCLAIM %s
+  // CHECK-CXX23-EXCLAIM: COMPLETION: consteval
+  // CHECK-CXX23-EXCLAIM-NOT: constexpr
+  // CHECK-PATTERN-CXX23-EXCLAIM: COMPLETION: Pattern : consteval {
+  // CHECK-PATTERN-CXX23-EXCLAIM: <#statements#>
+  // CHECK-PATTERN-CXX23-EXCLAIM: }
+}


        


More information about the cfe-commits mailing list