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: } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits