ilya-biryukov updated this revision to Diff 161260.
ilya-biryukov added a comment.

- Reverted changes to FileIndex, use merged index instead


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50889

Files:
  clangd/ClangdServer.cpp
  clangd/ClangdServer.h
  clangd/index/FileIndex.cpp
  clangd/index/FileIndex.h

Index: clangd/index/FileIndex.h
===================================================================
--- clangd/index/FileIndex.h
+++ clangd/index/FileIndex.h
@@ -64,7 +64,11 @@
   /// nullptr, this removes all symbols in the file.
   /// If \p AST is not null, \p PP cannot be null and it should be the
   /// preprocessor that was used to build \p AST.
-  void update(PathRef Path, ASTContext *AST, std::shared_ptr<Preprocessor> PP);
+  /// If \p TopLevelDecls is set, only these decls are indexed. Otherwise, all
+  /// top level decls obtained from \p AST are indexed.
+  void
+  update(PathRef Path, ASTContext *AST, std::shared_ptr<Preprocessor> PP,
+         llvm::Optional<llvm::ArrayRef<Decl *>> TopLevelDecls = llvm::None);
 
   bool
   fuzzyFind(const FuzzyFindRequest &Req,
@@ -86,8 +90,12 @@
 /// Retrieves namespace and class level symbols in \p AST.
 /// Exposed to assist in unit tests.
 /// If URISchemes is empty, the default schemes in SymbolCollector will be used.
-SymbolSlab indexAST(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
-                    llvm::ArrayRef<std::string> URISchemes = {});
+/// If \p TopLevelDecls is set, only these decls are indexed. Otherwise, all top
+/// level decls obtained from \p AST are indexed.
+SymbolSlab
+indexAST(ASTContext &AST, std::shared_ptr<Preprocessor> PP,
+         llvm::Optional<llvm::ArrayRef<Decl *>> TopLevelDecls = llvm::None,
+         llvm::ArrayRef<std::string> URISchemes = {});
 
 } // namespace clangd
 } // namespace clang
Index: clangd/index/FileIndex.cpp
===================================================================
--- clangd/index/FileIndex.cpp
+++ clangd/index/FileIndex.cpp
@@ -8,15 +8,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "FileIndex.h"
-#include "SymbolCollector.h"
 #include "../Logger.h"
+#include "SymbolCollector.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Lex/Preprocessor.h"
 
 namespace clang {
 namespace clangd {
 
 SymbolSlab 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
@@ -38,10 +39,13 @@
       index::IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly;
   IndexOpts.IndexFunctionLocals = false;
 
-  std::vector<const Decl *> TopLevelDecls(
-      AST.getTranslationUnitDecl()->decls().begin(),
-      AST.getTranslationUnitDecl()->decls().end());
-  index::indexTopLevelDecls(AST, TopLevelDecls, Collector, IndexOpts);
+  std::vector<Decl *> Storage;
+  if (!TopLevelDecls) {
+    Storage.assign(AST.getTranslationUnitDecl()->decls().begin(),
+                   AST.getTranslationUnitDecl()->decls().end());
+    TopLevelDecls = Storage;
+  }
+  index::indexTopLevelDecls(AST, *TopLevelDecls, Collector, IndexOpts);
 
   return Collector.takeSymbols();
 }
@@ -81,13 +85,14 @@
 }
 
 void FileIndex::update(PathRef Path, ASTContext *AST,
-                       std::shared_ptr<Preprocessor> PP) {
+                       std::shared_ptr<Preprocessor> PP,
+                       llvm::Optional<llvm::ArrayRef<Decl *>> TopLevelDecls) {
   if (!AST) {
     FSymbols.update(Path, nullptr);
   } else {
     assert(PP);
     auto Slab = llvm::make_unique<SymbolSlab>();
-    *Slab = indexAST(*AST, PP, URISchemes);
+    *Slab = indexAST(*AST, PP, TopLevelDecls, URISchemes);
     FSymbols.update(Path, std::move(Slab));
   }
   auto Symbols = FSymbols.allSymbols();
Index: clangd/ClangdServer.h
===================================================================
--- clangd/ClangdServer.h
+++ clangd/ClangdServer.h
@@ -207,6 +207,27 @@
 
   tooling::CompileCommand getCompileCommand(PathRef File);
 
+  /// Manages dynamic index for open files. Each file might contribute two sets
+  /// of symbols to the dynamic index: symbols from the preamble and symbols
+  /// from the file itself. Those have different lifetimes and we merge results from both 
+  class DynamicIndex : public ParsingCallbacks {
+  public:
+    DynamicIndex(std::vector<std::string> URISchemes);
+
+    SymbolIndex &index() const;
+
+    void onPreambleAST(PathRef Path, ASTContext &Ctx,
+                          std::shared_ptr<clang::Preprocessor> PP) override;
+    void onMainAST(PathRef Path, ParsedAST &AST) override;
+
+  private:
+    FileIndex PreambleIdx;
+    FileIndex MainFileIdx;
+    /// Merged view into both indexes. Merges are performed in a similar manner
+    /// to the merges of dynamic and static index.
+    std::unique_ptr<SymbolIndex> MergedIndex;
+  };
+
   GlobalCompilationDatabase &CDB;
   DiagnosticsConsumer &DiagConsumer;
   FileSystemProvider &FSProvider;
@@ -221,10 +242,8 @@
   //   - the static index passed to the constructor
   //   - a merged view of a static and dynamic index (MergedIndex)
   SymbolIndex *Index;
-  // If present, an up-to-date of symbols in open files. Read via Index.
-  std::unique_ptr<FileIndex> FileIdx;
-  /// Callbacks responsible for updating FileIdx.
-  std::unique_ptr<ParsingCallbacks> FileIdxUpdater;
+  /// If present, an up-to-date of symbols in open files. Read via Index.
+  std::unique_ptr<DynamicIndex> FileIdx;
   // If present, a merged view of FileIdx and an external index. Read via Index.
   std::unique_ptr<SymbolIndex> MergedIndex;
   // If set, this represents the workspace path.
Index: clangd/ClangdServer.cpp
===================================================================
--- clangd/ClangdServer.cpp
+++ clangd/ClangdServer.cpp
@@ -66,22 +66,17 @@
   Optional<Expected<tooling::AtomicChanges>> Result;
 };
 
