hokein created this revision. hokein added a reviewer: sammccall. Herald added subscribers: kadircet, arphaman, jkorous, MaskRay, ioeric, ilya-biryukov.
handleDeclOccurrencce reports a canonical declartion, so stick to use canonical declarations to determine whether a declaration is in the target set. Also fix a previous ref test which misses a matched label (it fails without this patch). Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D52871 Files: clangd/XRefs.cpp unittests/clangd/XRefsTests.cpp
Index: unittests/clangd/XRefsTests.cpp =================================================================== --- unittests/clangd/XRefsTests.cpp +++ unittests/clangd/XRefsTests.cpp @@ -1128,6 +1128,14 @@ } )cpp", + R"cpp(// Forward declaration + class $foo[[Foo]]; + class $foo[[Foo]] {} + int main() { + $foo[[Fo^o]] foo; + } + )cpp", + R"cpp(// Function int $foo[[foo]](int) {} int main() { @@ -1148,11 +1156,11 @@ )cpp", R"cpp(// Method call - struct Foo { int [[foo]](); }; - int Foo::[[foo]]() {} + struct Foo { int $foo[[foo]](); }; + int Foo::$foo[[foo]]() {} int main() { Foo f; - f.^foo(); + f.$foo[[^foo]](); } )cpp", Index: clangd/XRefs.cpp =================================================================== --- clangd/XRefs.cpp +++ clangd/XRefs.cpp @@ -361,48 +361,50 @@ class ReferenceFinder : public index::IndexDataConsumer { public: struct Reference { - const Decl *Target; + const Decl *CanonicalTarget; SourceLocation Loc; index::SymbolRoleSet Role; }; ReferenceFinder(ASTContext &AST, Preprocessor &PP, const std::vector<const Decl *> &TargetDecls) : AST(AST) { for (const Decl *D : TargetDecls) - Targets.insert(D); + CanonicalTargets.insert(D->getCanonicalDecl()); } std::vector<Reference> take() && { std::sort(References.begin(), References.end(), [](const Reference &L, const Reference &R) { - return std::tie(L.Loc, L.Target, L.Role) < - std::tie(R.Loc, R.Target, R.Role); + return std::tie(L.Loc, L.CanonicalTarget, L.Role) < + std::tie(R.Loc, R.CanonicalTarget, R.Role); }); // We sometimes see duplicates when parts of the AST get traversed twice. - References.erase(std::unique(References.begin(), References.end(), - [](const Reference &L, const Reference &R) { - return std::tie(L.Target, L.Loc, L.Role) == - std::tie(R.Target, R.Loc, R.Role); - }), - References.end()); + References.erase( + std::unique(References.begin(), References.end(), + [](const Reference &L, const Reference &R) { + return std::tie(L.CanonicalTarget, L.Loc, L.Role) == + std::tie(R.CanonicalTarget, R.Loc, R.Role); + }), + References.end()); return std::move(References); } bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef<index::SymbolRelation> Relations, SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override { + assert(D->isCanonicalDecl() && "expect D to be a canonical declaration"); const SourceManager &SM = AST.getSourceManager(); Loc = SM.getFileLoc(Loc); - if (SM.isWrittenInMainFile(Loc) && Targets.count(D)) + if (SM.isWrittenInMainFile(Loc) && CanonicalTargets.count(D)) References.push_back({D, Loc, Roles}); return true; } private: - llvm::SmallSet<const Decl *, 4> Targets; + llvm::SmallSet<const Decl *, 4> CanonicalTargets; std::vector<Reference> References; const ASTContext &AST; };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits