Skip to content

Commit 9b4f370

Browse files
committed
When code completion walks the members of a protocol or interface,
make sure that we walk the definition. Fixes <rdar://problem/11427742>. llvm-svn: 158357
1 parent 2ae781f commit 9b4f370

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3334,14 +3334,35 @@ void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
33343334
/// property name.
33353335
typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
33363336

3337-
static void AddObjCProperties(ObjCContainerDecl *Container,
3337+
/// \brief Retrieve the container definition, if any?
3338+
static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
3339+
if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
3340+
if (Interface->hasDefinition())
3341+
return Interface->getDefinition();
3342+
3343+
return Interface;
3344+
}
3345+
3346+
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3347+
if (Protocol->hasDefinition())
3348+
return Protocol->getDefinition();
3349+
3350+
return Protocol;
3351+
}
3352+
return Container;
3353+
}
3354+
3355+
static void AddObjCProperties(ObjCContainerDecl *Container,
33383356
bool AllowCategories,
33393357
bool AllowNullaryMethods,
33403358
DeclContext *CurContext,
33413359
AddedPropertiesSet &AddedProperties,
33423360
ResultBuilder &Results) {
33433361
typedef CodeCompletionResult Result;
33443362

3363+
// Retrieve the definition.
3364+
Container = getContainerDef(Container);
3365+
33453366
// Add properties in this container.
33463367
for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
33473368
PEnd = Container->prop_end();
@@ -3617,6 +3638,8 @@ void Sema::CodeCompleteCase(Scope *S) {
36173638
// Code-complete the cases of a switch statement over an enumeration type
36183639
// by providing the list of
36193640
EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
3641+
if (EnumDecl *Def = Enum->getDefinition())
3642+
Enum = Def;
36203643

36213644
// Determine which enumerators we have already seen in the switch statement.
36223645
// FIXME: Ideally, we would also be able to look *past* the code-completion
@@ -4695,6 +4718,7 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
46954718
ResultBuilder &Results,
46964719
bool InOriginalClass = true) {
46974720
typedef CodeCompletionResult Result;
4721+
Container = getContainerDef(Container);
46984722
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
46994723
MEnd = Container->meth_end();
47004724
M != MEnd; ++M) {
@@ -5826,7 +5850,8 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
58265850
return;
58275851

58285852
// Ignore any properties that have already been implemented.
5829-
for (DeclContext::decl_iterator D = Container->decls_begin(),
5853+
Container = getContainerDef(Container);
5854+
for (DeclContext::decl_iterator D = Container->decls_begin(),
58305855
DEnd = Container->decls_end();
58315856
D != DEnd; ++D)
58325857
if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
@@ -5959,9 +5984,12 @@ static void FindImplementableMethods(ASTContext &Context,
59595984
KnownMethodsMap &KnownMethods,
59605985
bool InOriginalClass = true) {
59615986
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
5962-
// Recurse into protocols.
5987+
// Make sure we have a definition; that's what we'll walk.
59635988
if (!IFace->hasDefinition())
59645989
return;
5990+
5991+
IFace = IFace->getDefinition();
5992+
Container = IFace;
59655993

59665994
const ObjCList<ObjCProtocolDecl> &Protocols
59675995
= IFace->getReferencedProtocols();
@@ -6003,16 +6031,20 @@ static void FindImplementableMethods(ASTContext &Context,
60036031
}
60046032

60056033
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
6006-
if (Protocol->hasDefinition()) {
6007-
// Recurse into protocols.
6008-
const ObjCList<ObjCProtocolDecl> &Protocols
6009-
= Protocol->getReferencedProtocols();
6010-
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6011-
E = Protocols.end();
6012-
I != E; ++I)
6013-
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6014-
KnownMethods, false);
6015-
}
6034+
// Make sure we have a definition; that's what we'll walk.
6035+
if (!Protocol->hasDefinition())
6036+
return;
6037+
Protocol = Protocol->getDefinition();
6038+
Container = Protocol;
6039+
6040+
// Recurse into protocols.
6041+
const ObjCList<ObjCProtocolDecl> &Protocols
6042+
= Protocol->getReferencedProtocols();
6043+
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
6044+
E = Protocols.end();
6045+
I != E; ++I)
6046+
FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
6047+
KnownMethods, false);
60166048
}
60176049

60186050
// Add methods in this container. This operation occurs last because

clang/test/Index/complete-method-decls.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ - (id)initWithTwoInts:(inout int)x second:(int)y;
88
- (int)getInt;
99
- (id)getSelf;
1010
@end
11-
11+
@protocol P1;
1212
@protocol P2<P1>
1313
+ (id)alloc;
1414
@end

clang/test/Index/complete-properties.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ @implementation I4 {
4545
@synthesize Prop2 = Prop2_;
4646
@end
4747

48+
@protocol P1
49+
@property int Prop5;
50+
@end
51+
52+
@class P1;
53+
54+
@interface I5<P1>
55+
@end
56+
@implementation I5
57+
@synthesize Prop5;
58+
@end
4859
// RUN: c-index-test -code-completion-at=%s:20:13 %s | FileCheck -check-prefix=CHECK-CC1 %s
4960
// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText Prop0}
5061
// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText Prop1}
@@ -80,3 +91,6 @@ @implementation I4 {
8091
// CHECK-CC7-NOT: ObjCIvarDecl:{ResultType id}{TypedText _Prop2}
8192
// CHECK-CC7: ObjCIvarDecl:{ResultType I4 *}{TypedText Prop1} (17)
8293
// CHECK-CC7: ObjCIvarDecl:{ResultType id}{TypedText Prop2_} (7)
94+
95+
// RUN: c-index-test -code-completion-at=%s:57:13 -fobjc-nonfragile-abi %s | FileCheck -check-prefix=CHECK-CC8 %s
96+
// CHECK-CC8: ObjCPropertyDecl:{ResultType int}{TypedText Prop5} (35)

0 commit comments

Comments
 (0)