aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaCodeComplete.cpp58
-rw-r--r--test/Index/complete-method-decls.m2
-rw-r--r--test/Index/complete-properties.m14
3 files changed, 60 insertions, 14 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index f8a9b4c2d1..681190c004 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3334,7 +3334,25 @@ void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
/// property name.
typedef llvm::SmallPtrSet<IdentifierInfo*, 16> AddedPropertiesSet;
-static void AddObjCProperties(ObjCContainerDecl *Container,
+/// \brief Retrieve the container definition, if any?
+static ObjCContainerDecl *getContainerDef(ObjCContainerDecl *Container) {
+ if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
+ if (Interface->hasDefinition())
+ return Interface->getDefinition();
+
+ return Interface;
+ }
+
+ if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
+ if (Protocol->hasDefinition())
+ return Protocol->getDefinition();
+
+ return Protocol;
+ }
+ return Container;
+}
+
+static void AddObjCProperties(ObjCContainerDecl *Container,
bool AllowCategories,
bool AllowNullaryMethods,
DeclContext *CurContext,
@@ -3342,6 +3360,9 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
ResultBuilder &Results) {
typedef CodeCompletionResult Result;
+ // Retrieve the definition.
+ Container = getContainerDef(Container);
+
// Add properties in this container.
for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
PEnd = Container->prop_end();
@@ -3617,6 +3638,8 @@ void Sema::CodeCompleteCase(Scope *S) {
// Code-complete the cases of a switch statement over an enumeration type
// by providing the list of
EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
+ if (EnumDecl *Def = Enum->getDefinition())
+ Enum = Def;
// Determine which enumerators we have already seen in the switch statement.
// FIXME: Ideally, we would also be able to look *past* the code-completion
@@ -4695,6 +4718,7 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
ResultBuilder &Results,
bool InOriginalClass = true) {
typedef CodeCompletionResult Result;
+ Container = getContainerDef(Container);
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
MEnd = Container->meth_end();
M != MEnd; ++M) {
@@ -5826,7 +5850,8 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S) {
return;
// Ignore any properties that have already been implemented.
- for (DeclContext::decl_iterator D = Container->decls_begin(),
+ Container = getContainerDef(Container);
+ for (DeclContext::decl_iterator D = Container->decls_begin(),
DEnd = Container->decls_end();
D != DEnd; ++D)
if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
@@ -5959,9 +5984,12 @@ static void FindImplementableMethods(ASTContext &Context,
KnownMethodsMap &KnownMethods,
bool InOriginalClass = true) {
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
- // Recurse into protocols.
+ // Make sure we have a definition; that's what we'll walk.
if (!IFace->hasDefinition())
return;
+
+ IFace = IFace->getDefinition();
+ Container = IFace;
const ObjCList<ObjCProtocolDecl> &Protocols
= IFace->getReferencedProtocols();
@@ -6003,16 +6031,20 @@ static void FindImplementableMethods(ASTContext &Context,
}
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
- if (Protocol->hasDefinition()) {
- // Recurse into protocols.
- const ObjCList<ObjCProtocolDecl> &Protocols
- = Protocol->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end();
- I != E; ++I)
- FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
- KnownMethods, false);
- }
+ // Make sure we have a definition; that's what we'll walk.
+ if (!Protocol->hasDefinition())
+ return;
+ Protocol = Protocol->getDefinition();
+ Container = Protocol;
+
+ // Recurse into protocols.
+ const ObjCList<ObjCProtocolDecl> &Protocols
+ = Protocol->getReferencedProtocols();
+ for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+ E = Protocols.end();
+ I != E; ++I)
+ FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
+ KnownMethods, false);
}
// Add methods in this container. This operation occurs last because
diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m
index becb7de6eb..ce48246370 100644
--- a/test/Index/complete-method-decls.m
+++ b/test/Index/complete-method-decls.m
@@ -8,7 +8,7 @@
- (int)getInt;
- (id)getSelf;
@end
-
+@protocol P1;
@protocol P2<P1>
+ (id)alloc;
@end
diff --git a/test/Index/complete-properties.m b/test/Index/complete-properties.m
index ce1870e651..a445056369 100644
--- a/test/Index/complete-properties.m
+++ b/test/Index/complete-properties.m
@@ -45,6 +45,17 @@ id test(I3 *i3) {
@synthesize Prop2 = Prop2_;
@end
+@protocol P1
+@property int Prop5;
+@end
+
+@class P1;
+
+@interface I5<P1>
+@end
+@implementation I5
+@synthesize Prop5;
+@end
// RUN: c-index-test -code-completion-at=%s:20:13 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText Prop0}
// CHECK-CC1: ObjCPropertyDecl:{ResultType int}{TypedText Prop1}
@@ -80,3 +91,6 @@ id test(I3 *i3) {
// CHECK-CC7-NOT: ObjCIvarDecl:{ResultType id}{TypedText _Prop2}
// CHECK-CC7: ObjCIvarDecl:{ResultType I4 *}{TypedText Prop1} (17)
// 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)