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@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@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@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@classReceivers _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits