Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -3753,6 +3753,19 @@ LookupVisibleDecls(Class, LookupMemberName, Consumer, CodeCompleter->includeGlobals()); } + } else if (const ObjCObjectPointerType *ObjCPtr = + BaseType->getAs()) { + if (const ObjCObjectType *ObjCObj = ObjCPtr->getObjectType()) { + if (!IsArrow && ObjCObj->isObjCQualifiedId()) { + AddedPropertiesSet AddedProperties; + // Add properties from the protocols in a qualified id. + for (ObjCProtocolDecl *P : ObjCObj->quals()) { + AddObjCProperties(CCContext, P, /*AllowCategories=*/true, + /*AllowNullaryMethods=*/true, CurContext, + AddedProperties, Results); + } + } + } } // FIXME: How do we cope with isa? Index: test/CodeCompletion/objc-protocol-member-access.m =================================================================== --- /dev/null +++ test/CodeCompletion/objc-protocol-member-access.m @@ -0,0 +1,24 @@ +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + +@protocol Bar +@property (readonly) int bar; +@end + +@protocol Foo + +@property (nonatomic, readonly) int foo; +- (void)foobar: (int)x; + +@end + +int getFoo(id object) { + id modelObject = (id)object; + int foo = modelObject.; + return foo; +} + +// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:17:25 %s -o - | FileCheck %s +// CHECK: bar : [#int#]bar +// CHECK: foo : [#int#]foo +// CHECK-NOT: foobar