Author: Sam McCall Date: 2020-01-28T11:13:33+01:00 New Revision: f4871ead55f59a7dfee56ea97c32b5df4209d9ce
URL: https://github.com/llvm/llvm-project/commit/f4871ead55f59a7dfee56ea97c32b5df4209d9ce DIFF: https://github.com/llvm/llvm-project/commit/f4871ead55f59a7dfee56ea97c32b5df4209d9ce.diff LOG: [clangd] Support pseudo-obj expr, opaque values, and property references in findExplicitReferences() Reviewers: ilya-biryukov, dgoldman Subscribers: MaskRay, jkorous, arphaman, jfb, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D72508 Added: Modified: clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index ca0584cbec78..352674ebc4c7 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -619,7 +619,7 @@ llvm::SmallVector<ReferenceLoc, 2> refInDecl(const Decl *D) { llvm::SmallVector<ReferenceLoc, 2> refInExpr(const Expr *E) { struct Visitor : ConstStmtVisitor<Visitor> { - // FIXME: handle more complicated cases, e.g. ObjC, designated initializers. + // FIXME: handle more complicated cases: more ObjC, designated initializers. llvm::SmallVector<ReferenceLoc, 2> Refs; void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E) { @@ -660,6 +660,14 @@ llvm::SmallVector<ReferenceLoc, 2> refInExpr(const Expr *E) { /*IsDecl=*/false, {E->getPack()}}); } + + void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) { + Refs.push_back(ReferenceLoc{ + NestedNameSpecifierLoc(), E->getLocation(), + /*IsDecl=*/false, + // Select the getter, setter, or @property depending on the call. + explicitReferenceTargets(DynTypedNode::create(*E), {})}); + } }; Visitor V; @@ -780,6 +788,20 @@ class ExplicitReferenceCollector return true; } + bool TraverseOpaqueValueExpr(OpaqueValueExpr *OVE) { + visitNode(DynTypedNode::create(*OVE)); + // Not clear why the source expression is skipped by default... + // FIXME: can we just make RecursiveASTVisitor do this? + return RecursiveASTVisitor::TraverseStmt(OVE->getSourceExpr()); + } + + bool TraversePseudoObjectExpr(PseudoObjectExpr *POE) { + visitNode(DynTypedNode::create(*POE)); + // Traverse only the syntactic form to find the *written* references. + // (The semantic form also contains lots of duplication) + return RecursiveASTVisitor::TraverseStmt(POE->getSyntacticForm()); + } + // We re-define Traverse*, since there's no corresponding Visit*. // TemplateArgumentLoc is the only way to get locations for references to // template template parameters. diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index f2659a96172b..3960ef18e0d6 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -590,6 +590,7 @@ class FindExplicitReferencesTest : public ::testing::Test { // parsing. TU.ExtraArgs.push_back("-fno-delayed-template-parsing"); TU.ExtraArgs.push_back("-std=c++2a"); + TU.ExtraArgs.push_back("-xobjective-c++"); auto AST = TU.build(); auto *TestDecl = &findDecl(AST, "foo"); @@ -1124,7 +1125,37 @@ TEST_F(FindExplicitReferencesTest, All) { "3: targets = {foo::bar}, decl\n" "4: targets = {T}\n" "5: targets = {t}, decl\n" - "6: targets = {t}\n"}}; + "6: targets = {t}\n"}, + // Objective-C: properties + { + R"cpp( + @interface I {} + @property(retain) I* x; + @property(retain) I* y; + @end + I *f; + void foo() { + $0^f.$1^x.$2^y = 0; + } + )cpp", + "0: targets = {f}\n" + "1: targets = {I::x}\n" + "2: targets = {I::y}\n"}, + // Objective-C: implicit properties + { + R"cpp( + @interface I {} + -(I*)x; + -(void)setY:(I*)y; + @end + I *f; + void foo() { + $0^f.$1^x.$2^y = 0; + } + )cpp", + "0: targets = {f}\n" + "1: targets = {I::x}\n" + "2: targets = {I::setY:}\n"}}; for (const auto &C : Cases) { llvm::StringRef ExpectedCode = C.first; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits