Index: clang-tools-extra/trunk/clangd/CMakeLists.txt =================================================================== --- clang-tools-extra/trunk/clangd/CMakeLists.txt +++ clang-tools-extra/trunk/clangd/CMakeLists.txt @@ -62,6 +62,7 @@ Logger.cpp Protocol.cpp Quality.cpp + Preamble.cpp RIFF.cpp Selection.cpp SemanticHighlighting.cpp Index: clang-tools-extra/trunk/clangd/ClangdServer.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.cpp +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp @@ -13,6 +13,7 @@ #include "Format.h" #include "FormattedString.h" #include "Headers.h" +#include "Preamble.h" #include "Protocol.h" #include "SemanticHighlighting.h" #include "SourceCode.h" Index: clang-tools-extra/trunk/clangd/ClangdUnit.h =================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnit.h +++ clang-tools-extra/trunk/clangd/ClangdUnit.h @@ -11,64 +11,23 @@ #include "Compiler.h" #include "Diagnostics.h" -#include "FS.h" -#include "Function.h" #include "Headers.h" #include "Path.h" -#include "Protocol.h" +#include "Preamble.h" #include "index/CanonicalIncludes.h" -#include "index/Index.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Serialization/ASTBitCodes.h" #include "clang/Tooling/CompilationDatabase.h" -#include "clang/Tooling/Core/Replacement.h" #include "clang/Tooling/Syntax/Tokens.h" #include "llvm/ADT/ArrayRef.h" #include #include #include -namespace llvm { -class raw_ostream; - -namespace vfs { -class FileSystem; -} // namespace vfs -} // namespace llvm - namespace clang { - -namespace tooling { -struct CompileCommand; -} // namespace tooling - namespace clangd { - -// Stores Preamble and associated data. -struct PreambleData { - PreambleData(PrecompiledPreamble Preamble, std::vector Diags, - IncludeStructure Includes, - std::vector MainFileMacros, - std::unique_ptr StatCache, - CanonicalIncludes CanonIncludes); - - tooling::CompileCommand CompileCommand; - PrecompiledPreamble Preamble; - std::vector Diags; - // Processes like code completions and go-to-definitions will need #include - // information, and their compile action skips preamble range. - IncludeStructure Includes; - // Macros defined in the preamble section of the main file. - // Users care about headers vs main-file, not preamble vs non-preamble. - // These should be treated as main-file entities e.g. for code completion. - std::vector MainFileMacros; - // Cache of FS operations performed when building the preamble. - // When reusing a preamble, this cache can be consumed to save IO. - std::unique_ptr StatCache; - CanonicalIncludes CanonIncludes; -}; +class SymbolIndex; /// Stores and provides access to parsed AST. class ParsedAST { @@ -161,23 +120,6 @@ CanonicalIncludes CanonIncludes; }; -using PreambleParsedCallback = - std::function, - const CanonicalIncludes &)>; - -/// Rebuild the preamble for the new inputs unless the old one can be reused. -/// If \p OldPreamble can be reused, it is returned unchanged. -/// If \p OldPreamble is null, always builds the preamble. -/// If \p PreambleCallback is set, it will be run on top of the AST while -/// building the preamble. Note that if the old preamble was reused, no AST is -/// built and, therefore, the callback will not be executed. -std::shared_ptr -buildPreamble(PathRef FileName, CompilerInvocation &CI, - std::shared_ptr OldPreamble, - const tooling::CompileCommand &OldCompileCommand, - const ParseInputs &Inputs, bool StoreInMemory, - PreambleParsedCallback PreambleCallback); - /// Build an AST from provided user inputs. This function does not check if /// preamble can be reused, as this function expects that \p Preamble is the /// result of calling buildPreamble. Index: clang-tools-extra/trunk/clangd/ClangdUnit.cpp =================================================================== --- clang-tools-extra/trunk/clangd/ClangdUnit.cpp +++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp @@ -53,13 +53,6 @@ namespace clangd { namespace { -bool compileCommandsAreEqual(const tooling::CompileCommand &LHS, - const tooling::CompileCommand &RHS) { - // We don't check for Output, it should not matter to clangd. - return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename && - llvm::makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine); -} - template std::size_t getUsedBytes(const std::vector &Vec) { return Vec.capacity() * sizeof(T); } @@ -105,10 +98,9 @@ std::vector TopLevelDecls; }; -// CollectMainFileMacroExpansions and CollectMainFileMacros are two different -// classes as CollectMainFileMacroExpansions is only used when building the AST -// for the main file. CollectMainFileMacros is only used when building the -// preamble. +// This collects macro expansions in the main file. +// (Contrast with CollectMainFileMacros in Preamble.cpp, which collects macro +// *definitions* in the preamble region of the main file). class CollectMainFileMacroExpansions : public PPCallbacks { const SourceManager &SM; std::vector &MainFileMacroLocs; @@ -127,83 +119,6 @@ } }; -class CollectMainFileMacros : public PPCallbacks { -public: - explicit CollectMainFileMacros(const SourceManager &SM, - std::vector *Out) - : SM(SM), Out(Out) {} - - void FileChanged(SourceLocation Loc, FileChangeReason, - SrcMgr::CharacteristicKind, FileID Prev) { - InMainFile = SM.isWrittenInMainFile(Loc); - } - - void MacroDefined(const Token &MacroName, const MacroDirective *MD) { - if (InMainFile) - MainFileMacros.insert(MacroName.getIdentifierInfo()->getName()); - } - - void EndOfMainFile() { - for (const auto &Entry : MainFileMacros) - Out->push_back(Entry.getKey()); - llvm::sort(*Out); - } - -private: - const SourceManager &SM; - bool InMainFile = true; - llvm::StringSet<> MainFileMacros; - std::vector *Out; -}; - -class CppFilePreambleCallbacks : public PreambleCallbacks { -public: - CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback) - : File(File), ParsedCallback(ParsedCallback) { - } - - IncludeStructure takeIncludes() { return std::move(Includes); } - - std::vector takeMainFileMacros() { - return std::move(MainFileMacros); - } - - CanonicalIncludes takeCanonicalIncludes() { return std::move(CanonIncludes); } - - void AfterExecute(CompilerInstance &CI) override { - if (!ParsedCallback) - return; - trace::Span Tracer("Running PreambleCallback"); - ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr(), CanonIncludes); - } - - void BeforeExecute(CompilerInstance &CI) override { - addSystemHeadersMapping(&CanonIncludes, CI.getLangOpts()); - SourceMgr = &CI.getSourceManager(); - } - - std::unique_ptr createPPCallbacks() override { - assert(SourceMgr && "SourceMgr must be set at this point"); - return std::make_unique( - collectIncludeStructureCallback(*SourceMgr, &Includes), - std::make_unique(*SourceMgr, &MainFileMacros)); - } - - CommentHandler *getCommentHandler() override { - IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes); - return IWYUHandler.get(); - } - -private: - PathRef File; - PreambleParsedCallback ParsedCallback; - IncludeStructure Includes; - CanonicalIncludes CanonIncludes; - std::vector MainFileMacros; - std::unique_ptr IWYUHandler = nullptr; - SourceManager *SourceMgr = nullptr; -}; - // When using a preamble, only preprocessor events outside its bounds are seen. // This is almost what we want: replaying transitive preprocessing wastes time. // However this confuses clang-tidy checks: they don't see any #includes! @@ -585,16 +500,6 @@ return CanonIncludes; } -PreambleData::PreambleData(PrecompiledPreamble Preamble, - std::vector Diags, IncludeStructure Includes, - std::vector MainFileMacros, - std::unique_ptr StatCache, - CanonicalIncludes CanonIncludes) - : Preamble(std::move(Preamble)), Diags(std::move(Diags)), - Includes(std::move(Includes)), MainFileMacros(std::move(MainFileMacros)), - StatCache(std::move(StatCache)), CanonIncludes(std::move(CanonIncludes)) { -} - ParsedAST::ParsedAST(std::shared_ptr Preamble, std::unique_ptr Clang, std::unique_ptr Action, @@ -613,79 +518,6 @@ assert(this->Action); } -std::shared_ptr -buildPreamble(PathRef FileName, CompilerInvocation &CI, - std::shared_ptr OldPreamble, - const tooling::CompileCommand &OldCompileCommand, - const ParseInputs &Inputs, bool StoreInMemory, - PreambleParsedCallback PreambleCallback) { - // Note that we don't need to copy the input contents, preamble can live - // without those. - auto ContentsBuffer = - llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName); - auto Bounds = - ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0); - - if (OldPreamble && - compileCommandsAreEqual(Inputs.CompileCommand, OldCompileCommand) && - OldPreamble->Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds, - Inputs.FS.get())) { - vlog("Reusing preamble for file {0}", llvm::Twine(FileName)); - return OldPreamble; - } - vlog("Preamble for file {0} cannot be reused. Attempting to rebuild it.", - FileName); - - trace::Span Tracer("BuildPreamble"); - SPAN_ATTACH(Tracer, "File", FileName); - StoreDiags PreambleDiagnostics; - llvm::IntrusiveRefCntPtr PreambleDiagsEngine = - CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), - &PreambleDiagnostics, false); - - // Skip function bodies when building the preamble to speed up building - // the preamble and make it smaller. - assert(!CI.getFrontendOpts().SkipFunctionBodies); - CI.getFrontendOpts().SkipFunctionBodies = true; - // We don't want to write comment locations into PCH. They are racy and slow - // to read back. We rely on dynamic index for the comments instead. - CI.getPreprocessorOpts().WriteCommentListToPCH = false; - - CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback); - if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { - log("Couldn't set working directory when building the preamble."); - // We proceed anyway, our lit-tests rely on results for non-existing working - // dirs. - } - - llvm::SmallString<32> AbsFileName(FileName); - Inputs.FS->makeAbsolute(AbsFileName); - auto StatCache = std::make_unique(AbsFileName); - auto BuiltPreamble = PrecompiledPreamble::Build( - CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine, - StatCache->getProducingFS(Inputs.FS), - std::make_shared(), StoreInMemory, - SerializedDeclsCollector); - - // When building the AST for the main file, we do want the function - // bodies. - CI.getFrontendOpts().SkipFunctionBodies = false; - - if (BuiltPreamble) { - vlog("Built preamble of size {0} for file {1}", BuiltPreamble->getSize(), - FileName); - std::vector Diags = PreambleDiagnostics.take(); - return std::make_shared( - std::move(*BuiltPreamble), std::move(Diags), - SerializedDeclsCollector.takeIncludes(), - SerializedDeclsCollector.takeMainFileMacros(), std::move(StatCache), - SerializedDeclsCollector.takeCanonicalIncludes()); - } else { - elog("Could not build a preamble for file {0}", FileName); - return nullptr; - } -} - llvm::Optional buildAST(PathRef FileName, std::unique_ptr Invocation, llvm::ArrayRef CompilerInvocationDiags, Index: clang-tools-extra/trunk/clangd/CodeComplete.h =================================================================== --- clang-tools-extra/trunk/clangd/CodeComplete.h +++ clang-tools-extra/trunk/clangd/CodeComplete.h @@ -22,7 +22,6 @@ #include "index/Index.h" #include "index/Symbol.h" #include "index/SymbolOrigin.h" -#include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/CodeCompleteOptions.h" #include "clang/Tooling/CompilationDatabase.h" Index: clang-tools-extra/trunk/clangd/CodeComplete.cpp =================================================================== --- clang-tools-extra/trunk/clangd/CodeComplete.cpp +++ clang-tools-extra/trunk/clangd/CodeComplete.cpp @@ -19,7 +19,6 @@ #include "CodeComplete.h" #include "AST.h" -#include "ClangdUnit.h" #include "CodeCompletionStrings.h" #include "Compiler.h" #include "Diagnostics.h" @@ -28,6 +27,7 @@ #include "FuzzyMatch.h" #include "Headers.h" #include "Logger.h" +#include "Preamble.h" #include "Protocol.h" #include "Quality.h" #include "SourceCode.h" Index: clang-tools-extra/trunk/clangd/Compiler.h =================================================================== --- clang-tools-extra/trunk/clangd/Compiler.h +++ clang-tools-extra/trunk/clangd/Compiler.h @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// // // Shared utilities for invoking the clang compiler. -// ClangdUnit takes care of much of this, but some features like CodeComplete -// run their own compile actions that share logic. +// Most callers will use this through Preamble/ParsedAST, but some features like +// CodeComplete run their own compile actions that share these low-level pieces. // //===----------------------------------------------------------------------===// Index: clang-tools-extra/trunk/clangd/Preamble.h =================================================================== --- clang-tools-extra/trunk/clangd/Preamble.h +++ clang-tools-extra/trunk/clangd/Preamble.h @@ -0,0 +1,88 @@ +//===--- Preamble.h - Reusing expensive parts of the AST ---------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// The vast majority of code in a typical translation unit is in the headers +// included at the top of the file. +// +// The preamble optimization says that we can parse this code once, and reuse +// the result multiple times. The preamble is invalidated by changes to the +// code in the preamble region, to the compile command, or to files on disk. +// +// This is the most important optimization in clangd: it allows operations like +// code-completion to have sub-second latency. It is supported by the +// PrecompiledPreamble functionality in clang, which wraps the techniques used +// by PCH files, modules etc into a convenient interface. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H + +#include "Compiler.h" +#include "Diagnostics.h" +#include "FS.h" +#include "Headers.h" +#include "index/CanonicalIncludes.h" +#include "clang/Frontend/PrecompiledPreamble.h" +#include "clang/Tooling/CompilationDatabase.h" + +#include +#include +#include + +namespace clang { +namespace clangd { + +/// The parsed preamble and associated data. +/// +/// As we must avoid re-parsing the preamble, any information that can only +/// be obtained during parsing must be eagerly captured and stored here. +struct PreambleData { + PreambleData(PrecompiledPreamble Preamble, std::vector Diags, + IncludeStructure Includes, + std::vector MainFileMacros, + std::unique_ptr StatCache, + CanonicalIncludes CanonIncludes); + + tooling::CompileCommand CompileCommand; + PrecompiledPreamble Preamble; + std::vector Diags; + // Processes like code completions and go-to-definitions will need #include + // information, and their compile action skips preamble range. + IncludeStructure Includes; + // Macros defined in the preamble section of the main file. + // Users care about headers vs main-file, not preamble vs non-preamble. + // These should be treated as main-file entities e.g. for code completion. + std::vector MainFileMacros; + // Cache of FS operations performed when building the preamble. + // When reusing a preamble, this cache can be consumed to save IO. + std::unique_ptr StatCache; + CanonicalIncludes CanonIncludes; +}; + +using PreambleParsedCallback = + std::function, + const CanonicalIncludes &)>; + +/// Build a preamble for the new inputs unless an old one can be reused. +/// If \p OldPreamble can be reused, it is returned unchanged. +/// If \p OldPreamble is null, always builds the preamble. +/// If \p PreambleCallback is set, it will be run on top of the AST while +/// building the preamble. Note that if the old preamble was reused, no AST is +/// built and, therefore, the callback will not be executed. +std::shared_ptr +buildPreamble(PathRef FileName, CompilerInvocation &CI, + std::shared_ptr OldPreamble, + const tooling::CompileCommand &OldCompileCommand, + const ParseInputs &Inputs, bool StoreInMemory, + PreambleParsedCallback PreambleCallback); + + +} // namespace clangd +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H Index: clang-tools-extra/trunk/clangd/Preamble.cpp =================================================================== --- clang-tools-extra/trunk/clangd/Preamble.cpp +++ clang-tools-extra/trunk/clangd/Preamble.cpp @@ -0,0 +1,193 @@ +//===--- Preamble.cpp - Reusing expensive parts of the AST ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Preamble.h" +#include "Logger.h" +#include "Trace.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/PreprocessorOptions.h" + +namespace clang { +namespace clangd { +namespace { + +bool compileCommandsAreEqual(const tooling::CompileCommand &LHS, + const tooling::CompileCommand &RHS) { + // We don't check for Output, it should not matter to clangd. + return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename && + llvm::makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine); +} + +// This collects macro definitions in the *preamble region* of the main file. +// (Contrast with CollectMainFileMacroExpansions in ClangdUnit.cpp, which +// collects macro *expansions* in the rest of the main file. +class CollectMainFileMacros : public PPCallbacks { +public: + explicit CollectMainFileMacros(const SourceManager &SM, + std::vector *Out) + : SM(SM), Out(Out) {} + + void FileChanged(SourceLocation Loc, FileChangeReason, + SrcMgr::CharacteristicKind, FileID Prev) { + InMainFile = SM.isWrittenInMainFile(Loc); + } + + void MacroDefined(const Token &MacroName, const MacroDirective *MD) { + if (InMainFile) + MainFileMacros.insert(MacroName.getIdentifierInfo()->getName()); + } + + void EndOfMainFile() { + for (const auto &Entry : MainFileMacros) + Out->push_back(Entry.getKey()); + llvm::sort(*Out); + } + +private: + const SourceManager &SM; + bool InMainFile = true; + llvm::StringSet<> MainFileMacros; + std::vector *Out; +}; + +class CppFilePreambleCallbacks : public PreambleCallbacks { +public: + CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback) + : File(File), ParsedCallback(ParsedCallback) { + } + + IncludeStructure takeIncludes() { return std::move(Includes); } + + std::vector takeMainFileMacros() { + return std::move(MainFileMacros); + } + + CanonicalIncludes takeCanonicalIncludes() { return std::move(CanonIncludes); } + + void AfterExecute(CompilerInstance &CI) override { + if (!ParsedCallback) + return; + trace::Span Tracer("Running PreambleCallback"); + ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr(), CanonIncludes); + } + + void BeforeExecute(CompilerInstance &CI) override { + addSystemHeadersMapping(&CanonIncludes, CI.getLangOpts()); + SourceMgr = &CI.getSourceManager(); + } + + std::unique_ptr createPPCallbacks() override { + assert(SourceMgr && "SourceMgr must be set at this point"); + return std::make_unique( + collectIncludeStructureCallback(*SourceMgr, &Includes), + std::make_unique(*SourceMgr, &MainFileMacros)); + } + + CommentHandler *getCommentHandler() override { + IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes); + return IWYUHandler.get(); + } + +private: + PathRef File; + PreambleParsedCallback ParsedCallback; + IncludeStructure Includes; + CanonicalIncludes CanonIncludes; + std::vector MainFileMacros; + std::unique_ptr IWYUHandler = nullptr; + SourceManager *SourceMgr = nullptr; +}; + +} // namespace + +PreambleData::PreambleData(PrecompiledPreamble Preamble, + std::vector Diags, IncludeStructure Includes, + std::vector MainFileMacros, + std::unique_ptr StatCache, + CanonicalIncludes CanonIncludes) + : Preamble(std::move(Preamble)), Diags(std::move(Diags)), + Includes(std::move(Includes)), MainFileMacros(std::move(MainFileMacros)), + StatCache(std::move(StatCache)), CanonIncludes(std::move(CanonIncludes)) { +} + +std::shared_ptr +buildPreamble(PathRef FileName, CompilerInvocation &CI, + std::shared_ptr OldPreamble, + const tooling::CompileCommand &OldCompileCommand, + const ParseInputs &Inputs, bool StoreInMemory, + PreambleParsedCallback PreambleCallback) { + // Note that we don't need to copy the input contents, preamble can live + // without those. + auto ContentsBuffer = + llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName); + auto Bounds = + ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0); + + if (OldPreamble && + compileCommandsAreEqual(Inputs.CompileCommand, OldCompileCommand) && + OldPreamble->Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds, + Inputs.FS.get())) { + vlog("Reusing preamble for file {0}", llvm::Twine(FileName)); + return OldPreamble; + } + vlog("Preamble for file {0} cannot be reused. Attempting to rebuild it.", + FileName); + + trace::Span Tracer("BuildPreamble"); + SPAN_ATTACH(Tracer, "File", FileName); + StoreDiags PreambleDiagnostics; + llvm::IntrusiveRefCntPtr PreambleDiagsEngine = + CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), + &PreambleDiagnostics, false); + + // Skip function bodies when building the preamble to speed up building + // the preamble and make it smaller. + assert(!CI.getFrontendOpts().SkipFunctionBodies); + CI.getFrontendOpts().SkipFunctionBodies = true; + // We don't want to write comment locations into PCH. They are racy and slow + // to read back. We rely on dynamic index for the comments instead. + CI.getPreprocessorOpts().WriteCommentListToPCH = false; + + CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback); + if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { + log("Couldn't set working directory when building the preamble."); + // We proceed anyway, our lit-tests rely on results for non-existing working + // dirs. + } + + llvm::SmallString<32> AbsFileName(FileName); + Inputs.FS->makeAbsolute(AbsFileName); + auto StatCache = std::make_unique(AbsFileName); + auto BuiltPreamble = PrecompiledPreamble::Build( + CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine, + StatCache->getProducingFS(Inputs.FS), + std::make_shared(), StoreInMemory, + SerializedDeclsCollector); + + // When building the AST for the main file, we do want the function + // bodies. + CI.getFrontendOpts().SkipFunctionBodies = false; + + if (BuiltPreamble) { + vlog("Built preamble of size {0} for file {1}", BuiltPreamble->getSize(), + FileName); + std::vector Diags = PreambleDiagnostics.take(); + return std::make_shared( + std::move(*BuiltPreamble), std::move(Diags), + SerializedDeclsCollector.takeIncludes(), + SerializedDeclsCollector.takeMainFileMacros(), std::move(StatCache), + SerializedDeclsCollector.takeCanonicalIncludes()); + } else { + elog("Could not build a preamble for file {0}", FileName); + return nullptr; + } +} + +} // namespace clangd +} // namespace clang Index: clang-tools-extra/trunk/clangd/TUScheduler.h =================================================================== --- clang-tools-extra/trunk/clangd/TUScheduler.h +++ clang-tools-extra/trunk/clangd/TUScheduler.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_TUSCHEDULER_H -#include "ClangdUnit.h" +#include "Compiler.h" #include "Diagnostics.h" #include "Function.h" #include "GlobalCompilationDatabase.h" @@ -24,6 +24,8 @@ namespace clang { namespace clangd { +class ParsedAST; +struct PreambleData; /// Returns a number of a default async threads to use for TUScheduler. /// Returned value is always >= 1 (i.e. will not cause requests to be processed Index: clang-tools-extra/trunk/clangd/TUScheduler.cpp =================================================================== --- clang-tools-extra/trunk/clangd/TUScheduler.cpp +++ clang-tools-extra/trunk/clangd/TUScheduler.cpp @@ -43,10 +43,12 @@ #include "TUScheduler.h" #include "Cancellation.h" +#include "ClangdUnit.h" #include "Compiler.h" #include "Diagnostics.h" #include "GlobalCompilationDatabase.h" #include "Logger.h" +#include "Preamble.h" #include "Trace.h" #include "index/CanonicalIncludes.h" #include "clang/Frontend/CompilerInvocation.h" Index: clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp =================================================================== --- clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp +++ clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp @@ -12,6 +12,7 @@ #include "Diagnostics.h" #include "Matchers.h" #include "Path.h" +#include "Preamble.h" #include "TUScheduler.h" #include "TestFS.h" #include "Threading.h"