//===--- 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 "CollectMacros.h" #include "Compiler.h" #include "Diagnostics.h" #include "FS.h" #include "Headers.h" #include "ModulesBuilder.h" #include "clang-include-cleaner/Record.h" #include "support/Path.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetOptions.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Lex/Lexer.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include <cstddef> #include <functional> #include <memory> #include <string> #include <utility> #include <vector> namespace clang { namespace clangd { /// The captured AST context. /// Keeps necessary structs for an ASTContext and Preprocessor alive. /// This enables consuming them after context that produced the AST is gone. /// (e.g. indexing a preamble ast on a separate thread). ASTContext stored /// inside is still not thread-safe. struct CapturedASTCtx { … }; /// 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 { … }; PreambleParsedCallback; /// Timings and statistics from the premble build. Unlike PreambleData, these /// do not need to be stored for later, but can be useful for logging, metrics, /// etc. struct PreambleBuildStats { … }; /// Build a preamble for the new inputs unless an old one can be reused. /// If \p PreambleCallback is set, it will be run on top of the AST while /// building the preamble. /// If Stats is not non-null, build statistics will be exported there. std::shared_ptr<const PreambleData> buildPreamble(PathRef FileName, CompilerInvocation CI, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback, PreambleBuildStats *Stats = nullptr); /// Returns true if \p Preamble is reusable for \p Inputs. Note that it will /// return true when some missing headers are now available. /// FIXME: Should return more information about the delta between \p Preamble /// and \p Inputs, e.g. new headers. bool isPreambleCompatible(const PreambleData &Preamble, const ParseInputs &Inputs, PathRef FileName, const CompilerInvocation &CI); /// Stores information required to parse a TU using a (possibly stale) Baseline /// preamble. Later on this information can be injected into the main file by /// updating compiler invocation with \c apply. This injected section /// approximately reflects additions to the preamble in Modified contents, e.g. /// new include directives. class PreamblePatch { … }; } // namespace clangd } // namespace clang #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H