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