annotate clang-tools-extra/clangd/Preamble.h @ 221:79ff65ed7e25

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