};
ReferenceFinder(const ParsedAST &AST,
- const std::vector<const NamedDecl *> &TargetDecls)
- : AST(AST) {
- for (const NamedDecl *D : TargetDecls)
- CanonicalTargets.insert(D->getCanonicalDecl());
- }
+ const llvm::DenseSet<SymbolID> &TargetIDs)
+ : AST(AST), TargetIDs(TargetIDs) {}
std::vector<Reference> take() && {
llvm::sort(References, [](const Reference &L, const Reference &R) {
llvm::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();
- if (!CanonicalTargets.count(D) || !isInsideMainFile(Loc, SM))
+ if (!isInsideMainFile(Loc, SM) ||
+ TargetIDs.find(getSymbolID(D)) == TargetIDs.end())
return true;
const auto &TB = AST.getTokens();
Loc = SM.getFileLoc(Loc);
}
private:
- llvm::SmallSet<const Decl *, 4> CanonicalTargets;
std::vector<Reference> References;
const ParsedAST &AST;
+ const llvm::DenseSet<SymbolID> &TargetIDs;
};
std::vector<ReferenceFinder::Reference>
-findRefs(const std::vector<const NamedDecl *> &Decls, ParsedAST &AST) {
- ReferenceFinder RefFinder(AST, Decls);
+findRefs(const llvm::DenseSet<SymbolID> &IDs, ParsedAST &AST) {
+ ReferenceFinder RefFinder(AST, IDs);
index::IndexingOptions IndexOpts;
IndexOpts.SystemSymbolFilter =
index::IndexingOptions::SystemSymbolFilterKind::All;
if (!Decls.empty()) {
// FIXME: we may get multiple DocumentHighlights with the same location
// and different kinds, deduplicate them.
- for (const auto &Ref : findRefs({Decls.begin(), Decls.end()}, AST))
+ llvm::DenseSet<SymbolID> Targets;
+ for (const NamedDecl *ND : Decls)
+ if (auto ID = getSymbolID(ND))
+ Targets.insert(ID);
+ for (const auto &Ref : findRefs(Targets, AST))
Result.push_back(toHighlight(Ref, SM));
return true;
}
llvm::consumeError(CurLoc.takeError());
return {};
}
- llvm::Optional<DefinedMacro> Macro;
- if (const auto *IdentifierAtCursor =
- syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens())) {
- Macro = locateMacroAt(*IdentifierAtCursor, AST.getPreprocessor());
- }
RefsRequest Req;
+
+ const auto *IdentifierAtCursor =
+ syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
+ llvm::Optional<DefinedMacro> Macro;
+ if (IdentifierAtCursor)
+ Macro = locateMacroAt(*IdentifierAtCursor, AST.getPreprocessor());
if (Macro) {
// Handle references to macro.
if (auto MacroSID = getSymbolID(Macro->Name, Macro->Info, SM)) {
DeclRelation::TemplatePattern | DeclRelation::Alias;
std::vector<const NamedDecl *> Decls =
getDeclAtPosition(AST, *CurLoc, Relations);
+ llvm::DenseSet<SymbolID> Targets;
+ for (const NamedDecl *D : Decls)
+ if (auto ID = getSymbolID(D))
+ Targets.insert(ID);
+
+ llvm::DenseSet<SymbolID> Overrides;
+ if (Index) {
+ RelationsRequest FindOverrides;
+ FindOverrides.Predicate = RelationKind::OverriddenBy;
+ for (const NamedDecl *ND : Decls) {
+ // Special case: virtual void meth^od() = 0 includes refs of overrides.
+ if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(ND)) {
+ if (CMD->isPure())
+ if (IdentifierAtCursor && SM.getSpellingLoc(CMD->getLocation()) ==
+ IdentifierAtCursor->location())
+ if (auto ID = getSymbolID(CMD))
+ FindOverrides.Subjects.insert(ID);
+ }
+ }
+ if (!FindOverrides.Subjects.empty())
+ Index->relations(FindOverrides,
+ [&](const SymbolID &Subject, const Symbol &Object) {
+ Overrides.insert(Object.ID);
+ });
+ Targets.insert(Overrides.begin(), Overrides.end());
+ }
// We traverse the AST to find references in the main file.
- auto MainFileRefs = findRefs(Decls, AST);
+ auto MainFileRefs = findRefs(Targets, AST);
// We may get multiple refs with the same location and different Roles, as
// cross-reference is only interested in locations, we deduplicate them
// by the location to avoid emitting duplicated locations.
Results.References.push_back(std::move(Result));
}
if (Index && Results.References.size() <= Limit) {
+ Req.IDs = std::move(Overrides);
for (const Decl *D : Decls) {
// Not all symbols can be referenced from outside (e.g.
// function-locals).