Skip to content

Commit c31367e

Browse files
committed
[clangd] Build ASTs only with fresh preambles or after building a new preamble
Summary: This is another step for out-of-order preamble builds. To keep the diagnostic behavior same, we only build ASTs either with "usable" preambles, the ones that are fully applicable to a given ParseInput, or after building a new preamble. Which is the same behaviour as what we do today. ASTs built in the latter is called golden ASTs. Reviewers: sammccall Subscribers: ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76725
1 parent 6b85032 commit c31367e

File tree

7 files changed

+394
-290
lines changed

7 files changed

+394
-290
lines changed

clang-tools-extra/clangd/Preamble.cpp

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ PreambleData::PreambleData(const ParseInputs &Inputs,
9090

9191
std::shared_ptr<const PreambleData>
9292
buildPreamble(PathRef FileName, CompilerInvocation CI,
93-
std::shared_ptr<const PreambleData> OldPreamble,
9493
const ParseInputs &Inputs, bool StoreInMemory,
9594
PreambleParsedCallback PreambleCallback) {
9695
// Note that we don't need to copy the input contents, preamble can live
@@ -100,23 +99,6 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
10099
auto Bounds =
101100
ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0);
102101

103-
if (OldPreamble &&
104-
compileCommandsAreEqual(Inputs.CompileCommand,
105-
OldPreamble->CompileCommand) &&
106-
OldPreamble->Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds,
107-
Inputs.FS.get())) {
108-
vlog("Reusing preamble version {0} for version {1} of {2}",
109-
OldPreamble->Version, Inputs.Version, FileName);
110-
return OldPreamble;
111-
}
112-
if (OldPreamble)
113-
vlog("Rebuilding invalidated preamble for {0} version {1} "
114-
"(previous was version {2})",
115-
FileName, Inputs.Version, OldPreamble->Version);
116-
else
117-
vlog("Building first preamble for {0} version {1}", FileName,
118-
Inputs.Version);
119-
120102
trace::Span Tracer("BuildPreamble");
121103
SPAN_ATTACH(Tracer, "File", FileName);
122104
StoreDiags PreambleDiagnostics;
@@ -172,5 +154,17 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
172154
}
173155
}
174156

157+
bool isPreambleCompatible(const PreambleData &Preamble,
158+
const ParseInputs &Inputs, PathRef FileName,
159+
const CompilerInvocation &CI) {
160+
auto ContentsBuffer =
161+
llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName);
162+
auto Bounds =
163+
ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0);
164+
return compileCommandsAreEqual(Inputs.CompileCommand,
165+
Preamble.CompileCommand) &&
166+
Preamble.Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds,
167+
Inputs.FS.get());
168+
}
175169
} // namespace clangd
176170
} // namespace clang

clang-tools-extra/clangd/Preamble.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
#include "Diagnostics.h"
2828
#include "FS.h"
2929
#include "Headers.h"
30+
#include "Path.h"
3031
#include "index/CanonicalIncludes.h"
32+
#include "clang/Frontend/CompilerInvocation.h"
3133
#include "clang/Frontend/PrecompiledPreamble.h"
3234
#include "clang/Tooling/CompilationDatabase.h"
3335

@@ -72,17 +74,20 @@ using PreambleParsedCallback =
7274
const CanonicalIncludes &)>;
7375

7476
/// Build a preamble for the new inputs unless an old one can be reused.
75-
/// If \p OldPreamble can be reused, it is returned unchanged.
76-
/// If \p OldPreamble is null, always builds the preamble.
7777
/// If \p PreambleCallback is set, it will be run on top of the AST while
78-
/// building the preamble. Note that if the old preamble was reused, no AST is
79-
/// built and, therefore, the callback will not be executed.
78+
/// building the preamble.
8079
std::shared_ptr<const PreambleData>
8180
buildPreamble(PathRef FileName, CompilerInvocation CI,
82-
std::shared_ptr<const PreambleData> OldPreamble,
8381
const ParseInputs &Inputs, bool StoreInMemory,
8482
PreambleParsedCallback PreambleCallback);
8583

84+
/// Returns true if \p Preamble is reusable for \p Inputs. Note that it will
85+
/// return true when some missing headers are now available.
86+
/// FIXME: Should return more information about the delta between \p Preamble
87+
/// and \p Inputs, e.g. new headers.
88+
bool isPreambleCompatible(const PreambleData &Preamble,
89+
const ParseInputs &Inputs, PathRef FileName,
90+
const CompilerInvocation &CI);
8691
} // namespace clangd
8792
} // namespace clang
8893

0 commit comments

Comments
 (0)