-class UpdateFileIndex : public ParsingCallbacks {
+// FIXME(ibiryukov): this should be a generic helper instead.
+class NoopCallbacks : public ParsingCallbacks {
 public:
-  UpdateFileIndex(FileIndex *FileIdx) : FileIdx(FileIdx) {}
-
-  void onPreambleAST(PathRef Path, ASTContext &Ctx,
-                     std::shared_ptr<clang::Preprocessor> PP) override {
-    if (FileIdx)
-      FileIdx->update(Path, &Ctx, std::move(PP));
-  }
-
-  void onMainAST(PathRef Path, ParsedAST &AST) override {
-    // FIXME: merge results from the main file into the index too.
+  static ParsingCallbacks &instance() {
+    static ParsingCallbacks *Instance = new NoopCallbacks;
+    return *Instance;
   }
 
-private:
-  FileIndex *FileIdx;
+  void onPreambleAST(PathRef Path, ASTContext &Ctx,
+                     std::shared_ptr<clang::Preprocessor> PP) override {}
+  void onMainAST(PathRef Path, ParsedAST &AST) override {}
 };
 
 } // namespace
@@ -101,23 +96,22 @@
     : CDB(CDB), DiagConsumer(DiagConsumer), FSProvider(FSProvider),
       ResourceDir(Opts.ResourceDir ? Opts.ResourceDir->str()
                                    : getStandardResourceDir()),
-      FileIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.URISchemes)
+      FileIdx(Opts.BuildDynamicSymbolIndex ? new DynamicIndex(Opts.URISchemes)
                                            : nullptr),
-      FileIdxUpdater(llvm::make_unique<UpdateFileIndex>(FileIdx.get())),
       PCHs(std::make_shared<PCHContainerOperations>()),
       // Pass a callback into `WorkScheduler` to extract symbols from a newly
       // parsed file and rebuild the file index synchronously each time an AST
       // is parsed.
       // FIXME(ioeric): this can be slow and we may be able to index on less
       // critical paths.
       WorkScheduler(Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
-                    *FileIdxUpdater, Opts.UpdateDebounce,
-                    Opts.RetentionPolicy) {
+                    FileIdx ? *FileIdx : NoopCallbacks::instance(),
+                    Opts.UpdateDebounce, Opts.RetentionPolicy) {
   if (FileIdx && Opts.StaticIndex) {
-    MergedIndex = mergeIndex(FileIdx.get(), Opts.StaticIndex);
+    MergedIndex = mergeIndex(&FileIdx->index(), Opts.StaticIndex);
     Index = MergedIndex.get();
   } else if (FileIdx)
-    Index = FileIdx.get();
+    Index = &FileIdx->index();
   else if (Opts.StaticIndex)
     Index = Opts.StaticIndex;
   else
@@ -488,3 +482,19 @@
 ClangdServer::blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds) {
   return WorkScheduler.blockUntilIdle(timeoutSeconds(TimeoutSeconds));
 }
+
+ClangdServer::DynamicIndex::DynamicIndex(std::vector<std::string> URISchemes)
+    : PreambleIdx(URISchemes), MainFileIdx(URISchemes),
+      MergedIndex(mergeIndex(&MainFileIdx, &PreambleIdx)) {}
+
+SymbolIndex &ClangdServer::DynamicIndex::index() const { return *MergedIndex; }
+
+void ClangdServer::DynamicIndex::onPreambleAST(
+    PathRef Path, ASTContext &Ctx, std::shared_ptr<clang::Preprocessor> PP) {
+  PreambleIdx.update(Path, &Ctx, PP, /*TopLevelDecls=*/llvm::None);
+}
+
+void ClangdServer::DynamicIndex::onMainAST(PathRef Path, ParsedAST &AST) {
+  MainFileIdx.update(Path, &AST.getASTContext(), AST.getPreprocessorPtr(),
+                     AST.getLocalTopLevelDecls());
+}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to