Skip to content

Commit 3556ead

Browse files
Implement the RefKind::Call optimization
1 parent f3d2263 commit 3556ead

File tree

5 files changed

+32
-13
lines changed

5 files changed

+32
-13
lines changed

clang-tools-extra/clangd/XRefs.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,10 +2319,10 @@ outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
23192319
// In this function, we find outgoing calls based on the index only.
23202320
RefsRequest Request;
23212321
Request.IDs.insert(*ID);
2322-
// We could restrict more specifically to calls by introducing a new RefKind,
2323-
// but non-call references (such as address-of-function) can still be
2324-
// interesting as they can indicate indirect calls.
2325-
Request.Filter = RefKind::Reference;
2322+
// Note that RefKind::Call just restricts the matched SymbolKind to
2323+
// functions, not the form of the reference (e.g. address-of-function,
2324+
// which can indicate an indirect call, should still be caught).
2325+
Request.Filter = RefKind::Call;
23262326
// Initially store the ranges in a map keyed by SymbolID of the callee.
23272327
// This allows us to group different calls to the same function
23282328
// into the same CallHierarchyOutgoingCall.
@@ -2347,11 +2347,11 @@ outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
23472347
// Filter references to only keep function calls
23482348
using SK = index::SymbolKind;
23492349
auto Kind = Callee.SymInfo.Kind;
2350-
if (Kind != SK::Function && Kind != SK::InstanceMethod &&
2351-
Kind != SK::ClassMethod && Kind != SK::StaticMethod &&
2352-
Kind != SK::Constructor && Kind != SK::Destructor &&
2353-
Kind != SK::ConversionFunction)
2354-
return;
2350+
bool NotCall = (Kind != SK::Function && Kind != SK::InstanceMethod &&
2351+
Kind != SK::ClassMethod && Kind != SK::StaticMethod &&
2352+
Kind != SK::Constructor && Kind != SK::Destructor &&
2353+
Kind != SK::ConversionFunction);
2354+
assert(!NotCall);
23552355

23562356
auto It = CallsOut.find(Callee.ID);
23572357
assert(It != CallsOut.end());

clang-tools-extra/clangd/index/Ref.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ enum class RefKind : uint8_t {
6363
// ^ this references Foo, but does not explicitly spell out its name
6464
// };
6565
Spelled = 1 << 3,
66+
// A reference which is a call. Used as a filter for which references
67+
// to store in data structures used for computing outgoing calls.
68+
Call = 1 << 4,
6669
All = Declaration | Definition | Reference | Spelled,
6770
};
6871

clang-tools-extra/clangd/index/SymbolCollector.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang-include-cleaner/Record.h"
1919
#include "clang-include-cleaner/Types.h"
2020
#include "index/CanonicalIncludes.h"
21+
#include "index/Ref.h"
2122
#include "index/Relation.h"
2223
#include "index/Symbol.h"
2324
#include "index/SymbolID.h"
@@ -617,7 +618,7 @@ bool SymbolCollector::handleDeclOccurrence(
617618
auto FileLoc = SM.getFileLoc(Loc);
618619
auto FID = SM.getFileID(FileLoc);
619620
if (Opts.RefsInHeaders || FID == SM.getMainFileID()) {
620-
addRef(ID, SymbolRef{FileLoc, FID, Roles,
621+
addRef(ID, SymbolRef{FileLoc, FID, Roles, index::getSymbolInfo(ND).Kind,
621622
getRefContainer(ASTNode.Parent, Opts),
622623
isSpelled(FileLoc, *ND)});
623624
}
@@ -731,8 +732,10 @@ bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name,
731732
// FIXME: Populate container information for macro references.
732733
// FIXME: All MacroRefs are marked as Spelled now, but this should be
733734
// checked.
734-
addRef(ID, SymbolRef{Loc, SM.getFileID(Loc), Roles, /*Container=*/nullptr,
735-
/*Spelled=*/true});
735+
addRef(ID,
736+
SymbolRef{Loc, SM.getFileID(Loc), Roles, index::SymbolKind::Macro,
737+
/*Container=*/nullptr,
738+
/*Spelled=*/true});
736739
}
737740

738741
// Collect symbols.
@@ -1123,6 +1126,14 @@ bool SymbolCollector::shouldIndexFile(FileID FID) {
11231126
return I.first->second;
11241127
}
11251128

1129+
static bool refIsCall(index::SymbolKind Kind) {
1130+
using SK = index::SymbolKind;
1131+
return Kind == SK::Function || Kind == SK::InstanceMethod ||
1132+
Kind == SK::ClassMethod || Kind == SK::StaticMethod ||
1133+
Kind == SK::Constructor || Kind == SK::Destructor ||
1134+
Kind == SK::ConversionFunction;
1135+
}
1136+
11261137
void SymbolCollector::addRef(SymbolID ID, const SymbolRef &SR) {
11271138
const auto &SM = ASTCtx->getSourceManager();
11281139
// FIXME: use the result to filter out references.
@@ -1134,6 +1145,9 @@ void SymbolCollector::addRef(SymbolID ID, const SymbolRef &SR) {
11341145
R.Location.End = Range.second;
11351146
R.Location.FileURI = HeaderFileURIs->toURI(*FE).c_str();
11361147
R.Kind = toRefKind(SR.Roles, SR.Spelled);
1148+
if (refIsCall(SR.Kind)) {
1149+
R.Kind |= RefKind::Call;
1150+
}
11371151
R.Container = getSymbolIDCached(SR.Container);
11381152
Refs.insert(ID, R);
11391153
}

clang-tools-extra/clangd/index/SymbolCollector.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ class SymbolCollector : public index::IndexDataConsumer {
209209
SourceLocation Loc;
210210
FileID FID;
211211
index::SymbolRoleSet Roles;
212+
index::SymbolKind Kind;
212213
const Decl *Container;
213214
bool Spelled;
214215
};

clang-tools-extra/clangd/index/dex/Dex.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ void Dex::buildIndex() {
151151
// Build RevRefs
152152
for (const auto &Pair : Refs)
153153
for (const auto &R : Pair.second)
154-
RevRefs[R.Container].emplace_back(R, Pair.first);
154+
if ((R.Kind & RefKind::Call) != RefKind::Unknown)
155+
RevRefs[R.Container].emplace_back(R, Pair.first);
155156
}
156157

157158
std::unique_ptr<Iterator> Dex::iterator(const Token &Tok) const {

0 commit comments

Comments
 (0)