r318129 - [completion] complete ObjC interface names in an expression

Alex Lorenz via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 13 17:46:24 PST 2017


Author: arphaman
Date: Mon Nov 13 17:46:24 2017
New Revision: 318129

URL: http://llvm.org/viewvc/llvm-project?rev=318129&view=rev
Log:
[completion] complete ObjC interface names in an expression

Objective-C interfaces can be used in a class property expression.

rdar://26982192

Modified:
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/test/Index/complete-interfaces.m

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=318129&r1=318128&r2=318129&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Mon Nov 13 17:46:24 2017
@@ -264,8 +264,12 @@ static unsigned getDeclShowContexts(cons
       Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
     
     // In Objective-C, you can only be a subclass of another Objective-C class
-    if (isa<ObjCInterfaceDecl>(ND))
+    if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
+      // Objective-C interfaces can be used in a class property expression.
+      if (ID->getDefinition())
+        Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
       Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);
+    }
 
     // Deal with tag names.
     if (isa<EnumDecl>(ND)) {

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=318129&r1=318128&r2=318129&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Mon Nov 13 17:46:24 2017
@@ -1082,9 +1082,16 @@ bool ResultBuilder::IsOrdinaryName(const
 /// ordinary name lookup but is not a type name.
 bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
   ND = cast<NamedDecl>(ND->getUnderlyingDecl());
-  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
+  if (isa<TypeDecl>(ND))
     return false;
-  
+  // Objective-C interfaces names are not filtered by this method because they
+  // can be used in a class property expression. We can still filter out
+  // @class declarations though.
+  if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
+    if (!ID->getDefinition())
+      return false;
+  }
+
   unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
   if (SemaRef.getLangOpts().CPlusPlus)
     IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;

Modified: cfe/trunk/test/Index/complete-interfaces.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-interfaces.m?rev=318129&r1=318128&r2=318129&view=diff
==============================================================================
--- cfe/trunk/test/Index/complete-interfaces.m (original)
+++ cfe/trunk/test/Index/complete-interfaces.m Mon Nov 13 17:46:24 2017
@@ -45,3 +45,19 @@
 
 
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
+
+
+void useClasses() {
+  int i = 0;
+  [Int3 message:1];
+}
+
+// RUN: c-index-test -code-completion-at=%s:51:11 %s | FileCheck -check-prefix=CHECK-USE %s
+// RUN: c-index-test -code-completion-at=%s:52:17 %s | FileCheck -check-prefix=CHECK-USE %s
+// CHECK-USE: ObjCInterfaceDecl:{TypedText Int2} (50)
+// CHECK-USE: ObjCInterfaceDecl:{TypedText Int3} (50)
+// CHECK-USE-NOT: Int1
+// CHECK-USE-NOT: Int4
+
+// Caching should work too:
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:51:11 %s | FileCheck -check-prefix=CHECK-USE %s




More information about the cfe-commits mailing list