From: Douglas Gregor Date: Thu, 14 Apr 2011 20:33:34 +0000 (+0000) Subject: When determining the "usage" type of a declaration for the purposes of code X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e64d56185f0bf7dbd536c1b3ecbc853c22a9184;p=clang When determining the "usage" type of a declaration for the purposes of code completion, look through block pointer and function pointer types to the result type of the block/function. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129535 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 75253b5b30..12ce270c74 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -667,8 +667,39 @@ QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) { T = Value->getType(); else return QualType(); - - return T.getNonReferenceType(); + + // Dig through references, function pointers, and block pointers to + // get down to the likely type of an expression when the entity is + // used. + do { + if (const ReferenceType *Ref = T->getAs()) { + T = Ref->getPointeeType(); + continue; + } + + if (const PointerType *Pointer = T->getAs()) { + if (Pointer->getPointeeType()->isFunctionType()) { + T = Pointer->getPointeeType(); + continue; + } + + break; + } + + if (const BlockPointerType *Block = T->getAs()) { + T = Block->getPointeeType(); + continue; + } + + if (const FunctionType *Function = T->getAs()) { + T = Function->getResultType(); + continue; + } + + break; + } while (true); + + return T; } void ResultBuilder::AdjustResultPriorityForDecl(Result &R) { diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m index 0658d53c65..0ea3385056 100644 --- a/test/Index/complete-objc-message.m +++ b/test/Index/complete-objc-message.m @@ -175,6 +175,12 @@ void test_missing_open_more() { A *a = A class_method3]; } +void test_block_invoke(A *(^block1)(int), + int (^block2)(int), + id (^block3)(int)) { + [block1(5) init]; +} + // RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: {TypedText categoryClassMethod} // CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)}{HorizontalSpace }{TypedText withKeyword:}{Placeholder (int)} @@ -285,6 +291,12 @@ void test_missing_open_more() { // CHECK-CLASS-RESULT: ObjCClassMethodDecl:{ResultType void}{TypedText class_method3} (35) // CHECK-CLASS-RESULT: ObjCClassMethodDecl:{ResultType void}{TypedText class_method4} (35) +// RUN: c-index-test -code-completion-at=%s:181:4 %s | FileCheck -check-prefix=CHECK-BLOCK-RECEIVER %s +// CHECK-BLOCK-RECEIVER: ObjCInterfaceDecl:{TypedText A} (50) +// CHECK-BLOCK-RECEIVER: ObjCInterfaceDecl:{TypedText B} (50) +// CHECK-BLOCK-RECEIVER: ParmDecl:{ResultType A *(^)(int)}{TypedText block1} (34) +// CHECK-BLOCK-RECEIVER-NEXT: ParmDecl:{ResultType id (^)(int)}{TypedText block3} (34) + // Test code completion with a missing opening bracket: // RUN: c-index-test -code-completion-at=%s:135:5 %s | FileCheck -check-prefix=CHECK-CCI %s // RUN: c-index-test -code-completion-at=%s:139:7 %s | FileCheck -check-prefix=CHECK-CC7 %s