From d2d8be6a27d0ef73d46039604682f7890e1cc3e0 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Sat, 30 Jul 2011 08:36:53 +0000 Subject: [PATCH] Add code completion to produce "else" blocks after an "if" statement. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136564 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 1 + lib/Parse/ParseStmt.cpp | 3 ++ lib/Sema/SemaCodeComplete.cpp | 55 +++++++++++++++++++++++++++++++++++ test/Index/complete-stmt.c | 12 ++++++++ 4 files changed, 71 insertions(+) create mode 100644 test/Index/complete-stmt.c diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index cbb096d9c5..f15ebc6438 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5824,6 +5824,7 @@ public: void CodeCompleteCall(Scope *S, Expr *Fn, Expr **Args, unsigned NumArgs); void CodeCompleteInitializer(Scope *S, Decl *D); void CodeCompleteReturn(Scope *S); + void CodeCompleteAfterIf(Scope *S); void CodeCompleteAssignmentRHS(Scope *S, Expr *LHS); void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index b34e4f8277..d57e527990 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -953,6 +953,9 @@ StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs) { // Pop the 'else' scope if needed. InnerScope.Exit(); + } else if (Tok.is(tok::code_completion)) { + Actions.CodeCompleteAfterIf(getCurScope()); + ConsumeCodeCompletionToken(); } IfScope.Exit(); diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 9f5befd96e..5803a76600 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -3702,6 +3702,61 @@ void Sema::CodeCompleteReturn(Scope *S) { CodeCompleteExpression(S, ResultType); } +void Sema::CodeCompleteAfterIf(Scope *S) { + typedef CodeCompletionResult Result; + ResultBuilder Results(*this, CodeCompleter->getAllocator(), + mapCodeCompletionContext(*this, PCC_Statement)); + Results.setFilter(&ResultBuilder::IsOrdinaryName); + Results.EnterNewScope(); + + CodeCompletionDeclConsumer Consumer(Results, CurContext); + LookupVisibleDecls(S, LookupOrdinaryName, Consumer, + CodeCompleter->includeGlobals()); + + AddOrdinaryNameResults(PCC_Statement, S, *this, Results); + + // "else" block + CodeCompletionBuilder Builder(Results.getAllocator()); + Builder.AddTypedTextChunk("else"); + 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 if" block + Builder.AddTypedTextChunk("else"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddTextChunk("if"); + Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + Builder.AddChunk(CodeCompletionString::CK_LeftParen); + if (getLangOptions().CPlusPlus) + Builder.AddPlaceholderChunk("condition"); + else + Builder.AddPlaceholderChunk("expression"); + 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()); + + Results.ExitScope(); + + if (S->getFnParent()) + AddPrettyFunctionResults(PP.getLangOptions(), Results); + + if (CodeCompleter->includeMacros()) + AddMacroResults(PP, Results); + + HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(), + Results.data(),Results.size()); +} + void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) { if (LHS) CodeCompleteExpression(S, static_cast(LHS)->getType()); diff --git a/test/Index/complete-stmt.c b/test/Index/complete-stmt.c new file mode 100644 index 0000000000..98fa9df44d --- /dev/null +++ b/test/Index/complete-stmt.c @@ -0,0 +1,12 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + + +void f(int x) { + if (x) { + } +} + +// RUN: c-index-test -code-completion-at=%s:7:4 %s | FileCheck -check-prefix=CHECK-IF-ELSE %s +// CHECK-IF-ELSE: NotImplemented:{TypedText else}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Placeholder statements}{VerticalSpace }{RightBrace }} (40) +// CHECK-IF-ELSE: NotImplemented:{TypedText else}{HorizontalSpace }{Text if}{HorizontalSpace }{LeftParen (}{Placeholder expression}{RightParen )}{HorizontalSpace }{LeftBrace {}{VerticalSpace }{Placeholder statements}{VerticalSpace }{RightBrace }} (40) -- 2.40.0