]> granicus.if.org Git - clang/commitdiff
Don't walk the translation unit context to produce protocol names when
authorDouglas Gregor <dgregor@apple.com>
Thu, 9 Dec 2010 21:44:02 +0000 (21:44 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 9 Dec 2010 21:44:02 +0000 (21:44 +0000)
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

lib/Sema/SemaCodeComplete.cpp
lib/Sema/SemaLookup.cpp
test/Index/complete-protocols.m

index 6d40fb8d295f6c75f6a2984ae00fa8b14ae5b865..727dd7929c0cd54ff76c3aa30894ff561ef77f60 100644 (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);
-
-  // Add all protocols.
-  AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
-                     Results);
+  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);
 
-  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());
index 16ca78f4dd2eb9fa2b601089b7ae2810d3b14d01..6ff9cc69f1cf5d9bce2a444251a1c5604ac58ada 100644 (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())
index 89f61bcf9ac9e4a2d73b82362c3316e143db7734..6af0198baae0b0436207b8483cce40166a8285e3 100644 (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