aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-04-14 20:33:34 +0000
committerDouglas Gregor <dgregor@apple.com>2011-04-14 20:33:34 +0000
commit3e64d56185f0bf7dbd536c1b3ecbc853c22a9184 (patch)
tree5073ecdb1543053b3a53481f97da83b00e6dff19
parent414d8967e1d760ea1e19a4aca96b13777a8cf8c5 (diff)
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 <rdar://problem/9282583>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129535 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaCodeComplete.cpp35
-rw-r--r--test/Index/complete-objc-message.m12
2 files changed, 45 insertions, 2 deletions
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<ReferenceType>()) {
+ T = Ref->getPointeeType();
+ continue;
+ }
+
+ if (const PointerType *Pointer = T->getAs<PointerType>()) {
+ if (Pointer->getPointeeType()->isFunctionType()) {
+ T = Pointer->getPointeeType();
+ continue;
+ }
+
+ break;
+ }
+
+ if (const BlockPointerType *Block = T->getAs<BlockPointerType>()) {
+ T = Block->getPointeeType();
+ continue;
+ }
+
+ if (const FunctionType *Function = T->getAs<FunctionType>()) {
+ 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