[clang] 8ba4867 - [CodeComplete] Tweak completion for else.
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 30 08:48:31 PDT 2020
Author: Nathan James
Date: 2020-06-30T16:48:24+01:00
New Revision: 8ba4867c27000ee029ab70a1194050d884fce6c7
URL: https://github.com/llvm/llvm-project/commit/8ba4867c27000ee029ab70a1194050d884fce6c7
DIFF: https://github.com/llvm/llvm-project/commit/8ba4867c27000ee029ab70a1194050d884fce6c7.diff
LOG: [CodeComplete] Tweak completion for else.
If an `if` statement uses braces for its `then` block, suggest braces for the `else` and `else if` completion blocks, Otherwise don't suggest them.
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D82626
Added:
Modified:
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseStmt.cpp
clang/lib/Sema/SemaCodeComplete.cpp
clang/test/CodeCompletion/patterns.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 24ceceeb69d0..77eda3b25c83 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11980,7 +11980,7 @@ class Sema final {
void CodeCompleteDesignator(const QualType BaseType,
llvm::ArrayRef<Expr *> InitExprs,
const Designation &D);
- void CodeCompleteAfterIf(Scope *S);
+ void CodeCompleteAfterIf(Scope *S, bool IsBracedThen);
void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext,
bool IsUsingDeclaration, QualType BaseType,
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 773c31ff3aec..3299a059c437 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1348,6 +1348,8 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
if (IsConstexpr)
ConstexprCondition = Cond.getKnownValue();
+ bool IsBracedThen = Tok.is(tok::l_brace);
+
// C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do this
// if the body isn't a compound statement to avoid push/pop in common cases.
@@ -1366,7 +1368,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
// would have to notify ParseStatement not to create a new scope. It's
// simpler to let it create a new scope.
//
- ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
+ ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, IsBracedThen);
MisleadingIndentationChecker MIChecker(*this, MSK_if, IfLoc);
@@ -1427,7 +1429,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
// Pop the 'else' scope if needed.
InnerScope.Exit();
} else if (Tok.is(tok::code_completion)) {
- Actions.CodeCompleteAfterIf(getCurScope());
+ Actions.CodeCompleteAfterIf(getCurScope(), IsBracedThen);
cutOffParsing();
return StmtError();
} else if (InnerStatementTrailingElseLoc.isValid()) {
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index a96ea1e69bcc..26d127e1262f 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5759,7 +5759,7 @@ void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
CodeCompleteExpression(S, Data);
}
-void Sema::CodeCompleteAfterIf(Scope *S) {
+void Sema::CodeCompleteAfterIf(Scope *S, bool IsBracedThen) {
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompleter->getCodeCompletionTUInfo(),
mapCodeCompletionContext(*this, PCC_Statement));
@@ -5776,15 +5776,25 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
// "else" block
CodeCompletionBuilder Builder(Results.getAllocator(),
Results.getCodeCompletionTUInfo());
+
+ auto AddElseBodyPattern = [&] {
+ if (IsBracedThen) {
+ 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);
+ } else {
+ Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
+ Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+ Builder.AddPlaceholderChunk("statement");
+ Builder.AddChunk(CodeCompletionString::CK_SemiColon);
+ }
+ };
Builder.AddTypedTextChunk("else");
- if (Results.includeCodePatterns()) {
- 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);
- }
+ if (Results.includeCodePatterns())
+ AddElseBodyPattern();
Results.AddResult(Builder.TakeString());
// "else if" block
@@ -5797,12 +5807,7 @@ void Sema::CodeCompleteAfterIf(Scope *S) {
Builder.AddPlaceholderChunk("expression");
Builder.AddChunk(CodeCompletionString::CK_RightParen);
if (Results.includeCodePatterns()) {
- 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);
+ AddElseBodyPattern();
}
Results.AddResult(Builder.TakeString());
diff --git a/clang/test/CodeCompletion/patterns.cpp b/clang/test/CodeCompletion/patterns.cpp
index 5189e3e636d5..9d18ced8aa6d 100644
--- a/clang/test/CodeCompletion/patterns.cpp
+++ b/clang/test/CodeCompletion/patterns.cpp
@@ -74,3 +74,30 @@ int Cls::*memptr_return() {
// RUN: %clang_cc1 -fsyntax-only -std=c++03 -code-completion-patterns -code-completion-at=%s:37:1 %s -o - | FileCheck -check-prefix=RETURN-PTR-STD03 %s
// RUN: %clang_cc1 -fsyntax-only -std=c++03 -code-completion-patterns -code-completion-at=%s:41:1 %s -o - | FileCheck -check-prefix=RETURN-PTR-STD03 %s
// RETURN-PTR-STD03-NOT: COMPLETION: Pattern : return nullptr;
+
+void something();
+
+void unbraced_if() {
+ if (true)
+ something();
+ // line 83
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:83:3 %s -o - | FileCheck -check-prefix=UNBRACED-IF %s
+// UNBRACED-IF: COMPLETION: Pattern : else
+// UNBRACED-IF-NEXT: <#statement#>;
+// UNBRACED-IF: COMPLETION: Pattern : else if (<#condition#>)
+// UNBRACED-IF-NEXT: <#statement#>;
+
+void braced_if() {
+ if (true) {
+ something();
+ }
+ // line 95
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:95:3 %s -o - | FileCheck -check-prefix=BRACED-IF %s
+// BRACED-IF: COMPLETION: Pattern : else {
+// BRACED-IF-NEXT: <#statements#>
+// BRACED-IF-NEXT: }
+// BRACED-IF: COMPLETION: Pattern : else if (<#condition#>) {
+// BRACED-IF-NEXT: <#statements#>
+// BRACED-IF-NEXT: }
More information about the cfe-commits
mailing list