diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2168,23 +2168,38 @@ Results.AddResult(Result(Builder.TakeString())); } - // "return expression ;" or "return ;", depending on whether we - // know the function is void or not. - bool isVoid = false; + // "return expression ;" or "return ;", depending on the return type. + QualType ReturnType; if (const auto *Function = dyn_cast(SemaRef.CurContext)) - isVoid = Function->getReturnType()->isVoidType(); + ReturnType = Function->getReturnType(); else if (const auto *Method = dyn_cast(SemaRef.CurContext)) - isVoid = Method->getReturnType()->isVoidType(); + ReturnType = Method->getReturnType(); else if (SemaRef.getCurBlock() && !SemaRef.getCurBlock()->ReturnType.isNull()) - isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType(); - Builder.AddTypedTextChunk("return"); - if (!isVoid) { - Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace); + ReturnType = SemaRef.getCurBlock()->ReturnType;; + if (ReturnType.isNull() || ReturnType->isVoidType()) { + Builder.AddTypedTextChunk("return"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Results.AddResult(Result(Builder.TakeString())); + } else { + assert(!ReturnType.isNull()); + // "return expression ;" + Builder.AddTypedTextChunk("return"); + Builder.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace); Builder.AddPlaceholderChunk("expression"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Results.AddResult(Result(Builder.TakeString())); + // When boolean, also add 'return true;' and 'return false;'. + if (ReturnType->isBooleanType()) { + Builder.AddTypedTextChunk("return true"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Results.AddResult(Result(Builder.TakeString())); + + Builder.AddTypedTextChunk("return false"); + Builder.AddChunk(CodeCompletionString::CK_SemiColon); + Results.AddResult(Result(Builder.TakeString())); + } } - Builder.AddChunk(CodeCompletionString::CK_SemiColon); - Results.AddResult(Result(Builder.TakeString())); // goto identifier ; Builder.AddTypedTextChunk("goto"); diff --git a/clang/test/CodeCompletion/patterns.cpp b/clang/test/CodeCompletion/patterns.cpp --- a/clang/test/CodeCompletion/patterns.cpp +++ b/clang/test/CodeCompletion/patterns.cpp @@ -30,10 +30,23 @@ void void_return() { // line 31 } +bool bool_return() { + // line 34 +} // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:28:1 %s -o - | FileCheck -check-prefix=RETURN-VAL %s -// RETURN-VAL-NOT: COMPLETION: Pattern : return;{{$}} +// RETURN-VAL-NOT: COMPLETION: Pattern : return; +// RETURN-VAL-NOT: COMPLETION: Pattern : return false; +// RETURN-VAL-NOT: COMPLETION: Pattern : return true; // RETURN-VAL: COMPLETION: Pattern : return <#expression#>;{{$}} // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:31:1 %s -o - | FileCheck -check-prefix=RETURN-VOID %s -// RETURN-VOID-NOT: COMPLETION: Pattern : return <#expression#>;{{$}} +// RETURN-VOID-NOT: COMPLETION: Pattern : return false; +// RETURN-VOID-NOT: COMPLETION: Pattern : return true; +// RETURN-VOID-NOT: COMPLETION: Pattern : return <#expression#>; // RETURN-VOID: COMPLETION: Pattern : return;{{$}} + +// RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:34:1 %s -o - | FileCheck -check-prefix=RETURN-BOOL %s +// RETURN-BOOL-NOT: COMPLETION: Pattern : return; +// RETURN-BOOL: COMPLETION: Pattern : return <#expression#>;{{$}} +// RETURN-BOOL: COMPLETION: Pattern : return false;{{$}} +// RETURN-BOOL: COMPLETION: Pattern : return true;{{$}}