summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/index/FileIndex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/index/FileIndex.cpp')
-rw-r--r--clang-tools-extra/clangd/index/FileIndex.cpp76
1 files changed, 64 insertions, 12 deletions
diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp
index 48d05959dae..883faf9f398 100644
--- a/clang-tools-extra/clangd/index/FileIndex.cpp
+++ b/clang-tools-extra/clangd/index/FileIndex.cpp
@@ -16,9 +16,10 @@
namespace clang {
namespace clangd {
-SymbolSlab indexAST(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
- llvm::Optional<llvm::ArrayRef<Decl *>> TopLevelDecls,
- llvm::ArrayRef<std::string> URISchemes) {
+std::pair<SymbolSlab, SymbolOccurrenceSlab>
+indexAST(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
+ llvm::Optional<llvm::ArrayRef<Decl *>> TopLevelDecls,
+ llvm::ArrayRef<std::string> URISchemes) {
SymbolCollector::Options CollectorOpts;
// FIXME(ioeric): we might also want to collect include headers. We would need
// to make sure all includes are canonicalized (with CanonicalIncludes), which
@@ -31,8 +32,6 @@ SymbolSlab indexAST(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
CollectorOpts.URISchemes = URISchemes;
CollectorOpts.Origin = SymbolOrigin::Dynamic;
- SymbolCollector Collector(std::move(CollectorOpts));
- Collector.setPreprocessor(PP);
index::IndexingOptions IndexOpts;
// We only need declarations, because we don't count references.
IndexOpts.SystemSymbolFilter =
@@ -46,20 +45,45 @@ SymbolSlab indexAST(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
DeclsToIndex.assign(AST.getTranslationUnitDecl()->decls().begin(),
AST.getTranslationUnitDecl()->decls().end());
+ // We only collect occurrences when indexing main AST.
+ // FIXME: this is a hacky way to detect whether we are indexing preamble AST
+ // or main AST, we should make it explicitly.
+ bool IsIndexMainAST = TopLevelDecls.hasValue();
+ if (IsIndexMainAST)
+ CollectorOpts.OccurrenceFilter = AllOccurrenceKinds;
+
+ SymbolCollector Collector(std::move(CollectorOpts));
+ Collector.setPreprocessor(PP);
index::indexTopLevelDecls(AST, DeclsToIndex, Collector, IndexOpts);
- return Collector.takeSymbols();
+ const auto &SM = AST.getSourceManager();
+ const auto *MainFileEntry = SM.getFileEntryForID(SM.getMainFileID());
+ std::string FileName = MainFileEntry ? MainFileEntry->getName() : "";
+
+ auto Syms = Collector.takeSymbols();
+ auto Occurrences = Collector.takeOccurrences();
+ vlog("index {0}AST for {1}: \n"
+ " symbol slab: {2} symbols, {3} bytes\n"
+ " occurrence slab: {4} symbols, {5} bytes",
+ IsIndexMainAST ? "Main" : "Preamble", FileName, Syms.size(),
+ Syms.bytes(), Occurrences.size(), Occurrences.bytes());
+ return {std::move(Syms), std::move(Occurrences)};
}
FileIndex::FileIndex(std::vector<std::string> URISchemes)
: URISchemes(std::move(URISchemes)) {}
-void FileSymbols::update(PathRef Path, std::unique_ptr<SymbolSlab> Slab) {
+void FileSymbols::update(PathRef Path, std::unique_ptr<SymbolSlab> Slab,
+ std::unique_ptr<SymbolOccurrenceSlab> Occurrences) {
std::lock_guard<std::mutex> Lock(Mutex);
if (!Slab)
FileToSlabs.erase(Path);
else
FileToSlabs[Path] = std::move(Slab);
+ if (!Occurrences)
+ FileToOccurrenceSlabs.erase(Path);
+ else
+ FileToOccurrenceSlabs[Path] = std::move(Occurrences);
}
std::shared_ptr<std::vector<const Symbol *>> FileSymbols::allSymbols() {
@@ -85,19 +109,47 @@ std::shared_ptr<std::vector<const Symbol *>> FileSymbols::allSymbols() {
return {std::move(Snap), Pointers};
}
+std::shared_ptr<MemIndex::OccurrenceMap> FileSymbols::allOccurrences() const {
+ // The snapshot manages life time of symbol occurrence slabs and provides
+ // pointers to all occurrences in all occurrence slabs.
+ struct Snapshot {
+ MemIndex::OccurrenceMap Occurrences; // ID => {Occurrence}
+ std::vector<std::shared_ptr<SymbolOccurrenceSlab>> KeepAlive;
+ };
+
+ auto Snap = std::make_shared<Snapshot>();
+ {
+ std::lock_guard<std::mutex> Lock(Mutex);
+
+ for (const auto &FileAndSlab : FileToOccurrenceSlabs) {
+ Snap->KeepAlive.push_back(FileAndSlab.second);
+ for (const auto &IDAndOccurrences : *FileAndSlab.second) {
+ auto &Occurrences = Snap->Occurrences[IDAndOccurrences.first];
+ for (const auto &Occurrence : IDAndOccurrences.second)
+ Occurrences.push_back(&Occurrence);
+ }
+ }
+ }
+
+ return {std::move(Snap), &Snap->Occurrences};
+}
+
void FileIndex::update(PathRef Path, ASTContext *AST,
std::shared_ptr<Preprocessor> PP,
llvm::Optional<llvm::ArrayRef<Decl *>> TopLevelDecls) {
if (!AST) {
- FSymbols.update(Path, nullptr);
+ FSymbols.update(Path, nullptr, nullptr);
} else {
assert(PP);
auto Slab = llvm::make_unique<SymbolSlab>();
- *Slab = indexAST(*AST, PP, TopLevelDecls, URISchemes);
- FSymbols.update(Path, std::move(Slab));
+ auto OccurrenceSlab = llvm::make_unique<SymbolOccurrenceSlab>();
+ auto IndexResults = indexAST(*AST, PP, TopLevelDecls, URISchemes);
+ std::tie(*Slab, *OccurrenceSlab) =
+ indexAST(*AST, PP, TopLevelDecls, URISchemes);
+ FSymbols.update(Path, std::move(Slab), std::move(OccurrenceSlab));
}
auto Symbols = FSymbols.allSymbols();
- Index.build(std::move(Symbols));
+ Index.build(std::move(Symbols), FSymbols.allOccurrences());
}
bool FileIndex::fuzzyFind(
@@ -115,7 +167,7 @@ void FileIndex::lookup(
void FileIndex::findOccurrences(
const OccurrencesRequest &Req,
llvm::function_ref<void(const SymbolOccurrence &)> Callback) const {
- log("findOccurrences is not implemented.");
+ Index.findOccurrences(Req, Callback);
}
size_t FileIndex::estimateMemoryUsage() const {
OpenPOWER on IntegriCloud