diff options
author | Sam McCall <sam.mccall@gmail.com> | 2018-01-31 13:40:48 +0000 |
---|---|---|
committer | Sam McCall <sam.mccall@gmail.com> | 2018-01-31 13:40:48 +0000 |
commit | 6b02285f807ef85a60e062435c726e118727ccea (patch) | |
tree | f7e180cdd82a9a9b1d44f47b7d538eb81fef937f /clang-tools-extra/clangd/ClangdUnit.cpp | |
parent | d6cd356a199904448c55701e6ca28e78132478b5 (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.cpp | 53 |
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(); |