From 67da50e18dbc93dbc8b70c4270379ea7ca30067f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 8 Sep 2010 22:47:51 +0000 Subject: [PATCH] When providing a completion for a function/method parameter of block pointer type, actually provide a usable block literal expression. llvm-svn: 113431 --- clang/lib/Sema/SemaCodeComplete.cpp | 37 ++++++++++++++++------------- clang/test/Index/complete-blocks.m | 19 +++++++++++---- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index c367d52704bb..d8c2c4ff207a 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1830,23 +1830,28 @@ static std::string FormatFunctionParameter(ASTContext &Context, // We have the function prototype behind the block pointer type, as it was // written in the source. - std::string Result = "(^)("; - for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) { - if (I) - Result += ", "; - Result += FormatFunctionParameter(Context, Block->getArg(I)); - - if (I == N - 1 && Block->getTypePtr()->isVariadic()) - Result += ", ..."; + std::string Result; + QualType ResultType = Block->getTypePtr()->getResultType(); + if (!ResultType->isVoidType()) + ResultType.getAsStringInternal(Result, Context.PrintingPolicy); + + Result = '^' + Result; + if (Block->getNumArgs() == 0) { + if (Block->getTypePtr()->isVariadic()) + Result += "(...)"; + } else { + Result += "("; + for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) { + if (I) + Result += ", "; + Result += FormatFunctionParameter(Context, Block->getArg(I)); + + if (I == N - 1 && Block->getTypePtr()->isVariadic()) + Result += ", ..."; + } + Result += ")"; } - if (Block->getTypePtr()->isVariadic() && Block->getNumArgs() == 0) - Result += "..."; - else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus) - Result += "void"; - - Result += ")"; - Block->getTypePtr()->getResultType().getAsStringInternal(Result, - Context.PrintingPolicy); + return Result; } diff --git a/clang/test/Index/complete-blocks.m b/clang/test/Index/complete-blocks.m index 7233efb8b00f..ef96c09efde3 100644 --- a/clang/test/Index/complete-blocks.m +++ b/clang/test/Index/complete-blocks.m @@ -16,9 +16,20 @@ void test_f() { void test_A(A *a) { [a method:0]; } + +@interface B +- method3:(int (^)(void))b; +@end + +void test_B(B *b) { + [b method3:^int(void){ return 0; }]; +} + // RUN: c-index-test -code-completion-at=%s:8:1 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder int (^)(int x, int y)}{RightParen )} (45) -// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText g}{LeftParen (}{Placeholder void (^)(float f, double d)}{RightParen )} (45) +// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder ^int(int x, int y)}{RightParen )} (45) +// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText g}{LeftParen (}{Placeholder ^(float f, double d)}{RightParen )} (45) // RUN: c-index-test -code-completion-at=%s:17:6 %s | FileCheck -check-prefix=CHECK-CC2 %s -// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText method2:}{Placeholder void (^)(float f, double d)} (20) -// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText method:}{Placeholder int (^)(int x, int y)} (20) +// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText method2:}{Placeholder ^(float f, double d)} (20) +// CHECK-CC2: ObjCInstanceMethodDecl:{ResultType id}{TypedText method:}{Placeholder ^int(int x, int y)} (20) +// RUN: c-index-test -code-completion-at=%s:25:6 %s | FileCheck -check-prefix=CHECK-CC3 %s +// CHECK-CC3: ObjCInstanceMethodDecl:{ResultType id}{TypedText method3:}{Placeholder ^int} (20)