[clang] 13a8aa3 - [clang] RecursiveASTVisitor visits ObjCPropertyRefExpr's class receiver

David Goldman via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 1 11:46:05 PDT 2021


Author: David Goldman
Date: 2021-06-01T14:45:25-04:00
New Revision: 13a8aa3ee15a67048deeb193fe8b86005fdf9d10

URL: https://github.com/llvm/llvm-project/commit/13a8aa3ee15a67048deeb193fe8b86005fdf9d10
DIFF: https://github.com/llvm/llvm-project/commit/13a8aa3ee15a67048deeb193fe8b86005fdf9d10.diff

LOG: [clang] RecursiveASTVisitor visits ObjCPropertyRefExpr's class receiver

We now make up a TypeLoc for the class receiver to simplify visiting,
notably for indexing, availability, and clangd.

Differential Revision: https://reviews.llvm.org/D101645

Added: 
    

Modified: 
    clang-tools-extra/clangd/FindTarget.cpp
    clang-tools-extra/clangd/unittests/FindTargetTests.cpp
    clang/include/clang/AST/RecursiveASTVisitor.h
    clang/lib/Index/IndexBody.cpp
    clang/lib/Sema/SemaAvailability.cpp
    clang/test/Index/Core/index-source.m

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 4789d28ecf48c..c8eca4e7ca8c7 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -306,9 +306,6 @@ struct TargetFinder {
         Outer.add(OME->getMethodDecl(), Flags);
       }
       void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
-        // FIXME: We miss visiting the class receiver if one exists, which
-        // means we skip the corresponding ObjCInterfaceDecl ref since it
-        // doesn't have a corresponding node.
         if (OPRE->isExplicitProperty())
           Outer.add(OPRE->getExplicitProperty(), Flags);
         else {
@@ -766,13 +763,6 @@ llvm::SmallVector<ReferenceLoc> refInStmt(const Stmt *S,
     }
 
     void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
-      // There's no contained TypeLoc node for a class receiver type.
-      if (E->isClassReceiver()) {
-        Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
-                                    E->getReceiverLocation(),
-                                    /*IsDecl=*/false,
-                                    {E->getClassReceiver()}});
-      }
       Refs.push_back(ReferenceLoc{
           NestedNameSpecifierLoc(), E->getLocation(),
           /*IsDecl=*/false,

diff  --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index beca7c292583d..67dcb574d500a 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -981,8 +981,7 @@ TEST_F(TargetDeclTest, ObjC) {
       id value = [[Foo]].sharedInstance;
     }
   )cpp";
-  // FIXME: We currently can't identify the interface here.
-  EXPECT_DECLS("ObjCPropertyRefExpr", "+ (id)sharedInstance");
+  EXPECT_DECLS("ObjCInterfaceTypeLoc", "@interface Foo");
 
   Code = R"cpp(
     @interface Foo

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index b3ea6f7817ef9..0623a5c8d5ea8 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -2638,7 +2638,16 @@ DEF_TRAVERSE_STMT(ObjCMessageExpr, {
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
 })
 
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {
+  if (S->isClassReceiver()) {
+    ObjCInterfaceDecl *IDecl = S->getClassReceiver();
+    QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
+    ObjCInterfaceLocInfo Data;
+    Data.NameLoc = S->getReceiverLocation();
+    Data.NameEndLoc = Data.NameLoc;
+    TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
+  }
+})
 DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
 DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
 DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})

diff  --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index 7279e3b53c815..fa35f749d0284 100644
--- a/clang/lib/Index/IndexBody.cpp
+++ b/clang/lib/Index/IndexBody.cpp
@@ -286,9 +286,6 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
   }
 
   bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-    if (E->isClassReceiver())
-      IndexCtx.handleReference(E->getClassReceiver(), E->getReceiverLocation(),
-                               Parent, ParentDC);
     if (E->isExplicitProperty()) {
       SmallVector<SymbolRelation, 2> Relations;
       SymbolRoleSet Roles = getRolesForRef(E, Relations);

diff  --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index d69600aaf94ea..bb704b1066cf8 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -683,11 +683,7 @@ class DiagnoseUnguardedAvailability
   // to any useful diagnostics.
   bool TraverseCaseStmt(CaseStmt *CS) { return TraverseStmt(CS->getSubStmt()); }
 
-  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
-    if (PRE->isClassReceiver())
-      DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation());
-    return true;
-  }
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) { return true; }
 
   bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
     if (ObjCMethodDecl *D = Msg->getMethodDecl()) {

diff  --git a/clang/test/Index/Core/index-source.m b/clang/test/Index/Core/index-source.m
index ed616dbc9ae6e..07c7d207607cb 100644
--- a/clang/test/Index/Core/index-source.m
+++ b/clang/test/Index/Core/index-source.m
@@ -405,15 +405,15 @@ + (void)setImplicit:(int)x;
 
 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: [[@LINE-1]]:18 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,Writ,RelCont | rel: 1
 // CHECK-NEXT: RelCont | classReceivers | c:@F at classReceivers
+// CHECK: [[@LINE-3]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
 // CHECK: [[@LINE-4]]:18 | class-method/acc-set/ObjC | setP1: | c:objc(cs)ClassReceivers(cm)setP1: | +[ClassReceivers setP1:] | Ref,Call,Impl,RelCall,RelCont | rel: 1
 // CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F at 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: [[@LINE-1]]:24 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,RelCont | rel: 1
 // CHECK-NEXT: RelCont | classReceivers | c:@F at classReceivers
+// CHECK: [[@LINE-3]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
 // CHECK: [[@LINE-4]]:24 | class-method/acc-get/ObjC | p1 | c:objc(cs)ClassReceivers(cm)p1 | +[ClassReceivers p1] | Ref,Call,Impl,RelCall,RelCont | rel: 1
 // CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F at classReceivers
 


        


More information about the cfe-commits mailing list