@@ -292,13 +292,25 @@ const NamedDecl *getPreferredDecl(const NamedDecl *D) {
292292 return D;
293293}
294294
295- std::vector<LocatedSymbol> findOverrides (llvm::DenseSet<SymbolID> IDs,
296- const SymbolIndex *Index,
297- llvm::StringRef MainFilePath) {
295+ std::vector<LocatedSymbol> findImplementors (llvm::DenseSet<SymbolID> IDs,
296+ RelationKind Predicate,
297+ const SymbolIndex *Index,
298+ llvm::StringRef MainFilePath) {
298299 if (IDs.empty ())
299300 return {};
301+ static constexpr trace::Metric FindImplementorsMetric (
302+ " find_implementors" , trace::Metric::Counter, " case" );
303+ switch (Predicate) {
304+ case RelationKind::BaseOf:
305+ FindImplementorsMetric.record (1 , " find-base" );
306+ break ;
307+ case RelationKind::OverriddenBy:
308+ FindImplementorsMetric.record (1 , " find-override" );
309+ break ;
310+ }
311+
300312 RelationsRequest Req;
301- Req.Predicate = RelationKind::OverriddenBy ;
313+ Req.Predicate = Predicate ;
302314 Req.Subjects = std::move (IDs);
303315 std::vector<LocatedSymbol> Results;
304316 Index->relations (Req, [&](const SymbolID &Subject, const Symbol &Object) {
@@ -335,6 +347,8 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
335347 // Keep track of SymbolID -> index mapping, to fill in index data later.
336348 llvm::DenseMap<SymbolID, size_t > ResultIndex;
337349
350+ static constexpr trace::Metric LocateASTReferentMetric (
351+ " locate_ast_referent" , trace::Metric::Counter, " case" );
338352 auto AddResultDecl = [&](const NamedDecl *D) {
339353 D = getPreferredDecl (D);
340354 auto Loc =
@@ -368,8 +382,10 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
368382 // saved in the AST.
369383 if (CMD->isPure ()) {
370384 if (TouchedIdentifier && SM.getSpellingLoc (CMD->getLocation ()) ==
371- TouchedIdentifier->location ())
385+ TouchedIdentifier->location ()) {
372386 VirtualMethods.insert (getSymbolID (CMD));
387+ LocateASTReferentMetric.record (1 , " method-to-override" );
388+ }
373389 }
374390 // Special case: void foo() ^override: jump to the overridden method.
375391 const InheritableAttr *Attr = D->getAttr <OverrideAttr>();
@@ -378,6 +394,7 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
378394 if (Attr && TouchedIdentifier &&
379395 SM.getSpellingLoc (Attr->getLocation ()) ==
380396 TouchedIdentifier->location ()) {
397+ LocateASTReferentMetric.record (1 , " method-to-base" );
381398 // We may be overridding multiple methods - offer them all.
382399 for (const NamedDecl *ND : CMD->overridden_methods ())
383400 AddResultDecl (ND);
@@ -402,6 +419,7 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
402419 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
403420 if (TouchedIdentifier &&
404421 D->getLocation () == TouchedIdentifier->location ()) {
422+ LocateASTReferentMetric.record (1 , " template-specialization-to-primary" );
405423 AddResultDecl (CTSD->getSpecializedTemplate ());
406424 continue ;
407425 }
@@ -417,9 +435,12 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
417435 if (const auto *ID = CD->getClassInterface ())
418436 if (TouchedIdentifier &&
419437 (CD->getLocation () == TouchedIdentifier->location () ||
420- ID->getName () == TouchedIdentifier->text (SM)))
438+ ID->getName () == TouchedIdentifier->text (SM))) {
439+ LocateASTReferentMetric.record (1 , " objc-category-to-class" );
421440 AddResultDecl (ID);
441+ }
422442
443+ LocateASTReferentMetric.record (1 , " regular" );
423444 // Otherwise the target declaration is the right one.
424445 AddResultDecl (D);
425446 }
@@ -458,7 +479,8 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
458479 });
459480 }
460481
461- auto Overrides = findOverrides (VirtualMethods, Index, MainFilePath);
482+ auto Overrides = findImplementors (VirtualMethods, RelationKind::OverriddenBy,
483+ Index, MainFilePath);
462484 Result.insert (Result.end (), Overrides.begin (), Overrides.end ());
463485 return Result;
464486}
@@ -1239,12 +1261,20 @@ std::vector<LocatedSymbol> findImplementations(ParsedAST &AST, Position Pos,
12391261 }
12401262 DeclRelationSet Relations =
12411263 DeclRelation::TemplatePattern | DeclRelation::Alias;
1242- llvm::DenseSet<SymbolID> VirtualMethods;
1243- for (const NamedDecl *ND : getDeclAtPosition (AST, *CurLoc, Relations))
1244- if (const CXXMethodDecl *CXXMD = llvm::dyn_cast<CXXMethodDecl>(ND))
1245- if (CXXMD->isVirtual ())
1246- VirtualMethods.insert (getSymbolID (ND));
1247- return findOverrides (std::move (VirtualMethods), Index, *MainFilePath);
1264+ llvm::DenseSet<SymbolID> IDs;
1265+ RelationKind QueryKind;
1266+ for (const NamedDecl *ND : getDeclAtPosition (AST, *CurLoc, Relations)) {
1267+ if (const auto *CXXMD = llvm::dyn_cast<CXXMethodDecl>(ND)) {
1268+ if (CXXMD->isVirtual ()) {
1269+ IDs.insert (getSymbolID (ND));
1270+ QueryKind = RelationKind::OverriddenBy;
1271+ }
1272+ } else if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
1273+ IDs.insert (getSymbolID (RD));
1274+ QueryKind = RelationKind::BaseOf;
1275+ }
1276+ }
1277+ return findImplementors (std::move (IDs), QueryKind, Index, *MainFilePath);
12481278}
12491279
12501280ReferencesResult findReferences (ParsedAST &AST, Position Pos, uint32_t Limit,
0 commit comments