Skip to content

[clang][CodeComplete] Add code completion for if constexpr and consteval #124315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Mar 17, 2025

Conversation

FantasqueX
Copy link
Contributor

@FantasqueX FantasqueX commented Jan 24, 2025

C++17 supports if constexpr statement. C++23 supports if consteval statement. This patch implements this in code completion.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 24, 2025

@llvm/pr-subscribers-clang

Author: FantasqueX (FantasqueX)

Changes

C++17 supports if constexpr statement. This patch implements this in code completion.


Full diff: https://github.com/llvm/llvm-project/pull/124315.diff

3 Files Affected:

  • (modified) clang/include/clang/Sema/SemaCodeCompletion.h (+1)
  • (modified) clang/lib/Parse/ParseStmt.cpp (+8)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+15)
diff --git a/clang/include/clang/Sema/SemaCodeCompletion.h b/clang/include/clang/Sema/SemaCodeCompletion.h
index e931596c215d31..af44745d5d1239 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 CodeCompleteIfConstExpr(Scope *S) 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 cd4504630f8719..3f9900dd997ada 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1553,6 +1553,14 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
       IsConsteval = true;
       ConstevalLoc = ConsumeToken();
     }
+
+    if (Tok.is(tok::code_completion)) {
+      if (getLangOpts().CPlusPlus17) {
+        cutOffParsing();
+        Actions.CodeCompletion().CodeCompleteIfConstExpr(getCurScope());
+        return StmtError();
+      }
+    }
   }
   if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {
     Diag(Tok, diag::err_expected_lparen_after) << "if";
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 58f3efbe0daf89..b159fd26a45208 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6762,6 +6762,21 @@ void SemaCodeCompletion::CodeCompleteInitializer(Scope *S, Decl *D) {
   CodeCompleteExpression(S, Data);
 }
 
+void SemaCodeCompletion::CodeCompleteIfConstExpr(Scope *S) const {
+  ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
+                        CodeCompletionContext::CCC_SymbolOrNewName);
+  Results.EnterNewScope();
+
+  Results.AddResult(CodeCompletionResult("constexpr"));
+
+  Results.ExitScope();
+
+  HandleCodeCompleteResults(&SemaRef, CodeCompleter,
+                            Results.getCompletionContext(), Results.data(),
+                            Results.size());
+}
+
 void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
   ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(),

@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch from 47f97a5 to 0715933 Compare January 31, 2025 10:31
@FantasqueX FantasqueX changed the title [clangd] Add code completion for if constexpr [Sema] Add code completion for if constexpr Jan 31, 2025
Copy link
Member

@Lancern Lancern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! Please add a test for your patch. You can take tests under clang/test/CodeCompletion for reference.

@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch from 0715933 to d276c4a Compare February 3, 2025 14:51
@FantasqueX FantasqueX requested a review from Lancern February 3, 2025 14:52
@Lancern Lancern requested a review from kadircet February 11, 2025 04:23
Copy link
Member

@Lancern Lancern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch 2 times, most recently from c8998ac to e6d79ad Compare February 15, 2025 10:19
@FantasqueX FantasqueX requested a review from zyn0217 February 15, 2025 11:13
@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch from 6ae8c5a to dcb660f Compare February 17, 2025 12:48
@FantasqueX FantasqueX changed the title [Sema] Add code completion for if constexpr [Sema] Add code completion for if constexpr and consteval Feb 17, 2025
@HighCommander4
Copy link
Collaborator

If I'm understanding correctly, this patch only completes the keywords themselves.

SemaCodeComplete also has the ability to produce "snippets", for example here is a snippet for if statements. In such a case, the inserted text is if (condition) { statements }, with condition and statements being marked as placeholders (in editors with snippet support, the cursor will jump to the placeholders to allow you to type over them).

What do you think about adding similar snippets for if constexpr and if consteval?

@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch from dcb660f to 914e63c Compare February 23, 2025 17:20
Copy link

github-actions bot commented Feb 23, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@FantasqueX
Copy link
Contributor Author

Hi @HighCommander4 thanks for your suggestions. I'm happy to add snippets support for if constexpr and if consteval. Since if <any number white space> constexp and if !consteval is valid, I decided to add code snippet completion in the specific code completion function instead of in statement completion. Do you think it is OK?

@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch from d0d3984 to e488453 Compare February 25, 2025 06:13
@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch from e488453 to 144facd Compare March 7, 2025 16:51
@FantasqueX FantasqueX changed the title [Sema] Add code completion for if constexpr and consteval [clang][CodeComplete] Add code completion for if constexpr and consteval Mar 7, 2025
Copy link
Collaborator

@HighCommander4 HighCommander4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I tried out the patch with clangd and it seems to be working pretty well.

A further enhancement that occurs to me is that we could offer these patterns slightly earlier, e.g. when you're at the beginning of an empty line and invoke code completion and then type if to filter the results, you see the if (condition) {statements} pattern as the first result -- we could have if constexpr (condition) {statements} as another result there already. But that can be a future enhancement for another time.

The implementation looks pretty good, just have some minor comments.

bool AfterExclaim) const {
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(),
CodeCompletionContext::CCC_Other);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the similar function CodeCompleteAfterIf, I think mapCodeCompletionContext(SemaRef, PCC_Statement) would be more appropriate here than CodeCompletionContext::CCC_Other

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
I think they are different. In CodeCompleteAfterIf, it's valid to provide a statement. While in the new added CodeCompleteKeywordAfterIf only two keywords are appropriate.

C++17 supports `if constexpr` statement. This patch implements this in
code completion.
@FantasqueX FantasqueX force-pushed the code-complete-if-constexpr branch from 144facd to f49496e Compare March 13, 2025 08:14
@FantasqueX
Copy link
Contributor Author

@HighCommander4 @zyn0217 Really appreciate for your review. Thanks a lot.

Copy link
Collaborator

@HighCommander4 HighCommander4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM!

@HighCommander4 HighCommander4 merged commit 009d362 into llvm:main Mar 17, 2025
11 checks passed
@FantasqueX FantasqueX deleted the code-complete-if-constexpr branch March 17, 2025 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants