Index: lib/Sema/SemaCodeComplete.cpp =================================================================== --- lib/Sema/SemaCodeComplete.cpp +++ lib/Sema/SemaCodeComplete.cpp @@ -3958,7 +3958,8 @@ const CodeCompletionContext &CCContext, ObjCContainerDecl *Container, bool AllowCategories, bool AllowNullaryMethods, DeclContext *CurContext, AddedPropertiesSet &AddedProperties, ResultBuilder &Results, - bool IsBaseExprStatement = false, bool IsClassProperty = false) { + bool IsBaseExprStatement = false, bool IsClassProperty = false, + bool InOriginalClass = true) { typedef CodeCompletionResult Result; // Retrieve the definition. @@ -3973,8 +3974,10 @@ // expressions. if (!P->getType().getTypePtr()->isBlockPointerType() || !IsBaseExprStatement) { - Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), - CurContext); + Result R = Result(P, Results.getBasePriority(P), nullptr); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); return; } @@ -3985,8 +3988,10 @@ findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc, BlockProtoLoc); if (!BlockLoc) { - Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr), - CurContext); + Result R = Result(P, Results.getBasePriority(P), nullptr); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); return; } @@ -3997,9 +4002,10 @@ AddObjCBlockCall(Container->getASTContext(), getCompletionPrintingPolicy(Results.getSema()), Builder, P, BlockLoc, BlockProtoLoc); - Results.MaybeAddResult( - Result(Builder.TakeString(), P, Results.getBasePriority(P)), - CurContext); + Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P)); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); // Provide additional block setter completion iff the base expression is a // statement and the block property is mutable. @@ -4025,13 +4031,15 @@ // otherwise the setter completion should show up before the default // property completion, as we normally want to use the result of the // call. - Results.MaybeAddResult( + Result R = Result(Builder.TakeString(), P, Results.getBasePriority(P) + (BlockLoc.getTypePtr()->getReturnType()->isVoidType() ? CCD_BlockPropertySetter - : -CCD_BlockPropertySetter)), - CurContext); + : -CCD_BlockPropertySetter)); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); } }; @@ -4059,10 +4067,11 @@ AddResultTypeChunk(Context, Policy, M, CCContext.getBaseType(), Builder); Builder.AddTypedTextChunk( Results.getAllocator().CopyString(Name->getName())); - Results.MaybeAddResult( - Result(Builder.TakeString(), M, - CCP_MemberDeclaration + CCD_MethodAsProperty), - CurContext); + Result R = Result(Builder.TakeString(), M, + CCP_MemberDeclaration + CCD_MethodAsProperty); + if (!InOriginalClass) + setInBaseClass(R); + Results.MaybeAddResult(R, CurContext); }; if (IsClassProperty) { @@ -4088,34 +4097,39 @@ for (auto *P : Protocol->protocols()) AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); + IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/false); } else if (ObjCInterfaceDecl *IFace = dyn_cast(Container)){ if (AllowCategories) { // Look through categories. for (auto *Cat : IFace->known_categories()) AddObjCProperties(CCContext, Cat, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); + IsBaseExprStatement, IsClassProperty, + InOriginalClass); } // Look through protocols. for (auto *I : IFace->all_referenced_protocols()) AddObjCProperties(CCContext, I, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); + IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/false); // Look in the superclass. if (IFace->getSuperClass()) AddObjCProperties(CCContext, IFace->getSuperClass(), AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, - Results, IsBaseExprStatement, IsClassProperty); + Results, IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/false); } else if (const ObjCCategoryDecl *Category = dyn_cast(Container)) { // Look through protocols. for (auto *P : Category->protocols()) AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods, CurContext, AddedProperties, Results, - IsBaseExprStatement, IsClassProperty); + IsBaseExprStatement, IsClassProperty, + /*InOriginalClass*/false); } } @@ -4249,7 +4263,8 @@ for (auto *I : BaseType->getAs()->quals()) AddObjCProperties(CCContext, I, true, /*AllowNullaryMethods=*/true, CurContext, AddedProperties, Results, - IsBaseExprStatement); + IsBaseExprStatement, /*IsClassProperty*/false, + /*InOriginalClass*/false); } else if ((IsArrow && BaseType->isObjCObjectPointerType()) || (!IsArrow && BaseType->isObjCObjectType())) { // Objective-C instance variable access. Index: test/CodeCompletion/objc-protocol-member-access.m =================================================================== --- test/CodeCompletion/objc-protocol-member-access.m +++ test/CodeCompletion/objc-protocol-member-access.m @@ -19,6 +19,6 @@ } // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:17:25 %s -o - | FileCheck %s -// CHECK: bar : [#int#]bar -// CHECK: foo : [#int#]foo +// CHECK: bar (InBase) : [#int#]bar +// CHECK: foo (InBase) : [#int#]foo // CHECK-NOT: foobar Index: test/Index/complete-block-properties.m =================================================================== --- test/Index/complete-block-properties.m +++ test/Index/complete-block-properties.m @@ -40,15 +40,15 @@ // RUN: c-index-test -code-completion-at=%s:35:33 %s | FileCheck -check-prefix=CHECK-CC1 %s // RUN: c-index-test -code-completion-at=%s:36:21 %s | FileCheck -check-prefix=CHECK-CC1 %s //CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText barBlock}{LeftParen (}{Placeholder int *}{RightParen )} (35) -//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText block}{LeftParen (}{RightParen )} (35) -//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)()}{TypedText block}{Equal = }{Placeholder ^(void)} (38) -//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo}{TypedText blocker}{LeftParen (}{Placeholder int x}{Comma , }{Placeholder Foo y}{Comma , }{Placeholder ^(Foo *someParameter)foo}{RightParen )} (35) -//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo (^)(int, Foo, FooBlock)}{TypedText blocker}{Equal = }{Placeholder ^Foo(int x, Foo y, FooBlock foo)} (32) +//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText block}{LeftParen (}{RightParen )} (37) +//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)()}{TypedText block}{Equal = }{Placeholder ^(void)} (40) +//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo}{TypedText blocker}{LeftParen (}{Placeholder int x}{Comma , }{Placeholder Foo y}{Comma , }{Placeholder ^(Foo *someParameter)foo}{RightParen )} (37) +//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Foo (^)(int, Foo, FooBlock)}{TypedText blocker}{Equal = }{Placeholder ^Foo(int x, Foo y, FooBlock foo)} (34) //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35) //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText fooBlock}{LeftParen (}{Placeholder Foo *someParameter}{RightParen )} (35) //CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Test *}{TypedText getObject}{LeftParen (}{Placeholder int index}{RightParen )} (35) -//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText performA}{LeftParen (}{RightParen )} (35) -//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText performB}{LeftParen (}{Placeholder int x}{Comma , }{Placeholder int y}{RightParen )} (35) +//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText performA}{LeftParen (}{RightParen )} (37) +//CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText performB}{LeftParen (}{Placeholder int x}{Comma , }{Placeholder int y}{RightParen )} (37) @end Index: test/Index/complete-block-property-assignment.m =================================================================== --- test/Index/complete-block-property-assignment.m +++ test/Index/complete-block-property-assignment.m @@ -34,10 +34,10 @@ // RUN: c-index-test -code-completion-at=%s:28:27 %s | FileCheck -check-prefix=CHECK-CC1 %s // RUN: c-index-test -code-completion-at=%s:29:22 %s | FileCheck -check-prefix=CHECK-CC1 %s // RUN: c-index-test -code-completion-at=%s:30:9 %s | FileCheck -check-prefix=CHECK-CC1 %s -// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35) +// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (37) // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35) -// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onAction}{LeftParen (}{Placeholder Obj *object}{RightParen )} (35) -// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction}{Equal = }{Placeholder ^(Obj *object)} (38) +// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onAction}{LeftParen (}{Placeholder Obj *object}{RightParen )} (37) +// CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction}{Equal = }{Placeholder ^(Obj *object)} (40) // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onEventHandler}{LeftParen (}{Placeholder Foo *someParameter}{RightParen )} (35) // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler}{Equal = }{Placeholder ^(Foo *someParameter)} (38) // CHECK-CC1-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText onReadonly}{LeftParen (}{Placeholder int *someParameter}{RightParen )} (35) @@ -61,17 +61,17 @@ // RUN: c-index-test -code-completion-at=%s:52:23 %s | FileCheck -check-prefix=CHECK-NO %s // RUN: c-index-test -code-completion-at=%s:53:12 %s | FileCheck -check-prefix=CHECK-NO %s // RUN: c-index-test -code-completion-at=%s:56:15 %s | FileCheck -check-prefix=CHECK-NO %s -// CHECK-NO: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35) +// CHECK-NO: ObjCPropertyDecl:{ResultType int}{TypedText foo} (37) // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35) -// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35) +// CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (37) // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35) // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35) // CHECK-NO-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35) // RUN: c-index-test -code-completion-at=%s:54:15 %s | FileCheck -check-prefix=CHECK-NO1 %s -// CHECK-NO1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (35) +// CHECK-NO1: ObjCPropertyDecl:{ResultType int}{TypedText foo} (37) // CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType Obj *}{TypedText obj} (35) -// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (35) +// CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType void (^)(Obj *)}{TypedText onAction} (37) // CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType FooBlock}{TypedText onEventHandler} (35) // CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType void (^)(int *)}{TypedText onReadonly} (35) // CHECK-NO1-NEXT: ObjCPropertyDecl:{ResultType int (^)(int)}{TypedText processEvent} (35) Index: test/Index/complete-member-access.m =================================================================== --- test/Index/complete-member-access.m +++ test/Index/complete-member-access.m @@ -61,8 +61,8 @@ // RUN: c-index-test -code-completion-at=%s:34:12 %s | FileCheck -check-prefix=CHECK-CC3 %s // CHECK-CC3: ObjCInstanceMethodDecl:{ResultType int}{TypedText myOtherPropLikeThing} (37) // CHECK-CC3: ObjCPropertyDecl:{ResultType int}{TypedText myProp} (35) -// CHECK-CC3: ObjCPropertyDecl:{ResultType int}{TypedText prop1} (35) -// CHECK-CC3: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp} (35) +// CHECK-CC3: ObjCPropertyDecl:{ResultType int}{TypedText prop1} (37) +// CHECK-CC3: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp} (37) // CHECK-CC3: Completion contexts: // CHECK-CC3-NEXT: Objective-C property access // CHECK-CC3-NEXT: Container Kind: ObjCInterfaceDecl @@ -72,6 +72,6 @@ // RUN: c-index-test -code-completion-at=%s:42:20 %s | FileCheck -check-prefix=CHECK-CC4 %s // CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText myOtherPropLikeThing} (37) // CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText myProp} (35) -// CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText prop1} (35) -// CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp} (35) +// CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText prop1} (37) +// CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType float}{TypedText ProtoProp} (37) Index: test/Index/complete-properties.m =================================================================== --- test/Index/complete-properties.m +++ test/Index/complete-properties.m @@ -77,11 +77,11 @@ // CHECK-CC4-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop4} // RUN: c-index-test -code-completion-at=%s:29:13 %s | FileCheck -check-prefix=CHECK-CC5 %s -// CHECK-CC5: ObjCPropertyDecl:{ResultType int}{TypedText Prop0} (35) -// CHECK-CC5-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText Prop1} (35) -// CHECK-CC5-NEXT: ObjCPropertyDecl:{ResultType float}{TypedText Prop2} (35) +// CHECK-CC5: ObjCPropertyDecl:{ResultType int}{TypedText Prop0} (37) +// CHECK-CC5-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText Prop1} (37) +// CHECK-CC5-NEXT: ObjCPropertyDecl:{ResultType float}{TypedText Prop2} (37) // CHECK-CC5-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop3} (35) -// CHECK-CC5-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop4} (35) +// CHECK-CC5-NEXT: ObjCPropertyDecl:{ResultType id}{TypedText Prop4} (37) // RUN: c-index-test -code-completion-at=%s:9:11 %s | FileCheck -check-prefix=CHECK-CC6 %s // CHECK-CC6: ObjCInterfaceDecl:{TypedText MyClass} (50) @@ -93,7 +93,7 @@ // CHECK-CC7: ObjCIvarDecl:{ResultType id}{TypedText Prop2_} (7) // RUN: c-index-test -code-completion-at=%s:57:13 -fobjc-nonfragile-abi %s | FileCheck -check-prefix=CHECK-CC8 %s -// CHECK-CC8: ObjCPropertyDecl:{ResultType int}{TypedText Prop5} (35) +// CHECK-CC8: ObjCPropertyDecl:{ResultType int}{TypedText Prop5} (37) @interface ClassProperties @@ -157,12 +157,12 @@ // CHECK-CC9-NOT: instanceProperty // RUN: c-index-test -code-completion-at=%s:145:28 -fobjc-nonfragile-abi %s | FileCheck -check-prefix=CHECK-CC10 %s -// CHECK-CC10: ObjCPropertyDecl:{ResultType int}{TypedText explicit} (35) -// CHECK-CC10-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText explicitInProtocol} (35) -// CHECK-CC10-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText explicitReadonly} (35) -// CHECK-CC10-NEXT: ObjCClassMethodDecl:{ResultType int}{TypedText implicit} (37) -// CHECK-CC10-NEXT: ObjCClassMethodDecl:{ResultType int}{TypedText implicitInCategory} (37) -// CHECK-CC10-NEXT: ObjCClassMethodDecl:{ResultType int}{TypedText implicitReadonly} (37) +// CHECK-CC10: ObjCPropertyDecl:{ResultType int}{TypedText explicit} (37) +// CHECK-CC10-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText explicitInProtocol} (37) +// CHECK-CC10-NEXT: ObjCPropertyDecl:{ResultType int}{TypedText explicitReadonly} (37) +// CHECK-CC10-NEXT: ObjCClassMethodDecl:{ResultType int}{TypedText implicit} (39) +// CHECK-CC10-NEXT: ObjCClassMethodDecl:{ResultType int}{TypedText implicitInCategory} (39) +// CHECK-CC10-NEXT: ObjCClassMethodDecl:{ResultType int}{TypedText implicitReadonly} (39) // CHECK-CC10-NEXT: ObjCPropertyDecl:{ResultType ClassProperties *}{TypedText shadowedImplicit} (35) // CHECK-CC10-NOT: implicitInstance // CHECK-CC10-NOT: noProperty