Skip to content

Commit 009d362

Browse files
authored
[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.
1 parent 6c867e2 commit 009d362

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

clang/include/clang/Sema/SemaCodeCompletion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ class SemaCodeCompletion : public SemaBase {
152152
void CodeCompleteDesignator(const QualType BaseType,
153153
llvm::ArrayRef<Expr *> InitExprs,
154154
const Designation &D);
155+
void CodeCompleteKeywordAfterIf(bool AfterExclaim) const;
155156
void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
156157

157158
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext,

clang/lib/Parse/ParseStmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,11 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
15521552
: diag::ext_consteval_if);
15531553
IsConsteval = true;
15541554
ConstevalLoc = ConsumeToken();
1555+
} else if (Tok.is(tok::code_completion)) {
1556+
cutOffParsing();
1557+
Actions.CodeCompletion().CodeCompleteKeywordAfterIf(
1558+
NotLocation.isValid());
1559+
return StmtError();
15551560
}
15561561
}
15571562
if (!IsConsteval && (NotLocation.isValid() || Tok.isNot(tok::l_paren))) {

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6749,6 +6749,52 @@ void SemaCodeCompletion::CodeCompleteInitializer(Scope *S, Decl *D) {
67496749
CodeCompleteExpression(S, Data);
67506750
}
67516751

6752+
void SemaCodeCompletion::CodeCompleteKeywordAfterIf(bool AfterExclaim) const {
6753+
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
6754+
CodeCompleter->getCodeCompletionTUInfo(),
6755+
CodeCompletionContext::CCC_Other);
6756+
CodeCompletionBuilder Builder(Results.getAllocator(),
6757+
Results.getCodeCompletionTUInfo());
6758+
if (getLangOpts().CPlusPlus17) {
6759+
if (!AfterExclaim) {
6760+
if (Results.includeCodePatterns()) {
6761+
Builder.AddTypedTextChunk("constexpr");
6762+
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6763+
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
6764+
Builder.AddPlaceholderChunk("condition");
6765+
Builder.AddChunk(CodeCompletionString::CK_RightParen);
6766+
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6767+
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6768+
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6769+
Builder.AddPlaceholderChunk("statements");
6770+
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6771+
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
6772+
Results.AddResult({Builder.TakeString()});
6773+
} else {
6774+
Results.AddResult({"constexpr"});
6775+
}
6776+
}
6777+
}
6778+
if (getLangOpts().CPlusPlus23) {
6779+
if (Results.includeCodePatterns()) {
6780+
Builder.AddTypedTextChunk("consteval");
6781+
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
6782+
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
6783+
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6784+
Builder.AddPlaceholderChunk("statements");
6785+
Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
6786+
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
6787+
Results.AddResult({Builder.TakeString()});
6788+
} else {
6789+
Results.AddResult({"consteval"});
6790+
}
6791+
}
6792+
6793+
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
6794+
Results.getCompletionContext(), Results.data(),
6795+
Results.size());
6796+
}
6797+
67526798
void SemaCodeCompletion::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
67536799
ResultBuilder Results(SemaRef, CodeCompleter->getAllocator(),
67546800
CodeCompleter->getCodeCompletionTUInfo(),
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
template <bool Flag>
2+
void test() {
3+
if constexpr (Flag) {
4+
return;
5+
}
6+
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -code-completion-at=%s:3:7 %s | FileCheck -check-prefix=CHECK-CXX17 %s
7+
// 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
8+
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -code-completion-at=%s:3:7 %s | FileCheck -check-prefix=CHECK-CXX23 %s
9+
// 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
10+
// CHECK-CXX17: COMPLETION: constexpr
11+
// CHECK-PATTERN-CXX17: COMPLETION: Pattern : constexpr (<#condition#>) {
12+
// CHECK-PATTERN-CXX17: <#statements#>
13+
// CHECK-PATTERN-CXX17: }
14+
// CHECK-CXX23: COMPLETION: consteval
15+
// CHECK-CXX23: COMPLETION: constexpr
16+
// CHECK-PATTERN-CXX23: COMPLETION: Pattern : consteval {
17+
// CHECK-PATTERN-CXX23: <#statements#>
18+
// CHECK-PATTERN-CXX23: }
19+
// CHECK-PATTERN-CXX23: COMPLETION: Pattern : constexpr (<#condition#>) {
20+
// CHECK-PATTERN-CXX23: <#statements#>
21+
// CHECK-PATTERN-CXX23: }
22+
if !c
23+
// RUN: %clang_cc1 -fsyntax-only -std=c++23 -code-completion-at=%s:22:8 %s -o - | FileCheck -check-prefix=CHECK-CXX23-EXCLAIM %s
24+
// 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
25+
// CHECK-CXX23-EXCLAIM: COMPLETION: consteval
26+
// CHECK-CXX23-EXCLAIM-NOT: constexpr
27+
// CHECK-PATTERN-CXX23-EXCLAIM: COMPLETION: Pattern : consteval {
28+
// CHECK-PATTERN-CXX23-EXCLAIM: <#statements#>
29+
// CHECK-PATTERN-CXX23-EXCLAIM: }
30+
}

0 commit comments

Comments
 (0)