[index] The references to explicit class properties should be recorded

rdar://32376363

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303751 91177308-0d34-0410-b5e6-96231b3b80d8
(cherry picked from commit fa589cc9302c4982e13cccde57f10d22706906c1)
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index efa5ed8..d3632b8 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -254,6 +254,18 @@
       SymbolRoleSet Roles = getRolesForRef(E, Relations);
       return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
                                       Parent, ParentDC, Roles, Relations, E);
+    } else if (const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter()) {
+      // Class properties that are explicitly defined using @property
+      // declarations are represented implicitly as there is no ivar for class
+      // properties.
+      if (Getter->isClassMethod()) {
+        if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
+          SmallVector<SymbolRelation, 2> Relations;
+          SymbolRoleSet Roles = getRolesForRef(E, Relations);
+          return IndexCtx.handleReference(PD, E->getLocation(), Parent,
+                                          ParentDC, Roles, Relations, E);
+        }
+      }
     }
 
     // No need to do a handleReference for the objc method, because there will
diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m
index 7c2f753..a64c34a 100644
--- a/test/Index/Core/index-source.m
+++ b/test/Index/Core/index-source.m
@@ -397,8 +397,17 @@
 void classReceivers() {
   ClassReceivers.p1 = 0;
 // CHECK: [[@LINE-1]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:18 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,Writ,RelCont | rel: 1
+// CHECK-NEXT: RelCont | classReceivers | c:@F@classReceivers
+// CHECK: [[@LINE-4]]:18 | class-method/ObjC | setP1: | c:objc(cs)ClassReceivers(cm)setP1: | +[ClassReceivers setP1:] | Ref,Call,Impl,RelCall,RelCont | rel: 1
+// CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F@classReceivers
   (void)ClassReceivers.p1;
 // CHECK: [[@LINE-1]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:24 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | classReceivers | c:@F@classReceivers
+// CHECK: [[@LINE-4]]:24 | class-method/ObjC | p1 | c:objc(cs)ClassReceivers(cm)p1 | +[ClassReceivers p1] | Ref,Call,Impl,RelCall,RelCont | rel: 1
+// CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F@classReceivers
+
   ClassReceivers.implicit = 0;
 // CHECK: [[@LINE-1]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
   (void)ClassReceivers.implicit;