]> granicus.if.org Git - clang/commitdiff
[index] Remove 'implicit' role for message sends in implicit ObjC
authorAlex Lorenz <arphaman@gmail.com>
Mon, 3 Jul 2017 10:34:46 +0000 (10:34 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Mon, 3 Jul 2017 10:34:46 +0000 (10:34 +0000)
property references

rdar://32375673

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307016 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Index/IndexBody.cpp
test/Index/Core/index-source.m

index d3632b8b9b15f2d0e17519c77e6b1aa5c53629af..6bbd38102509f6768e1b0590aa5d669589cef0a4 100644 (file)
@@ -230,7 +230,31 @@ public:
       SmallVector<SymbolRelation, 2> Relations;
       addCallRole(Roles, Relations);
       Stmt *Containing = getParentStmt();
-      if (E->isImplicit() || (Containing && isa<PseudoObjectExpr>(Containing)))
+
+      auto IsImplicitProperty = [](const PseudoObjectExpr *POE) -> bool {
+        const auto *E = POE->getSyntacticForm();
+        if (const auto *BinOp = dyn_cast<BinaryOperator>(E))
+          E = BinOp->getLHS();
+        const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E);
+        if (!PRE)
+          return false;
+        if (PRE->isExplicitProperty())
+          return false;
+        if (const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
+          // Class properties that are explicitly defined using @property
+          // declarations are represented implicitly as there is no ivar for
+          // class properties.
+          if (Getter->isClassMethod() &&
+              Getter->getCanonicalDecl()->findPropertyDecl())
+            return false;
+        }
+        return true;
+      };
+      bool IsPropCall = Containing && isa<PseudoObjectExpr>(Containing);
+      // Implicit property message sends are not 'implicit'.
+      if ((E->isImplicit() || IsPropCall) &&
+          !(IsPropCall &&
+            IsImplicitProperty(cast<PseudoObjectExpr>(Containing))))
         Roles |= (unsigned)SymbolRole::Implicit;
 
       if (isDynamic(E)) {
index a64c34ad2ac169ece39e9395613dd58a2d604ffc..c911973a70d6f6bc068607c6b4799633a903e8ef 100644 (file)
@@ -413,3 +413,28 @@ void classReceivers() {
   (void)ClassReceivers.implicit;
 // CHECK: [[@LINE-1]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
 }
+
+@interface ImplicitProperties
+
+- (int)implicit;
+- (void)setImplicit:(int)x;
+
++ (int)classImplicit;
++ (void)setClassImplicit:(int)y;
+
+@end
+
+void testImplicitProperties(ImplicitProperties *c) {
+  c.implicit = 0;
+// CHECK: [[@LINE-1]]:5 | instance-method/ObjC | setImplicit: | c:objc(cs)ImplicitProperties(im)setImplicit: | -[ImplicitProperties setImplicit:] | Ref,Call,Dyn,RelRec,RelCall,RelCont | rel: 2
+// CHECK-NEXT: RelCall,RelCont | testImplicitProperties | c:@F@testImplicitProperties
+  c.implicit;
+// CHECK: [[@LINE-1]]:5 | instance-method/ObjC | implicit | c:objc(cs)ImplicitProperties(im)implicit | -[ImplicitProperties implicit] | Ref,Call,Dyn,RelRec,RelCall,RelCont | rel: 2
+// CHECK-NEXT: RelCall,RelCont | testImplicitProperties | c:@F@testImplicitProperties
+  ImplicitProperties.classImplicit = 1;
+// CHECK: [[@LINE-1]]:22 | class-method/ObjC | setClassImplicit: | c:objc(cs)ImplicitProperties(cm)setClassImplicit: | +[ImplicitProperties setClassImplicit:] | Ref,Call,RelCall,RelCont | rel: 1
+// CHECK-NEXT: RelCall,RelCont | testImplicitProperties | c:@F@testImplicitProperties
+  ImplicitProperties.classImplicit;
+// CHECK: [[@LINE-1]]:22 | class-method/ObjC | classImplicit | c:objc(cs)ImplicitProperties(cm)classImplicit | +[ImplicitProperties classImplicit] | Ref,Call,RelCall,RelCont | rel: 1
+// CHECK-NEXT: RelCall,RelCont | testImplicitProperties | c:@F@testImplicitProperties
+}