summaryrefslogtreecommitdiff
path: root/clang-tools-extra/clangd/ClangdUnit.cpp
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2018-01-31 13:40:48 +0000
committerSam McCall <sam.mccall@gmail.com>2018-01-31 13:40:48 +0000
commit6b02285f807ef85a60e062435c726e118727ccea (patch)
treef7e180cdd82a9a9b1d44f47b7d538eb81fef937f /clang-tools-extra/clangd/ClangdUnit.cpp
parentd6cd356a199904448c55701e6ca28e78132478b5 (diff)
[clangd] Pass Context implicitly using TLS.
Summary: Instead of passing Context explicitly around, we now have a thread-local Context object `Context::current()` which is an implicit argument to every function. Most manipulation of this should use the WithContextValue helper, which augments the current Context to add a single KV pair, and restores the old context on destruction. Advantages are: - less boilerplate in functions that just propagate contexts - reading most code doesn't require understanding context at all, and using context as values in fewer places still - fewer options to pass the "wrong" context when it changes within a scope (e.g. when using Span) - contexts pass through interfaces we can't modify, such as VFS - propagating contexts across threads was slightly tricky (e.g. copy vs move, no move-init in lambdas), and is now encapsulated in the threadpool Disadvantages are all the usual TLS stuff - hidden magic, and potential for higher memory usage on threads that don't use the context. (In practice, it's just one pointer) Reviewers: ilya-biryukov Subscribers: klimek, jkorous-apple, ioeric, cfe-commits Differential Revision: https://reviews.llvm.org/D42517
Diffstat (limited to 'clang-tools-extra/clangd/ClangdUnit.cpp')
-rw-r--r--clang-tools-extra/clangd/ClangdUnit.cpp53
1 files changed, 23 insertions, 30 deletions
diff --git a/clang-tools-extra/clangd/ClangdUnit.cpp b/clang-tools-extra/clangd/ClangdUnit.cpp
index b2276edc983..917294499fb 100644
--- a/clang-tools-extra/clangd/ClangdUnit.cpp
+++ b/clang-tools-extra/clangd/ClangdUnit.cpp
@@ -229,8 +229,7 @@ void clangd::dumpAST(ParsedAST &AST, llvm::raw_ostream &OS) {
}
llvm::Optional<ParsedAST>
-ParsedAST::Build(const Context &Ctx,
- std::unique_ptr<clang::CompilerInvocation> CI,
+ParsedAST::Build(std::unique_ptr<clang::CompilerInvocation> CI,
std::shared_ptr<const PreambleData> Preamble,
std::unique_ptr<llvm::MemoryBuffer> Buffer,
std::shared_ptr<PCHContainerOperations> PCHs,
@@ -254,12 +253,12 @@ ParsedAST::Build(const Context &Ctx,
auto Action = llvm::make_unique<ClangdFrontendAction>();
const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
if (!Action->BeginSourceFile(*Clang, MainInput)) {
- log(Ctx, "BeginSourceFile() failed when building AST for " +
- MainInput.getFile());
+ log("BeginSourceFile() failed when building AST for " +
+ MainInput.getFile());
return llvm::None;
}
if (!Action->Execute())
- log(Ctx, "Execute() failed when building AST for " + MainInput.getFile());
+ log("Execute() failed when building AST for " + MainInput.getFile());
// UnitDiagsConsumer is local, we can not store it in CompilerInstance that
// has a longer lifetime.
@@ -387,8 +386,7 @@ CppFile::CppFile(PathRef FileName, bool StorePreamblesInMemory,
RebuildCounter(0), RebuildInProgress(false), ASTMemUsage(0),
PreambleMemUsage(0), PCHs(std::move(PCHs)),
ASTCallback(std::move(ASTCallback)) {
- // FIXME(ibiryukov): we should pass a proper Context here.
- log(Context::empty(), "Created CppFile for " + FileName);
+ log("Created CppFile for " + FileName);
std::lock_guard<std::mutex> Lock(Mutex);
LatestAvailablePreamble = nullptr;
@@ -442,11 +440,11 @@ UniqueFunction<void()> CppFile::deferCancelRebuild() {
}
llvm::Optional<std::vector<DiagWithFixIts>>
-CppFile::rebuild(const Context &Ctx, ParseInputs &&Inputs) {
- return deferRebuild(std::move(Inputs))(Ctx);
+CppFile::rebuild(ParseInputs &&Inputs) {
+ return deferRebuild(std::move(Inputs))();
}
-UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>(const Context &)>
+UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>()>
CppFile::deferRebuild(ParseInputs &&Inputs) {
std::shared_ptr<const PreambleData> OldPreamble;
std::shared_ptr<PCHContainerOperations> PCHs;
@@ -483,13 +481,11 @@ CppFile::deferRebuild(ParseInputs &&Inputs) {
std::shared_ptr<CppFile> That = shared_from_this();
auto FinishRebuild =
[OldPreamble, RequestRebuildCounter, PCHs,
- That](ParseInputs Inputs,
- const Context &Ctx) mutable /* to allow changing OldPreamble. */
+ That](ParseInputs Inputs) mutable /* to allow changing OldPreamble. */
-> llvm::Optional<std::vector<DiagWithFixIts>> {
- log(Context::empty(),
- "Rebuilding file " + That->FileName + " with command [" +
- Inputs.CompileCommand.Directory + "] " +
- llvm::join(Inputs.CompileCommand.CommandLine, " "));
+ log("Rebuilding file " + That->FileName + " with command [" +
+ Inputs.CompileCommand.Directory + "] " +
+ llvm::join(Inputs.CompileCommand.CommandLine, " "));
// Only one execution of this method is possible at a time.
// RebuildGuard will wait for any ongoing rebuilds to finish and will put us
@@ -532,16 +528,16 @@ CppFile::deferRebuild(ParseInputs &&Inputs) {
if (OldPreamble &&
OldPreamble->Preamble.CanReuse(*CI, ContentsBuffer.get(), Bounds,
Inputs.FS.get())) {
- log(Ctx, "Reusing preamble for file " + Twine(That->FileName));
+ log("Reusing preamble for file " + Twine(That->FileName));
return OldPreamble;
}
- log(Ctx, "Premble for file " + Twine(That->FileName) +
- " cannot be reused. Attempting to rebuild it.");
+ log("Premble for file " + Twine(That->FileName) +
+ " cannot be reused. Attempting to rebuild it.");
// We won't need the OldPreamble anymore, release it so it can be
// deleted (if there are no other references to it).
OldPreamble.reset();
- trace::Span Tracer(Ctx, "Preamble");
+ trace::Span Tracer("Preamble");
SPAN_ATTACH(Tracer, "File", That->FileName);
std::vector<DiagWithFixIts> PreambleDiags;
StoreDiagsConsumer PreambleDiagnosticsConsumer(/*ref*/ PreambleDiags);
@@ -566,17 +562,15 @@ CppFile::deferRebuild(ParseInputs &&Inputs) {
CI->getFrontendOpts().SkipFunctionBodies = false;
if (BuiltPreamble) {
- log(Tracer.Ctx, "Built preamble of size " +
- Twine(BuiltPreamble->getSize()) + " for file " +
- Twine(That->FileName));
+ log("Built preamble of size " + Twine(BuiltPreamble->getSize()) +
+ " for file " + Twine(That->FileName));
return std::make_shared<PreambleData>(
std::move(*BuiltPreamble),
SerializedDeclsCollector.takeTopLevelDeclIDs(),
std::move(PreambleDiags));
} else {
- log(Tracer.Ctx,
- "Could not build a preamble for file " + Twine(That->FileName));
+ log("Could not build a preamble for file " + Twine(That->FileName));
return nullptr;
}
};
@@ -606,18 +600,17 @@ CppFile::deferRebuild(ParseInputs &&Inputs) {
// Compute updated AST.
llvm::Optional<ParsedAST> NewAST;
{
- trace::Span Tracer(Ctx, "Build");
+ trace::Span Tracer("Build");
SPAN_ATTACH(Tracer, "File", That->FileName);
- NewAST =
- ParsedAST::Build(Tracer.Ctx, std::move(CI), std::move(NewPreamble),
- std::move(ContentsBuffer), PCHs, Inputs.FS);
+ NewAST = ParsedAST::Build(std::move(CI), std::move(NewPreamble),
+ std::move(ContentsBuffer), PCHs, Inputs.FS);
}
if (NewAST) {
Diagnostics.insert(Diagnostics.end(), NewAST->getDiagnostics().begin(),
NewAST->getDiagnostics().end());
if (That->ASTCallback)
- That->ASTCallback(Ctx, That->FileName, NewAST.getPointer());
+ That->ASTCallback(That->FileName, NewAST.getPointer());
} else {
// Don't report even Preamble diagnostics if we coulnd't build AST.
Diagnostics.clear();