Don't walk the translation unit context to produce protocol names when

global code completions are disabled (e.g., because they are
cached). Also, make sure that forward-declared protocols are visited
when we look for all visible names within a declaration context.

Previously, we would end up with duplicate completions for protocols.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121416 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2010-12-09 21:44:02 +00:00
parent d64f4c1402
commit 70c233591a
3 changed files with 42 additions and 19 deletions

View File

@ -4950,20 +4950,25 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
unsigned NumProtocols) {
ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Results.EnterNewScope();
// Tell the result set to ignore all of the protocols we have
// already seen.
for (unsigned I = 0; I != NumProtocols; ++I)
if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
Protocols[I].second))
Results.Ignore(Protocol);
if (CodeCompleter && CodeCompleter->includeGlobals()) {
Results.EnterNewScope();
// Tell the result set to ignore all of the protocols we have
// already seen.
// FIXME: This doesn't work when caching code-completion results.
for (unsigned I = 0; I != NumProtocols; ++I)
if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
Protocols[I].second))
Results.Ignore(Protocol);
// Add all protocols.
AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
Results);
// Add all protocols.
AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
Results);
Results.ExitScope();
Results.ExitScope();
}
HandleCodeCompleteResults(this, CodeCompleter,
CodeCompletionContext::CCC_ObjCProtocolName,
Results.data(),Results.size());
@ -4971,13 +4976,17 @@ void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
ResultBuilder Results(*this, CodeCompletionContext::CCC_ObjCProtocolName);
Results.EnterNewScope();
// Add all protocols.
AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
Results);
if (CodeCompleter && CodeCompleter->includeGlobals()) {
Results.EnterNewScope();
// Add all protocols.
AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
Results);
Results.ExitScope();
Results.ExitScope();
}
HandleCodeCompleteResults(this, CodeCompleter,
CodeCompletionContext::CCC_ObjCProtocolName,
Results.data(),Results.size());

View File

@ -2463,12 +2463,24 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
DEnd = CurCtx->decls_end();
D != DEnd; ++D) {
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) {
if (Result.isAcceptableDecl(ND)) {
Consumer.FoundDecl(ND, Visited.checkHidden(ND), InBaseClass);
Visited.add(ND);
}
} else if (ObjCForwardProtocolDecl *ForwardProto
= dyn_cast<ObjCForwardProtocolDecl>(*D)) {
for (ObjCForwardProtocolDecl::protocol_iterator
P = ForwardProto->protocol_begin(),
PEnd = ForwardProto->protocol_end();
P != PEnd;
++P) {
if (Result.isAcceptableDecl(*P)) {
Consumer.FoundDecl(*P, Visited.checkHidden(*P), InBaseClass);
Visited.add(*P);
}
}
}
// Visit transparent contexts and inline namespaces inside this context.
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())

View File

@ -16,10 +16,12 @@ void f(id<Protocol1,Protocol2>);
// RUN: c-index-test -code-completion-at=%s:9:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: ObjCProtocolDecl:{TypedText Protocol1}
// CHECK-CC1: ObjCProtocolDecl:{TypedText Protocol2}
// CHECK-CC1-NEXT: ObjCProtocolDecl:{TypedText Protocol2}
// RUN: c-index-test -code-completion-at=%s:9:21 %s | FileCheck -check-prefix=CHECK-CC2 %s
// CHECK-CC2-NOT: ObjCProtocolDecl:{TypedText Protocol1}
// CHECK-CC2: ObjCProtocolDecl:{TypedText Protocol2}
// RUN: c-index-test -code-completion-at=%s:12:11 %s | FileCheck -check-prefix=CHECK-CC3 %s
// CHECK-CC3: ObjCProtocolDecl:{TypedText Protocol0}
// CHECK-CC3-NEXT: ObjCProtocolDecl:{TypedText Protocol2}
// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:9:11 %s | FileCheck -check-prefix=CHECK-CC1 %s