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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits