diff options
author | Ilya Biryukov <ibiryukov@google.com> | 2018-05-24 15:50:15 +0000 |
---|---|---|
committer | Ilya Biryukov <ibiryukov@google.com> | 2018-05-24 15:50:15 +0000 |
commit | 04f445cb5e4473af3e84befb944ea03a462acec0 (patch) | |
tree | ae2d85033716233dbdf8e5ecdc3aa056b70c06c8 /clang-tools-extra/clangd/ClangdUnit.cpp | |
parent | 9453a0d6660b0de06106d8b55c4594d92396f2d4 (diff) |
[clangd] Build index on preamble changes instead of the AST changes
Summary:
This is more efficient and avoids data races when reading files that
come from the preamble. The staleness can occur when reading a file
from disk that changed after the preamble was built. This can lead to
crashes, e.g. when parsing comments.
We do not to rely on symbols from the main file anyway, since any info
that those provide can always be taken from the AST.
Reviewers: ioeric, sammccall
Reviewed By: ioeric
Subscribers: malaperle, klimek, javed.absar, MaskRay, jkorous, cfe-commits
Differential Revision: https://reviews.llvm.org/D47272
Diffstat (limited to 'clang-tools-extra/clangd/ClangdUnit.cpp')
-rw-r--r-- | clang-tools-extra/clangd/ClangdUnit.cpp | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/clang-tools-extra/clangd/ClangdUnit.cpp b/clang-tools-extra/clangd/ClangdUnit.cpp index eb2fc184ccf..41f2df3669e 100644 --- a/clang-tools-extra/clangd/ClangdUnit.cpp +++ b/clang-tools-extra/clangd/ClangdUnit.cpp @@ -13,6 +13,8 @@ #include "Logger.h" #include "SourceCode.h" #include "Trace.h" +#include "clang/AST/ASTContext.h" +#include "clang/Basic/LangOptions.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" @@ -25,7 +27,6 @@ #include "clang/Sema/Sema.h" #include "clang/Serialization/ASTWriter.h" #include "clang/Tooling/CompilationDatabase.h" -#include "clang/Basic/LangOptions.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -86,6 +87,9 @@ private: class CppFilePreambleCallbacks : public PreambleCallbacks { public: + CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback) + : File(File), ParsedCallback(ParsedCallback) {} + std::vector<serialization::DeclID> takeTopLevelDeclIDs() { return std::move(TopLevelDeclIDs); } @@ -102,6 +106,13 @@ public: } } + void AfterExecute(CompilerInstance &CI) override { + if (!ParsedCallback) + return; + trace::Span Tracer("Running PreambleCallback"); + ParsedCallback(File, CI.getASTContext(), CI.getPreprocessorPtr()); + } + void HandleTopLevelDecl(DeclGroupRef DG) override { for (Decl *D : DG) { if (isa<ObjCMethodDecl>(D)) @@ -122,6 +133,8 @@ public: } private: + PathRef File; + PreambleParsedCallback ParsedCallback; std::vector<Decl *> TopLevelDecls; std::vector<serialization::DeclID> TopLevelDeclIDs; std::vector<Inclusion> Inclusions; @@ -277,9 +290,9 @@ ParsedAST::ParsedAST(std::shared_ptr<const PreambleData> Preamble, CppFile::CppFile(PathRef FileName, bool StorePreamblesInMemory, std::shared_ptr<PCHContainerOperations> PCHs, - ASTParsedCallback ASTCallback) + PreambleParsedCallback PreambleCallback) : FileName(FileName), StorePreamblesInMemory(StorePreamblesInMemory), - PCHs(std::move(PCHs)), ASTCallback(std::move(ASTCallback)) { + PCHs(std::move(PCHs)), PreambleCallback(std::move(PreambleCallback)) { log("Created CppFile for " + FileName); } @@ -346,10 +359,6 @@ llvm::Optional<std::vector<Diag>> CppFile::rebuild(ParseInputs &&Inputs) { Diagnostics.insert(Diagnostics.end(), NewAST->getDiagnostics().begin(), NewAST->getDiagnostics().end()); } - if (ASTCallback && NewAST) { - trace::Span Tracer("Running ASTCallback"); - ASTCallback(FileName, NewAST.getPointer()); - } // Write the results of rebuild into class fields. Command = std::move(Inputs.CompileCommand); @@ -404,7 +413,7 @@ CppFile::rebuildPreamble(CompilerInvocation &CI, assert(!CI.getFrontendOpts().SkipFunctionBodies); CI.getFrontendOpts().SkipFunctionBodies = true; - CppFilePreambleCallbacks SerializedDeclsCollector; + CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback); auto BuiltPreamble = PrecompiledPreamble::Build( CI, &ContentsBuffer, Bounds, *PreambleDiagsEngine, FS, PCHs, /*StoreInMemory=*/StorePreamblesInMemory, SerializedDeclsCollector); |