clang-tools  11.0.0git
Preamble.h
Go to the documentation of this file.
1 //===--- Preamble.h - Reusing expensive parts of the AST ---------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // The vast majority of code in a typical translation unit is in the headers
10 // included at the top of the file.
11 //
12 // The preamble optimization says that we can parse this code once, and reuse
13 // the result multiple times. The preamble is invalidated by changes to the
14 // code in the preamble region, to the compile command, or to files on disk.
15 //
16 // This is the most important optimization in clangd: it allows operations like
17 // code-completion to have sub-second latency. It is supported by the
18 // PrecompiledPreamble functionality in clang, which wraps the techniques used
19 // by PCH files, modules etc into a convenient interface.
20 //
21 //===----------------------------------------------------------------------===//
22 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H
23 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H
24 
25 #include "CollectMacros.h"
26 #include "Compiler.h"
27 #include "Diagnostics.h"
28 #include "FS.h"
29 #include "Headers.h"
31 #include "support/Path.h"
32 #include "clang/Frontend/CompilerInvocation.h"
33 #include "clang/Frontend/PrecompiledPreamble.h"
34 #include "clang/Lex/Lexer.h"
35 #include "clang/Tooling/CompilationDatabase.h"
36 #include "llvm/ADT/StringRef.h"
37 
38 #include <memory>
39 #include <string>
40 #include <vector>
41 
42 namespace clang {
43 namespace clangd {
44 
45 /// The parsed preamble and associated data.
46 ///
47 /// As we must avoid re-parsing the preamble, any information that can only
48 /// be obtained during parsing must be eagerly captured and stored here.
49 struct PreambleData {
50  PreambleData(const ParseInputs &Inputs, PrecompiledPreamble Preamble,
51  std::vector<Diag> Diags, IncludeStructure Includes,
53  std::unique_ptr<PreambleFileStatusCache> StatCache,
55 
56  // Version of the ParseInputs this preamble was built from.
57  std::string Version;
58  tooling::CompileCommand CompileCommand;
59  PrecompiledPreamble Preamble;
60  std::vector<Diag> Diags;
61  // Processes like code completions and go-to-definitions will need #include
62  // information, and their compile action skips preamble range.
64  // Macros defined in the preamble section of the main file.
65  // Users care about headers vs main-file, not preamble vs non-preamble.
66  // These should be treated as main-file entities e.g. for code completion.
68  // Cache of FS operations performed when building the preamble.
69  // When reusing a preamble, this cache can be consumed to save IO.
70  std::unique_ptr<PreambleFileStatusCache> StatCache;
72 };
73 
75  std::function<void(ASTContext &, std::shared_ptr<clang::Preprocessor>,
76  const CanonicalIncludes &)>;
77 
78 /// Build a preamble for the new inputs unless an old one can be reused.
79 /// If \p PreambleCallback is set, it will be run on top of the AST while
80 /// building the preamble.
81 std::shared_ptr<const PreambleData>
82 buildPreamble(PathRef FileName, CompilerInvocation CI,
83  const ParseInputs &Inputs, bool StoreInMemory,
84  PreambleParsedCallback PreambleCallback);
85 
86 /// Returns true if \p Preamble is reusable for \p Inputs. Note that it will
87 /// return true when some missing headers are now available.
88 /// FIXME: Should return more information about the delta between \p Preamble
89 /// and \p Inputs, e.g. new headers.
92  const CompilerInvocation &CI);
93 
94 /// Stores information required to parse a TU using a (possibly stale) Baseline
95 /// preamble. Later on this information can be injected into the main file by
96 /// updating compiler invocation with \c apply. This injected section
97 /// approximately reflects additions to the preamble in Modified contents, e.g.
98 /// new include directives.
100 public:
101  /// \p Preamble is used verbatim.
102  static PreamblePatch unmodified(const PreambleData &Preamble);
103  /// Builds a patch that contains new PP directives introduced to the preamble
104  /// section of \p Modified compared to \p Baseline.
105  /// FIXME: This only handles include directives, we should at least handle
106  /// define/undef.
107  static PreamblePatch create(llvm::StringRef FileName,
108  const ParseInputs &Modified,
109  const PreambleData &Baseline);
110  /// Adjusts CI (which compiles the modified inputs) to be used with the
111  /// baseline preamble. This is done by inserting an artifical include to the
112  /// \p CI that contains new directives calculated in create.
113  void apply(CompilerInvocation &CI) const;
114 
115  /// Returns #include directives from the \c Modified preamble that were
116  /// resolved using the \c Baseline preamble. This covers the new locations of
117  /// inclusions that were moved around, but not inclusions of new files. Those
118  /// will be recorded when parsing the main file: the includes in the injected
119  /// section will be resolved back to their spelled positions in the main file
120  /// using the presumed-location mechanism.
121  std::vector<Inclusion> preambleIncludes() const;
122 
123  /// Returns preamble bounds for the Modified.
124  PreambleBounds modifiedBounds() const { return ModifiedBounds; }
125 
126  /// Returns textual patch contents.
127  llvm::StringRef text() const { return PatchContents; }
128 
129 private:
130  PreamblePatch() = default;
131  std::string PatchContents;
132  std::string PatchFileName;
133  /// Includes that are present in both \p Baseline and \p Modified. Used for
134  /// patching includes of baseline preamble.
135  std::vector<Inclusion> PreambleIncludes;
136  PreambleBounds ModifiedBounds = {0, false};
137 };
138 
139 /// Translates locations inside preamble patch to their main-file equivalent
140 /// using presumed locations. Returns \p Loc if it isn't inside preamble patch.
141 SourceLocation translatePreamblePatchLocation(SourceLocation Loc,
142  const SourceManager &SM);
143 
144 } // namespace clangd
145 } // namespace clang
146 
147 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_PREAMBLE_H
SourceLocation Loc
&#39;#&#39; location in the include directive
MainFileMacros Macros
Definition: Preamble.h:67
ParseInputs Inputs
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:23
llvm::StringRef text() const
Returns textual patch contents.
Definition: Preamble.h:127
std::unique_ptr< CompilerInvocation > CI
Maps a definition location onto an #include file, based on a set of filename rules.
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation CI, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback)
Build a preamble for the new inputs unless an old one can be reused.
Definition: Preamble.cpp:321
CanonicalIncludes CanonIncludes
Definition: Preamble.h:71
std::unique_ptr< PreambleFileStatusCache > StatCache
Definition: Preamble.h:70
PathRef FileName
std::function< void(ASTContext &, std::shared_ptr< clang::Preprocessor >, const CanonicalIncludes &)> PreambleParsedCallback
Definition: Preamble.h:76
SourceLocation translatePreamblePatchLocation(SourceLocation Loc, const SourceManager &SM)
Translates locations inside preamble patch to their main-file equivalent using presumed locations...
Definition: Preamble.cpp:536
Stores information required to parse a TU using a (possibly stale) Baseline preamble.
Definition: Preamble.h:99
tooling::CompileCommand CompileCommand
Definition: Preamble.h:58
Information required to run clang, e.g. to parse AST or do code completion.
Definition: Compiler.h:47
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
PreambleData(const ParseInputs &Inputs, PrecompiledPreamble Preamble, std::vector< Diag > Diags, IncludeStructure Includes, MainFileMacros Macros, std::unique_ptr< PreambleFileStatusCache > StatCache, CanonicalIncludes CanonIncludes)
Definition: Preamble.cpp:308
PreambleBounds modifiedBounds() const
Returns preamble bounds for the Modified.
Definition: Preamble.h:124
std::vector< Diag > Diags
Definition: Preamble.h:60
PrecompiledPreamble Preamble
Definition: Preamble.h:59
IncludeStructure Includes
Definition: Preamble.h:63
The parsed preamble and associated data.
Definition: Preamble.h:49
bool isPreambleCompatible(const PreambleData &Preamble, const ParseInputs &Inputs, PathRef FileName, const CompilerInvocation &CI)
Returns true if Preamble is reusable for Inputs.
Definition: Preamble.cpp:377