diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-06-12 13:44:08 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-06-12 13:44:08 +0000 |
commit | b92a4089db33ae9d44e015cf2dfd1e82fea88747 (patch) | |
tree | c8c35a5b302d5f488448b1d6b1d3168feb62675c /lib/Sema/SemaCodeComplete.cpp | |
parent | 8ca9ff7ff7b7e9cd31314ea57237011b13901d91 (diff) |
When code completion walks the members of a protocol or interface,
make sure that we walk the definition. Fixes <rdar://problem/11427742>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158357 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 58 |
1 files changed, 45 insertions, 13 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 |