[clang-tools-extra] r323872 - [clangd] Pass Context implicitly using TLS.

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 31 05:40:48 PST 2018


Author: sammccall
Date: Wed Jan 31 05:40:48 2018
New Revision: 323872

URL: http://llvm.org/viewvc/llvm-project?rev=323872&view=rev
Log:
[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

Modified:
    clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
    clang-tools-extra/trunk/clangd/ClangdLSPServer.h
    clang-tools-extra/trunk/clangd/ClangdServer.cpp
    clang-tools-extra/trunk/clangd/ClangdServer.h
    clang-tools-extra/trunk/clangd/ClangdUnit.cpp
    clang-tools-extra/trunk/clangd/ClangdUnit.h
    clang-tools-extra/trunk/clangd/CodeComplete.cpp
    clang-tools-extra/trunk/clangd/CodeComplete.h
    clang-tools-extra/trunk/clangd/Context.cpp
    clang-tools-extra/trunk/clangd/Context.h
    clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp
    clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
    clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
    clang-tools-extra/trunk/clangd/Logger.cpp
    clang-tools-extra/trunk/clangd/Logger.h
    clang-tools-extra/trunk/clangd/Protocol.cpp
    clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
    clang-tools-extra/trunk/clangd/ProtocolHandlers.h
    clang-tools-extra/trunk/clangd/TUScheduler.cpp
    clang-tools-extra/trunk/clangd/TUScheduler.h
    clang-tools-extra/trunk/clangd/Threading.cpp
    clang-tools-extra/trunk/clangd/Threading.h
    clang-tools-extra/trunk/clangd/Trace.cpp
    clang-tools-extra/trunk/clangd/Trace.h
    clang-tools-extra/trunk/clangd/XRefs.cpp
    clang-tools-extra/trunk/clangd/XRefs.h
    clang-tools-extra/trunk/clangd/index/FileIndex.cpp
    clang-tools-extra/trunk/clangd/index/FileIndex.h
    clang-tools-extra/trunk/clangd/index/Index.h
    clang-tools-extra/trunk/clangd/index/MemIndex.cpp
    clang-tools-extra/trunk/clangd/index/MemIndex.h
    clang-tools-extra/trunk/clangd/index/Merge.cpp
    clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
    clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp
    clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
    clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp
    clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
    clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp
    clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp
    clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Wed Jan 31 05:40:48 2018
@@ -46,8 +46,8 @@ std::vector<TextEdit> replacementsToEdit
 
 } // namespace
 
-void ClangdLSPServer::onInitialize(Ctx C, InitializeParams &Params) {
-  reply(C, json::obj{
+void ClangdLSPServer::onInitialize(InitializeParams &Params) {
+  reply(json::obj{
       {{"capabilities",
         json::obj{
             {"textDocumentSync", 1},
@@ -82,38 +82,35 @@ void ClangdLSPServer::onInitialize(Ctx C
     Server.setRootPath(*Params.rootPath);
 }
 
-void ClangdLSPServer::onShutdown(Ctx C, ShutdownParams &Params) {
+void ClangdLSPServer::onShutdown(ShutdownParams &Params) {
   // Do essentially nothing, just say we're ready to exit.
   ShutdownRequestReceived = true;
-  reply(C, nullptr);
+  reply(nullptr);
 }
 
-void ClangdLSPServer::onExit(Ctx C, ExitParams &Params) { IsDone = true; }
+void ClangdLSPServer::onExit(ExitParams &Params) { IsDone = true; }
 
-void ClangdLSPServer::onDocumentDidOpen(Ctx C,
-                                        DidOpenTextDocumentParams &Params) {
+void ClangdLSPServer::onDocumentDidOpen(DidOpenTextDocumentParams &Params) {
   if (Params.metadata && !Params.metadata->extraFlags.empty())
     CDB.setExtraFlagsForFile(Params.textDocument.uri.file,
                              std::move(Params.metadata->extraFlags));
-  Server.addDocument(std::move(C), Params.textDocument.uri.file,
-                     Params.textDocument.text);
+  Server.addDocument(Params.textDocument.uri.file, Params.textDocument.text);
 }
 
-void ClangdLSPServer::onDocumentDidChange(Ctx C,
-                                          DidChangeTextDocumentParams &Params) {
+void ClangdLSPServer::onDocumentDidChange(DidChangeTextDocumentParams &Params) {
   if (Params.contentChanges.size() != 1)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       "can only apply one change at a time");
   // We only support full syncing right now.
-  Server.addDocument(std::move(C), Params.textDocument.uri.file,
+  Server.addDocument(Params.textDocument.uri.file,
                      Params.contentChanges[0].text);
 }
 
-void ClangdLSPServer::onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) {
+void ClangdLSPServer::onFileEvent(DidChangeWatchedFilesParams &Params) {
   Server.onFileEvent(Params);
 }
 
-void ClangdLSPServer::onCommand(Ctx C, ExecuteCommandParams &Params) {
+void ClangdLSPServer::onCommand(ExecuteCommandParams &Params) {
   if (Params.command == ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND &&
       Params.workspaceEdit) {
     // The flow for "apply-fix" :
@@ -127,31 +124,31 @@ void ClangdLSPServer::onCommand(Ctx C, E
 
     ApplyWorkspaceEditParams ApplyEdit;
     ApplyEdit.edit = *Params.workspaceEdit;
-    reply(C, "Fix applied.");
+    reply("Fix applied.");
     // We don't need the response so id == 1 is OK.
     // Ideally, we would wait for the response and if there is no error, we
     // would reply success/failure to the original RPC.
-    call(C, "workspace/applyEdit", ApplyEdit);
+    call("workspace/applyEdit", ApplyEdit);
   } else {
     // We should not get here because ExecuteCommandParams would not have
     // parsed in the first place and this handler should not be called. But if
     // more commands are added, this will be here has a safe guard.
     replyError(
-        C, ErrorCode::InvalidParams,
+        ErrorCode::InvalidParams,
         llvm::formatv("Unsupported command \"{0}\".", Params.command).str());
   }
 }
 
-void ClangdLSPServer::onRename(Ctx C, RenameParams &Params) {
+void ClangdLSPServer::onRename(RenameParams &Params) {
   auto File = Params.textDocument.uri.file;
   auto Code = Server.getDocument(File);
   if (!Code)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       "onRename called for non-added file");
 
-  auto Replacements = Server.rename(C, File, Params.position, Params.newName);
+  auto Replacements = Server.rename(File, Params.position, Params.newName);
   if (!Replacements) {
-    replyError(C, ErrorCode::InternalError,
+    replyError(ErrorCode::InternalError,
                llvm::toString(Replacements.takeError()));
     return;
   }
@@ -159,68 +156,66 @@ void ClangdLSPServer::onRename(Ctx C, Re
   std::vector<TextEdit> Edits = replacementsToEdits(*Code, *Replacements);
   WorkspaceEdit WE;
   WE.changes = {{Params.textDocument.uri.uri(), Edits}};
-  reply(C, WE);
+  reply(WE);
 }
 
-void ClangdLSPServer::onDocumentDidClose(Ctx C,
-                                         DidCloseTextDocumentParams &Params) {
-  Server.removeDocument(std::move(C), Params.textDocument.uri.file);
+void ClangdLSPServer::onDocumentDidClose(DidCloseTextDocumentParams &Params) {
+  Server.removeDocument(Params.textDocument.uri.file);
 }
 
 void ClangdLSPServer::onDocumentOnTypeFormatting(
-    Ctx C, DocumentOnTypeFormattingParams &Params) {
+    DocumentOnTypeFormattingParams &Params) {
   auto File = Params.textDocument.uri.file;
   auto Code = Server.getDocument(File);
   if (!Code)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       "onDocumentOnTypeFormatting called for non-added file");
 
   auto ReplacementsOrError = Server.formatOnType(*Code, File, Params.position);
   if (ReplacementsOrError)
-    reply(C, json::ary(replacementsToEdits(*Code, ReplacementsOrError.get())));
+    reply(json::ary(replacementsToEdits(*Code, ReplacementsOrError.get())));
   else
-    replyError(C, ErrorCode::UnknownErrorCode,
+    replyError(ErrorCode::UnknownErrorCode,
                llvm::toString(ReplacementsOrError.takeError()));
 }
 
 void ClangdLSPServer::onDocumentRangeFormatting(
-    Ctx C, DocumentRangeFormattingParams &Params) {
+    DocumentRangeFormattingParams &Params) {
   auto File = Params.textDocument.uri.file;
   auto Code = Server.getDocument(File);
   if (!Code)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       "onDocumentRangeFormatting called for non-added file");
 
   auto ReplacementsOrError = Server.formatRange(*Code, File, Params.range);
   if (ReplacementsOrError)
-    reply(C, json::ary(replacementsToEdits(*Code, ReplacementsOrError.get())));
+    reply(json::ary(replacementsToEdits(*Code, ReplacementsOrError.get())));
   else
-    replyError(C, ErrorCode::UnknownErrorCode,
+    replyError(ErrorCode::UnknownErrorCode,
                llvm::toString(ReplacementsOrError.takeError()));
 }
 
-void ClangdLSPServer::onDocumentFormatting(Ctx C,
-                                           DocumentFormattingParams &Params) {
+void ClangdLSPServer::onDocumentFormatting(DocumentFormattingParams &Params) {
   auto File = Params.textDocument.uri.file;
   auto Code = Server.getDocument(File);
   if (!Code)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       "onDocumentFormatting called for non-added file");
 
   auto ReplacementsOrError = Server.formatFile(*Code, File);
   if (ReplacementsOrError)
-    reply(C, json::ary(replacementsToEdits(*Code, ReplacementsOrError.get())));
+    reply(json::ary(replacementsToEdits(*Code, ReplacementsOrError.get())));
   else
-    replyError(C, ErrorCode::UnknownErrorCode,
+    replyError(ErrorCode::UnknownErrorCode,
                llvm::toString(ReplacementsOrError.takeError()));
 }
 
-void ClangdLSPServer::onCodeAction(Ctx C, CodeActionParams &Params) {
+void ClangdLSPServer::onCodeAction(CodeActionParams &Params) {
   // We provide a code action for each diagnostic at the requested location
   // which has FixIts available.
   auto Code = Server.getDocument(Params.textDocument.uri.file);
   if (!Code)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       "onCodeAction called for non-added file");
 
   json::ary Commands;
@@ -236,67 +231,53 @@ void ClangdLSPServer::onCodeAction(Ctx C
       });
     }
   }
-  reply(C, std::move(Commands));
+  reply(std::move(Commands));
 }
 
-void ClangdLSPServer::onCompletion(Ctx C, TextDocumentPositionParams &Params) {
-  auto Reply = Server
-                   .codeComplete(std::move(C), Params.textDocument.uri.file,
-                                 Position{Params.position.line,
-                                          Params.position.character},
-                                 CCOpts)
-                   .get(); // FIXME(ibiryukov): This could be made async if we
-                           // had an API that would allow to attach callbacks to
-                           // futures returned by ClangdServer.
-
-  // We have std::move'd from C, now restore it from response of codeComplete.
-  C = std::move(Reply.first);
-  auto List = std::move(Reply.second.Value);
-  reply(C, List);
+void ClangdLSPServer::onCompletion(TextDocumentPositionParams &Params) {
+  Server.codeComplete(Params.textDocument.uri.file,
+                      Position{Params.position.line, Params.position.character},
+                      CCOpts,
+                      [](Tagged<CompletionList> List) { reply(List.Value); });
 }
 
-void ClangdLSPServer::onSignatureHelp(Ctx C,
-                                      TextDocumentPositionParams &Params) {
+void ClangdLSPServer::onSignatureHelp(TextDocumentPositionParams &Params) {
   auto SignatureHelp = Server.signatureHelp(
-      C, Params.textDocument.uri.file,
+      Params.textDocument.uri.file,
       Position{Params.position.line, Params.position.character});
   if (!SignatureHelp)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       llvm::toString(SignatureHelp.takeError()));
-  reply(C, SignatureHelp->Value);
+  reply(SignatureHelp->Value);
 }
 
-void ClangdLSPServer::onGoToDefinition(Ctx C,
-                                       TextDocumentPositionParams &Params) {
+void ClangdLSPServer::onGoToDefinition(TextDocumentPositionParams &Params) {
   auto Items = Server.findDefinitions(
-      C, Params.textDocument.uri.file,
+      Params.textDocument.uri.file,
       Position{Params.position.line, Params.position.character});
   if (!Items)
-    return replyError(C, ErrorCode::InvalidParams,
+    return replyError(ErrorCode::InvalidParams,
                       llvm::toString(Items.takeError()));
-  reply(C, json::ary(Items->Value));
+  reply(json::ary(Items->Value));
 }
 
-void ClangdLSPServer::onSwitchSourceHeader(Ctx C,
-                                           TextDocumentIdentifier &Params) {
+void ClangdLSPServer::onSwitchSourceHeader(TextDocumentIdentifier &Params) {
   llvm::Optional<Path> Result = Server.switchSourceHeader(Params.uri.file);
-  reply(C, Result ? URI::createFile(*Result).toString() : "");
+  reply(Result ? URI::createFile(*Result).toString() : "");
 }
 
-void ClangdLSPServer::onDocumentHighlight(Ctx C,
-                                          TextDocumentPositionParams &Params) {
-
+void ClangdLSPServer::onDocumentHighlight(TextDocumentPositionParams &Params) {
   auto Highlights = Server.findDocumentHighlights(
-      C, Params.textDocument.uri.file,
+      Params.textDocument.uri.file,
       Position{Params.position.line, Params.position.character});
 
   if (!Highlights) {
-    replyError(C, ErrorCode::InternalError,
+    replyError(ErrorCode::InternalError,
                llvm::toString(Highlights.takeError()));
     return;
   }
 
-  reply(C, json::ary(Highlights->Value));
+  reply(json::ary(Highlights->Value));
 }
 
 ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,
@@ -315,8 +296,8 @@ bool ClangdLSPServer::run(std::istream &
   assert(!IsDone && "Run was called before");
 
   // Set up JSONRPCDispatcher.
-  JSONRPCDispatcher Dispatcher([](Context Ctx, const json::Expr &Params) {
-    replyError(Ctx, ErrorCode::MethodNotFound, "method not found");
+  JSONRPCDispatcher Dispatcher([](const json::Expr &Params) {
+    replyError(ErrorCode::MethodNotFound, "method not found");
   });
   registerCallbackHandlers(Dispatcher, Out, /*Callbacks=*/*this);
 
@@ -346,8 +327,7 @@ std::vector<TextEdit> ClangdLSPServer::g
 }
 
 void ClangdLSPServer::onDiagnosticsReady(
-    const Context &Ctx, PathRef File,
-    Tagged<std::vector<DiagWithFixIts>> Diagnostics) {
+    PathRef File, Tagged<std::vector<DiagWithFixIts>> Diagnostics) {
   json::ary DiagnosticsJSON;
 
   DiagnosticToReplacementMap LocalFixIts; // Temporary storage

Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdLSPServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdLSPServer.h Wed Jan 31 05:40:48 2018
@@ -50,32 +50,30 @@ public:
 private:
   // Implement DiagnosticsConsumer.
   virtual void
-  onDiagnosticsReady(const Context &Ctx, PathRef File,
+  onDiagnosticsReady(PathRef File,
                      Tagged<std::vector<DiagWithFixIts>> Diagnostics) override;
 
   // Implement ProtocolCallbacks.
-  void onInitialize(Ctx C, InitializeParams &Params) override;
-  void onShutdown(Ctx C, ShutdownParams &Params) override;
-  void onExit(Ctx C, ExitParams &Params) override;
-  void onDocumentDidOpen(Ctx C, DidOpenTextDocumentParams &Params) override;
-  void onDocumentDidChange(Ctx C, DidChangeTextDocumentParams &Params) override;
-  void onDocumentDidClose(Ctx C, DidCloseTextDocumentParams &Params) override;
+  void onInitialize(InitializeParams &Params) override;
+  void onShutdown(ShutdownParams &Params) override;
+  void onExit(ExitParams &Params) override;
+  void onDocumentDidOpen(DidOpenTextDocumentParams &Params) override;
+  void onDocumentDidChange(DidChangeTextDocumentParams &Params) override;
+  void onDocumentDidClose(DidCloseTextDocumentParams &Params) override;
   void
-  onDocumentOnTypeFormatting(Ctx C,
-                             DocumentOnTypeFormattingParams &Params) override;
+  onDocumentOnTypeFormatting(DocumentOnTypeFormattingParams &Params) override;
   void
-  onDocumentRangeFormatting(Ctx C,
-                            DocumentRangeFormattingParams &Params) override;
-  void onDocumentFormatting(Ctx C, DocumentFormattingParams &Params) override;
-  void onCodeAction(Ctx C, CodeActionParams &Params) override;
-  void onCompletion(Ctx C, TextDocumentPositionParams &Params) override;
-  void onSignatureHelp(Ctx C, TextDocumentPositionParams &Params) override;
-  void onGoToDefinition(Ctx C, TextDocumentPositionParams &Params) override;
-  void onSwitchSourceHeader(Ctx C, TextDocumentIdentifier &Params) override;
-  void onDocumentHighlight(Ctx C, TextDocumentPositionParams &Params) override;
-  void onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) override;
-  void onCommand(Ctx C, ExecuteCommandParams &Params) override;
-  void onRename(Ctx C, RenameParams &Parames) override;
+  onDocumentRangeFormatting(DocumentRangeFormattingParams &Params) override;
+  void onDocumentFormatting(DocumentFormattingParams &Params) override;
+  void onCodeAction(CodeActionParams &Params) override;
+  void onCompletion(TextDocumentPositionParams &Params) override;
+  void onSignatureHelp(TextDocumentPositionParams &Params) override;
+  void onGoToDefinition(TextDocumentPositionParams &Params) override;
+  void onSwitchSourceHeader(TextDocumentIdentifier &Params) override;
+  void onDocumentHighlight(TextDocumentPositionParams &Params) override;
+  void onFileEvent(DidChangeWatchedFilesParams &Params) override;
+  void onCommand(ExecuteCommandParams &Params) override;
+  void onRename(RenameParams &Parames) override;
 
   std::vector<TextEdit> getFixIts(StringRef File, const clangd::Diagnostic &D);
 

Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Wed Jan 31 05:40:48 2018
@@ -116,11 +116,11 @@ ClangdServer::ClangdServer(GlobalCompila
       // is parsed.
       // FIXME(ioeric): this can be slow and we may be able to index on less
       // critical paths.
-      WorkScheduler(
-          AsyncThreadsCount, StorePreamblesInMemory,
-          FileIdx ? [this](const Context &Ctx, PathRef Path,
-                           ParsedAST *AST) { FileIdx->update(Ctx, Path, AST); }
-                  : ASTParsedCallback()) {
+      WorkScheduler(AsyncThreadsCount, StorePreamblesInMemory,
+                    FileIdx
+                        ? [this](PathRef Path,
+                                 ParsedAST *AST) { FileIdx->update(Path, AST); }
+                        : ASTParsedCallback()) {
   if (FileIdx && StaticIdx) {
     MergedIndex = mergeIndex(FileIdx.get(), StaticIdx);
     Index = MergedIndex.get();
@@ -139,35 +139,33 @@ void ClangdServer::setRootPath(PathRef R
     this->RootPath = NewRootPath;
 }
 
-std::future<Context> ClangdServer::addDocument(Context Ctx, PathRef File,
-                                               StringRef Contents) {
+std::future<void> ClangdServer::addDocument(PathRef File, StringRef Contents) {
   DocVersion Version = DraftMgr.updateDraft(File, Contents);
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
-  return scheduleReparseAndDiags(std::move(Ctx), File,
-                                 VersionedDraft{Version, Contents.str()},
+  return scheduleReparseAndDiags(File, VersionedDraft{Version, Contents.str()},
                                  std::move(TaggedFS));
 }
 
-std::future<Context> ClangdServer::removeDocument(Context Ctx, PathRef File) {
+std::future<void> ClangdServer::removeDocument(PathRef File) {
   DraftMgr.removeDraft(File);
   CompileArgs.invalidate(File);
 
-  std::promise<Context> DonePromise;
-  std::future<Context> DoneFuture = DonePromise.get_future();
+  std::promise<void> DonePromise;
+  std::future<void> DoneFuture = DonePromise.get_future();
 
   auto Callback = BindWithForward(
-      [](Context Ctx, std::promise<Context> DonePromise, llvm::Error Err) {
+      [](std::promise<void> DonePromise, llvm::Error Err) {
         if (Err)
           ignoreError(std::move(Err));
-        DonePromise.set_value(std::move(Ctx));
+        DonePromise.set_value();
       },
-      std::move(Ctx), std::move(DonePromise));
+      std::move(DonePromise));
 
   WorkScheduler.remove(File, std::move(Callback));
   return DoneFuture;
 }
 
-std::future<Context> ClangdServer::forceReparse(Context Ctx, PathRef File) {
+std::future<void> ClangdServer::forceReparse(PathRef File) {
   auto FileContents = DraftMgr.getDraft(File);
   assert(FileContents.Draft &&
          "forceReparse() was called for non-added document");
@@ -177,38 +175,34 @@ std::future<Context> ClangdServer::force
   CompileArgs.invalidate(File);
 
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
-  return scheduleReparseAndDiags(std::move(Ctx), File, std::move(FileContents),
+  return scheduleReparseAndDiags(File, std::move(FileContents),
                                  std::move(TaggedFS));
 }
 
-std::future<std::pair<Context, Tagged<CompletionList>>>
-ClangdServer::codeComplete(Context Ctx, PathRef File, Position Pos,
+std::future<Tagged<CompletionList>>
+ClangdServer::codeComplete(PathRef File, Position Pos,
                            const clangd::CodeCompleteOptions &Opts,
                            llvm::Optional<StringRef> OverridenContents,
                            IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
-  using ResultType = std::pair<Context, Tagged<CompletionList>>;
-
-  std::promise<ResultType> ResultPromise;
-
-  auto Callback = [](std::promise<ResultType> ResultPromise, Context Ctx,
+  std::promise<Tagged<CompletionList>> ResultPromise;
+  auto Callback = [](std::promise<Tagged<CompletionList>> ResultPromise,
                      Tagged<CompletionList> Result) -> void {
-    ResultPromise.set_value({std::move(Ctx), std::move(Result)});
+    ResultPromise.set_value(std::move(Result));
   };
 
-  std::future<ResultType> ResultFuture = ResultPromise.get_future();
-  codeComplete(std::move(Ctx), File, Pos, Opts,
+  auto ResultFuture = ResultPromise.get_future();
+  codeComplete(File, Pos, Opts,
                BindWithForward(Callback, std::move(ResultPromise)),
                OverridenContents, UsedFS);
   return ResultFuture;
 }
 
 void ClangdServer::codeComplete(
-    Context Ctx, PathRef File, Position Pos,
-    const clangd::CodeCompleteOptions &Opts,
-    UniqueFunction<void(Context, Tagged<CompletionList>)> Callback,
+    PathRef File, Position Pos, const clangd::CodeCompleteOptions &Opts,
+    UniqueFunction<void(Tagged<CompletionList>)> Callback,
     llvm::Optional<StringRef> OverridenContents,
     IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
-  using CallbackType = UniqueFunction<void(Context, Tagged<CompletionList>)>;
+  using CallbackType = UniqueFunction<void(Tagged<CompletionList>)>;
 
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
   if (UsedFS)
@@ -231,8 +225,8 @@ void ClangdServer::codeComplete(
   // Copy PCHs to avoid accessing this->PCHs concurrently
   std::shared_ptr<PCHContainerOperations> PCHs = this->PCHs;
   auto Task = [PCHs, Pos, TaggedFS, CodeCompleteOpts](
-                  Context Ctx, std::string Contents, Path File,
-                  CallbackType Callback, llvm::Expected<InputsAndPreamble> IP) {
+                  std::string Contents, Path File, CallbackType Callback,
+                  llvm::Expected<InputsAndPreamble> IP) {
     assert(IP && "error when trying to read preamble for codeComplete");
     auto PreambleData = IP->Preamble;
     auto &Command = IP->Inputs.CompileCommand;
@@ -240,20 +234,19 @@ void ClangdServer::codeComplete(
     // FIXME(ibiryukov): even if Preamble is non-null, we may want to check
     // both the old and the new version in case only one of them matches.
     CompletionList Result = clangd::codeComplete(
-        Ctx, File, Command, PreambleData ? &PreambleData->Preamble : nullptr,
+        File, Command, PreambleData ? &PreambleData->Preamble : nullptr,
         Contents, Pos, TaggedFS.Value, PCHs, CodeCompleteOpts);
 
-    Callback(std::move(Ctx),
-             make_tagged(std::move(Result), std::move(TaggedFS.Tag)));
+    Callback(make_tagged(std::move(Result), std::move(TaggedFS.Tag)));
   };
 
-  WorkScheduler.runWithPreamble(
-      File, BindWithForward(Task, std::move(Ctx), std::move(Contents),
-                            File.str(), std::move(Callback)));
+  WorkScheduler.runWithPreamble(File, BindWithForward(Task, std::move(Contents),
+                                                      File.str(),
+                                                      std::move(Callback)));
 }
 
 llvm::Expected<Tagged<SignatureHelp>>
-ClangdServer::signatureHelp(const Context &Ctx, PathRef File, Position Pos,
+ClangdServer::signatureHelp(PathRef File, Position Pos,
                             llvm::Optional<StringRef> OverridenContents,
                             IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS) {
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
@@ -272,7 +265,7 @@ ClangdServer::signatureHelp(const Contex
     Contents = std::move(*Latest.Draft);
   }
 
-  auto Action = [=, &Ctx](llvm::Expected<InputsAndPreamble> IP)
+  auto Action = [=](llvm::Expected<InputsAndPreamble> IP)
       -> Expected<Tagged<SignatureHelp>> {
     if (!IP)
       return IP.takeError();
@@ -280,7 +273,7 @@ ClangdServer::signatureHelp(const Contex
     auto &Command = IP->Inputs.CompileCommand;
 
     return make_tagged(
-        clangd::signatureHelp(Ctx, File, Command,
+        clangd::signatureHelp(File, Command,
                               PreambleData ? &PreambleData->Preamble : nullptr,
                               Contents, Pos, TaggedFS.Value, PCHs),
         TaggedFS.Tag);
@@ -316,8 +309,7 @@ ClangdServer::formatOnType(StringRef Cod
 }
 
 Expected<std::vector<tooling::Replacement>>
-ClangdServer::rename(const Context &Ctx, PathRef File, Position Pos,
-                     llvm::StringRef NewName) {
+ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName) {
   using RetType = Expected<std::vector<tooling::Replacement>>;
   auto Action = [=](Expected<InputsAndAST> InpAST) -> RetType {
     if (!InpAST)
@@ -396,14 +388,14 @@ std::string ClangdServer::dumpAST(PathRe
 }
 
 llvm::Expected<Tagged<std::vector<Location>>>
-ClangdServer::findDefinitions(const Context &Ctx, PathRef File, Position Pos) {
+ClangdServer::findDefinitions(PathRef File, Position Pos) {
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
 
   using RetType = llvm::Expected<Tagged<std::vector<Location>>>;
-  auto Action = [=, &Ctx](llvm::Expected<InputsAndAST> InpAST) -> RetType {
+  auto Action = [=](llvm::Expected<InputsAndAST> InpAST) -> RetType {
     if (!InpAST)
       return InpAST.takeError();
-    auto Result = clangd::findDefinitions(Ctx, InpAST->AST, Pos);
+    auto Result = clangd::findDefinitions(InpAST->AST, Pos);
     return make_tagged(std::move(Result), TaggedFS.Tag);
   };
   return blockingRunWithAST<RetType>(WorkScheduler, File, Action);
@@ -483,8 +475,7 @@ ClangdServer::formatCode(llvm::StringRef
 }
 
 llvm::Expected<Tagged<std::vector<DocumentHighlight>>>
-ClangdServer::findDocumentHighlights(const Context &Ctx, PathRef File,
-                                     Position Pos) {
+ClangdServer::findDocumentHighlights(PathRef File, Position Pos) {
   auto FileContents = DraftMgr.getDraft(File);
   if (!FileContents.Draft)
     return llvm::make_error<llvm::StringError>(
@@ -494,17 +485,17 @@ ClangdServer::findDocumentHighlights(con
   auto TaggedFS = FSProvider.getTaggedFileSystem(File);
 
   using RetType = llvm::Expected<Tagged<std::vector<DocumentHighlight>>>;
-  auto Action = [=, &Ctx](llvm::Expected<InputsAndAST> InpAST) -> RetType {
+  auto Action = [=](llvm::Expected<InputsAndAST> InpAST) -> RetType {
     if (!InpAST)
       return InpAST.takeError();
-    auto Result = clangd::findDocumentHighlights(Ctx, InpAST->AST, Pos);
+    auto Result = clangd::findDocumentHighlights(InpAST->AST, Pos);
     return make_tagged(std::move(Result), TaggedFS.Tag);
   };
   return blockingRunWithAST<RetType>(WorkScheduler, File, Action);
 }
 
-std::future<Context> ClangdServer::scheduleReparseAndDiags(
-    Context Ctx, PathRef File, VersionedDraft Contents,
+std::future<void> ClangdServer::scheduleReparseAndDiags(
+    PathRef File, VersionedDraft Contents,
     Tagged<IntrusiveRefCntPtr<vfs::FileSystem>> TaggedFS) {
   tooling::CompileCommand Command = CompileArgs.getCompileCommand(File);
 
@@ -514,14 +505,12 @@ std::future<Context> ClangdServer::sched
   Path FileStr = File.str();
   VFSTag Tag = std::move(TaggedFS.Tag);
 
-  std::promise<Context> DonePromise;
-  std::future<Context> DoneFuture = DonePromise.get_future();
+  std::promise<void> DonePromise;
+  std::future<void> DoneFuture = DonePromise.get_future();
 
-  auto Callback = [this, Version, FileStr,
-                   Tag](std::promise<Context> DonePromise, Context Ctx,
-                        OptDiags Diags) {
-    auto Guard =
-        llvm::make_scope_exit([&]() { DonePromise.set_value(std::move(Ctx)); });
+  auto Callback = [this, Version, FileStr, Tag](std::promise<void> DonePromise,
+                                                OptDiags Diags) {
+    auto Guard = llvm::make_scope_exit([&]() { DonePromise.set_value(); });
     if (!Diags)
       return; // A new reparse was requested before this one completed.
 
@@ -538,10 +527,10 @@ std::future<Context> ClangdServer::sched
     LastReportedDiagsVersion = Version;
 
     DiagConsumer.onDiagnosticsReady(
-        Ctx, FileStr, make_tagged(std::move(*Diags), std::move(Tag)));
+        FileStr, make_tagged(std::move(*Diags), std::move(Tag)));
   };
 
-  WorkScheduler.update(std::move(Ctx), File,
+  WorkScheduler.update(File,
                        ParseInputs{std::move(Command),
                                    std::move(TaggedFS.Value),
                                    std::move(*Contents.Draft)},

Modified: clang-tools-extra/trunk/clangd/ClangdServer.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.h Wed Jan 31 05:40:48 2018
@@ -71,7 +71,7 @@ public:
 
   /// Called by ClangdServer when \p Diagnostics for \p File are ready.
   virtual void
-  onDiagnosticsReady(const Context &Ctx, PathRef File,
+  onDiagnosticsReady(PathRef File,
                      Tagged<std::vector<DiagWithFixIts>> Diagnostics) = 0;
 };
 
@@ -95,8 +95,6 @@ public:
   getTaggedFileSystem(PathRef File) override;
 };
 
-class ClangdServer;
-
 /// Provides API to manage ASTs for a collection of C++ files and request
 /// various language features.
 /// Currently supports async diagnostics, code completion, formatting and goto
@@ -156,30 +154,26 @@ public:
   /// diagnostics) is finished.
   /// FIXME: don't return futures here, LSP does not require a response for this
   /// request.
-  std::future<Context> addDocument(Context Ctx, PathRef File,
-                                   StringRef Contents);
+  std::future<void> addDocument(PathRef File, StringRef Contents);
+
   /// Remove \p File from list of tracked files, schedule a request to free
   /// resources associated with it.
   /// \return A future that will become ready when the file is removed and all
   /// associated resources are freed.
   /// FIXME: don't return futures here, LSP does not require a response for this
   /// request.
-  std::future<Context> removeDocument(Context Ctx, PathRef File);
+  std::future<void> removeDocument(PathRef File);
+
   /// Force \p File to be reparsed using the latest contents.
   /// Will also check if CompileCommand, provided by GlobalCompilationDatabase
   /// for \p File has changed. If it has, will remove currently stored Preamble
   /// and AST and rebuild them from scratch.
   /// FIXME: don't return futures here, LSP does not require a response for this
   /// request.
-  std::future<Context> forceReparse(Context Ctx, PathRef File);
+  std::future<void> forceReparse(PathRef File);
 
-  /// DEPRECATED. Please use a callback-based version, this API is deprecated
-  /// and will soon be removed.
-  ///
   /// Run code completion for \p File at \p Pos.
-  ///
-  /// Request is processed asynchronously. You can use the returned future to
-  /// wait for the results of the async request.
+  /// Request is processed asynchronously.
   ///
   /// If \p OverridenContents is not None, they will used only for code
   /// completion, i.e. no diagnostics update will be scheduled and a draft for
@@ -190,18 +184,18 @@ public:
   /// This method should only be called for currently tracked files. However, it
   /// is safe to call removeDocument for \p File after this method returns, even
   /// while returned future is not yet ready.
-  std::future<std::pair<Context, Tagged<CompletionList>>>
-  codeComplete(Context Ctx, PathRef File, Position Pos,
-               const clangd::CodeCompleteOptions &Opts,
-               llvm::Optional<StringRef> OverridenContents = llvm::None,
-               IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
-
   /// A version of `codeComplete` that runs \p Callback on the processing thread
   /// when codeComplete results become available.
-  void
-  codeComplete(Context Ctx, PathRef File, Position Pos,
+  void codeComplete(PathRef File, Position Pos,
+                    const clangd::CodeCompleteOptions &Opts,
+                    UniqueFunction<void(Tagged<CompletionList>)> Callback,
+                    llvm::Optional<StringRef> OverridenContents = llvm::None,
+                    IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
+
+  /// DEPRECATED: Please use the callback-based version of codeComplete.
+  std::future<Tagged<CompletionList>>
+  codeComplete(PathRef File, Position Pos,
                const clangd::CodeCompleteOptions &Opts,
-               UniqueFunction<void(Context, Tagged<CompletionList>)> Callback,
                llvm::Optional<StringRef> OverridenContents = llvm::None,
                IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
 
@@ -213,13 +207,13 @@ public:
   /// vfs::FileSystem used for signature help. This method should only be called
   /// for currently tracked files.
   llvm::Expected<Tagged<SignatureHelp>>
-  signatureHelp(const Context &Ctx, PathRef File, Position Pos,
+  signatureHelp(PathRef File, Position Pos,
                 llvm::Optional<StringRef> OverridenContents = llvm::None,
                 IntrusiveRefCntPtr<vfs::FileSystem> *UsedFS = nullptr);
 
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
-  llvm::Expected<Tagged<std::vector<Location>>>
-  findDefinitions(const Context &Ctx, PathRef File, Position Pos);
+  llvm::Expected<Tagged<std::vector<Location>>> findDefinitions(PathRef File,
+                                                                Position Pos);
 
   /// Helper function that returns a path to the corresponding source file when
   /// given a header file and vice versa.
@@ -227,7 +221,7 @@ public:
 
   /// Get document highlights for a given position.
   llvm::Expected<Tagged<std::vector<DocumentHighlight>>>
-  findDocumentHighlights(const Context &Ctx, PathRef File, Position Pos);
+  findDocumentHighlights(PathRef File, Position Pos);
 
   /// Run formatting for \p Rng inside \p File with content \p Code.
   llvm::Expected<tooling::Replacements> formatRange(StringRef Code,
@@ -244,8 +238,7 @@ public:
 
   /// Rename all occurrences of the symbol at the \p Pos in \p File to
   /// \p NewName.
-  Expected<std::vector<tooling::Replacement>> rename(const Context &Ctx,
-                                                     PathRef File, Position Pos,
+  Expected<std::vector<tooling::Replacement>> rename(PathRef File, Position Pos,
                                                      llvm::StringRef NewName);
 
   /// Gets current document contents for \p File. Returns None if \p File is not
@@ -277,8 +270,8 @@ private:
   formatCode(llvm::StringRef Code, PathRef File,
              ArrayRef<tooling::Range> Ranges);
 
-  std::future<Context>
-  scheduleReparseAndDiags(Context Ctx, PathRef File, VersionedDraft Contents,
+  std::future<void>
+  scheduleReparseAndDiags(PathRef File, VersionedDraft Contents,
                           Tagged<IntrusiveRefCntPtr<vfs::FileSystem>> TaggedFS);
 
   CompileArgsCache CompileArgs;

Modified: clang-tools-extra/trunk/clangd/ClangdUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp Wed Jan 31 05:40:48 2018
@@ -229,8 +229,7 @@ void clangd::dumpAST(ParsedAST &AST, llv
 }
 
 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
       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::deferCan
 }
 
 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 &&Inpu
   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 &&Inpu
       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 &&Inpu
       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 &&Inpu
     // 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();

Modified: clang-tools-extra/trunk/clangd/ClangdUnit.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.h Wed Jan 31 05:40:48 2018
@@ -10,7 +10,6 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
 
-#include "Context.h"
 #include "Function.h"
 #include "Path.h"
 #include "Protocol.h"
@@ -71,7 +70,7 @@ public:
   /// Attempts to run Clang and store parsed AST. If \p Preamble is non-null
   /// it is reused during parsing.
   static llvm::Optional<ParsedAST>
-  Build(const Context &Ctx, std::unique_ptr<clang::CompilerInvocation> CI,
+  Build(std::unique_ptr<clang::CompilerInvocation> CI,
         std::shared_ptr<const PreambleData> Preamble,
         std::unique_ptr<llvm::MemoryBuffer> Buffer,
         std::shared_ptr<PCHContainerOperations> PCHs,
@@ -148,8 +147,7 @@ private:
   mutable llvm::Optional<ParsedAST> AST;
 };
 
-using ASTParsedCallback =
-    std::function<void(const Context &Ctx, PathRef Path, ParsedAST *)>;
+using ASTParsedCallback = std::function<void(PathRef Path, ParsedAST *)>;
 
 /// Manages resources, required by clangd. Allows to rebuild file with new
 /// contents, and provides AST and Preamble for it.
@@ -186,8 +184,7 @@ public:
   /// Returns a list of diagnostics or a llvm::None, if another rebuild was
   /// requested in parallel (effectively cancelling this rebuild) before
   /// diagnostics were produced.
-  llvm::Optional<std::vector<DiagWithFixIts>> rebuild(const Context &Ctx,
-                                                      ParseInputs &&Inputs);
+  llvm::Optional<std::vector<DiagWithFixIts>> rebuild(ParseInputs &&Inputs);
 
   /// Schedule a rebuild and return a deferred computation that will finish the
   /// rebuild, that can be called on a different thread.
@@ -203,7 +200,7 @@ public:
   /// The future to finish rebuild returns a list of diagnostics built during
   /// reparse, or None, if another deferRebuild was called before this
   /// rebuild was finished.
-  UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>(const Context &)>
+  UniqueFunction<llvm::Optional<std::vector<DiagWithFixIts>>()>
   deferRebuild(ParseInputs &&Inputs);
 
   /// Returns a future to get the most fresh PreambleData for a file. The

Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Wed Jan 31 05:40:48 2018
@@ -633,12 +633,11 @@ struct SemaCompleteInput {
 
 // Invokes Sema code completion on a file.
 // Callback will be invoked once completion is done, but before cleaning up.
-bool semaCodeComplete(const Context &Ctx,
-                      std::unique_ptr<CodeCompleteConsumer> Consumer,
+bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
                       const clang::CodeCompleteOptions &Options,
                       const SemaCompleteInput &Input,
                       llvm::function_ref<void()> Callback = nullptr) {
-  auto Tracer = llvm::make_unique<trace::Span>(Ctx, "Sema completion");
+  auto Tracer = llvm::make_unique<trace::Span>("Sema completion");
   std::vector<const char *> ArgStrs;
   for (const auto &S : Input.Command.CommandLine)
     ArgStrs.push_back(S.c_str());
@@ -690,13 +689,12 @@ bool semaCodeComplete(const Context &Ctx
 
   SyntaxOnlyAction Action;
   if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
-    log(Ctx, "BeginSourceFile() failed when running codeComplete for " +
-                 Input.FileName);
+    log("BeginSourceFile() failed when running codeComplete for " +
+        Input.FileName);
     return false;
   }
   if (!Action.Execute()) {
-    log(Ctx,
-        "Execute() failed when running codeComplete for " + Input.FileName);
+    log("Execute() failed when running codeComplete for " + Input.FileName);
     return false;
   }
   Tracer.reset();
@@ -704,7 +702,7 @@ bool semaCodeComplete(const Context &Ctx
   if (Callback)
     Callback();
 
-  Tracer = llvm::make_unique<trace::Span>(Ctx, "Sema completion cleanup");
+  Tracer = llvm::make_unique<trace::Span>("Sema completion cleanup");
   Action.EndSourceFile();
 
   return true;
@@ -801,8 +799,6 @@ clang::CodeCompleteOptions CodeCompleteO
 //     This score is combined with the result quality score for the final score.
 //   - TopN determines the results with the best score.
 class CodeCompleteFlow {
-  trace::Span Tracer;
-  const Context &Ctx;
   const CodeCompleteOptions &Opts;
   // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup.
   std::unique_ptr<CompletionRecorder> RecorderOwner;
@@ -813,21 +809,22 @@ class CodeCompleteFlow {
 
 public:
   // A CodeCompleteFlow object is only useful for calling run() exactly once.
-  CodeCompleteFlow(const Context &Ctx, const CodeCompleteOptions &Opts)
-      : Tracer(Ctx, "CodeCompleteFlow"), Ctx(Tracer.Ctx), Opts(Opts),
-        RecorderOwner(new CompletionRecorder(Opts)), Recorder(*RecorderOwner) {}
+  CodeCompleteFlow(const CodeCompleteOptions &Opts)
+      : Opts(Opts), RecorderOwner(new CompletionRecorder(Opts)),
+        Recorder(*RecorderOwner) {}
 
   CompletionList run(const SemaCompleteInput &SemaCCInput) && {
+    trace::Span Tracer("CodeCompleteFlow");
     // We run Sema code completion first. It builds an AST and calculates:
     //   - completion results based on the AST. These are saved for merging.
     //   - partial identifier and context. We need these for the index query.
     CompletionList Output;
-    semaCodeComplete(Ctx, std::move(RecorderOwner), Opts.getClangCompleteOpts(),
+    semaCodeComplete(std::move(RecorderOwner), Opts.getClangCompleteOpts(),
                      SemaCCInput, [&] {
                        if (Recorder.CCSema)
                          Output = runWithSema();
                        else
-                         log(Ctx, "Code complete: no Sema callback, 0 results");
+                         log("Code complete: no Sema callback, 0 results");
                      });
 
     SPAN_ATTACH(Tracer, "sema_results", NSema);
@@ -835,8 +832,7 @@ public:
     SPAN_ATTACH(Tracer, "merged_results", NBoth);
     SPAN_ATTACH(Tracer, "returned_results", Output.items.size());
     SPAN_ATTACH(Tracer, "incomplete", Output.isIncomplete);
-    log(Ctx,
-        llvm::formatv("Code complete: {0} results from Sema, {1} from Index, "
+    log(llvm::formatv("Code complete: {0} results from Sema, {1} from Index, "
                       "{2} matched, {3} returned{4}.",
                       NSema, NIndex, NBoth, Output.items.size(),
                       Output.isIncomplete ? " (incomplete)" : ""));
@@ -871,7 +867,7 @@ private:
   SymbolSlab queryIndex() {
     if (!Opts.Index || !allowIndex(Recorder.CCContext.getKind()))
       return SymbolSlab();
-    trace::Span Tracer(Ctx, "Query index");
+    trace::Span Tracer("Query index");
     SPAN_ATTACH(Tracer, "limit", Opts.Limit);
 
     SymbolSlab::Builder ResultsBuilder;
@@ -882,15 +878,12 @@ private:
     Req.Query = Filter->pattern();
     Req.Scopes =
         getQueryScopes(Recorder.CCContext, Recorder.CCSema->getSourceManager());
-    log(Tracer.Ctx,
-        llvm::formatv("Code complete: fuzzyFind(\"{0}\", Scopes: [{1}]",
+    log(llvm::formatv("Code complete: fuzzyFind(\"{0}\", scopes=[{1}])",
                       Req.Query,
                       llvm::join(Req.Scopes.begin(), Req.Scopes.end(), ",")));
     // Run the query against the index.
-    Incomplete |=
-        !Opts.Index->fuzzyFind(Tracer.Ctx, Req, [&](const Symbol &Sym) {
-          ResultsBuilder.insert(Sym);
-        });
+    Incomplete |= !Opts.Index->fuzzyFind(
+        Req, [&](const Symbol &Sym) { ResultsBuilder.insert(Sym); });
     return std::move(ResultsBuilder).build();
   }
 
@@ -899,7 +892,7 @@ private:
   std::vector<std::pair<CompletionCandidate, CompletionItemScores>>
   mergeResults(const std::vector<CodeCompletionResult> &SemaResults,
                const SymbolSlab &IndexResults) {
-    trace::Span Tracer(Ctx, "Merge and score results");
+    trace::Span Tracer("Merge and score results");
     // We only keep the best N results at any time, in "native" format.
     TopN Top(Opts.Limit == 0 ? TopN::Unbounded : Opts.Limit);
     llvm::DenseSet<const Symbol *> UsedIndexResults;
@@ -960,18 +953,18 @@ private:
   }
 };
 
-CompletionList codeComplete(const Context &Ctx, PathRef FileName,
+CompletionList codeComplete(PathRef FileName,
                             const tooling::CompileCommand &Command,
                             PrecompiledPreamble const *Preamble,
                             StringRef Contents, Position Pos,
                             IntrusiveRefCntPtr<vfs::FileSystem> VFS,
                             std::shared_ptr<PCHContainerOperations> PCHs,
                             CodeCompleteOptions Opts) {
-  return CodeCompleteFlow(Ctx, Opts).run(
+  return CodeCompleteFlow(Opts).run(
       {FileName, Command, Preamble, Contents, Pos, VFS, PCHs});
 }
 
-SignatureHelp signatureHelp(const Context &Ctx, PathRef FileName,
+SignatureHelp signatureHelp(PathRef FileName,
                             const tooling::CompileCommand &Command,
                             PrecompiledPreamble const *Preamble,
                             StringRef Contents, Position Pos,
@@ -983,10 +976,10 @@ SignatureHelp signatureHelp(const Contex
   Options.IncludeMacros = false;
   Options.IncludeCodePatterns = false;
   Options.IncludeBriefComments = true;
-  semaCodeComplete(
-      Ctx, llvm::make_unique<SignatureHelpCollector>(Options, Result), Options,
-      {FileName, Command, Preamble, Contents, Pos, std::move(VFS),
-       std::move(PCHs)});
+  semaCodeComplete(llvm::make_unique<SignatureHelpCollector>(Options, Result),
+                   Options,
+                   {FileName, Command, Preamble, Contents, Pos, std::move(VFS),
+                    std::move(PCHs)});
   return Result;
 }
 

Modified: clang-tools-extra/trunk/clangd/CodeComplete.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.h (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.h Wed Jan 31 05:40:48 2018
@@ -15,7 +15,6 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CODECOMPLETE_H
 
-#include "Context.h"
 #include "Logger.h"
 #include "Path.h"
 #include "Protocol.h"
@@ -67,7 +66,7 @@ struct CodeCompleteOptions {
 };
 
 /// Get code completions at a specified \p Pos in \p FileName.
-CompletionList codeComplete(const Context &Ctx, PathRef FileName,
+CompletionList codeComplete(PathRef FileName,
                             const tooling::CompileCommand &Command,
                             PrecompiledPreamble const *Preamble,
                             StringRef Contents, Position Pos,
@@ -76,7 +75,7 @@ CompletionList codeComplete(const Contex
                             CodeCompleteOptions Opts);
 
 /// Get signature help at a specified \p Pos in \p FileName.
-SignatureHelp signatureHelp(const Context &Ctx, PathRef FileName,
+SignatureHelp signatureHelp(PathRef FileName,
                             const tooling::CompileCommand &Command,
                             PrecompiledPreamble const *Preamble,
                             StringRef Contents, Position Pos,

Modified: clang-tools-extra/trunk/clangd/Context.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Context.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Context.cpp (original)
+++ clang-tools-extra/trunk/clangd/Context.cpp Wed Jan 31 05:40:48 2018
@@ -20,5 +20,19 @@ Context::Context(std::shared_ptr<const D
 
 Context Context::clone() const { return Context(DataPtr); }
 
+// The thread-local Context is scoped in a function to avoid
+// initialization-order issues. It's created when first needed.
+static Context &currentContext() {
+  static thread_local Context C = Context::empty();
+  return C;
+}
+
+const Context &Context::current() { return currentContext(); }
+
+Context Context::swapCurrent(Context Replacement) {
+  std::swap(Replacement, currentContext());
+  return Replacement;
+}
+
 } // namespace clangd
 } // namespace clang

Modified: clang-tools-extra/trunk/clangd/Context.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Context.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Context.h (original)
+++ clang-tools-extra/trunk/clangd/Context.h Wed Jan 31 05:40:48 2018
@@ -16,15 +16,28 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONTEXT_H_
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
 #include <memory>
 #include <type_traits>
 
 namespace clang {
 namespace clangd {
 
-/// A key for a value of type \p Type, stored inside a context. Keys are
-/// non-movable and non-copyable. See documentation of the Context class for
-/// more details and usage examples.
+/// Values in a Context are indexed by typed keys.
+/// Key<T> serves two purposes:
+///   - it provides a lookup key for the context (each Key is unique),
+///   - it makes lookup type-safe: a Key<T> can only map to a T (or nothing).
+///
+/// Example:
+///    Key<int> RequestID;
+///    Key<int> Version;
+///
+///    Context Ctx = Context::empty().derive(RequestID, 10).derive(Version, 3);
+///    assert(*Ctx.get(RequestID) == 10);
+///    assert(*Ctx.get(Version) == 3);
+///
+/// Keys are typically used across multiple functions, so most of the time you
+/// would want to make them static class members or global variables.
 template <class Type> class Key {
 public:
   static_assert(!std::is_reference<Type>::value,
@@ -45,53 +58,24 @@ public:
 /// Conceptually, a context is a heterogeneous map<Key<T>, T>. Each key has
 /// an associated value type, which allows the map to be typesafe.
 ///
+/// There is an "ambient" context for each thread, Context::current().
+/// Most functions should read from this, and use WithContextValue or
+/// WithContext to extend or replace the context within a block scope.
+/// Only code dealing with threads and extension points should need to use
+/// other Context objects.
+///
 /// You can't add data to an existing context, instead you create a new
 /// immutable context derived from it with extra data added. When you retrieve
 /// data, the context will walk up the parent chain until the key is found.
-///
-/// Contexts should be:
-///  - passed by reference when calling synchronous functions
-///  - passed by value (move) when calling asynchronous functions. The result
-///    callback of async operations will receive the context again.
-///  - cloned only when 'forking' an asynchronous computation that we don't wait
-///    for.
-///
-/// Copy operations for this class are deleted, use an explicit clone() method
-/// when you need a copy of the context instead.
-///
-/// To derive a child context use derive() function, e.g.
-///     Context ChildCtx = ParentCtx.derive(RequestIdKey, 123);
-///
-/// To create a new root context, derive() from empty Context.
-/// e.g.:
-///     Context Ctx = Context::empty().derive(RequestIdKey, 123);
-///
-/// Values in the context are indexed by typed keys (instances of Key<T> class).
-/// Key<T> serves two purposes:
-///   - it provides a lookup key for the context (each instance of a key is
-///   unique),
-///   - it keeps the type information about the value stored in the context map
-///   in the template arguments.
-/// This provides a type-safe interface to store and access values of multiple
-/// types inside a single context.
-/// For example,
-///    Key<int> RequestID;
-///    Key<int> Version;
-///
-///    Context Ctx = Context::empty().derive(RequestID, 10).derive(Version, 3);
-///    assert(*Ctx.get(RequestID) == 10);
-///    assert(*Ctx.get(Version) == 3);
-///
-/// Keys are typically used across multiple functions, so most of the time you
-/// would want to make them static class members or global variables.
-///
-/// FIXME: Rather than manual plumbing, pass Context using thread-local storage
-/// by default, and make thread boundaries deal with propagation explicitly.
 class Context {
 public:
-  /// Returns an empty context that contains no data. Useful for calling
-  /// functions that require a context when no explicit context is available.
+  /// Returns an empty root context that contains no data.
   static Context empty();
+  /// Returns the context for the current thread, creating it if needed.
+  static const Context &current();
+  // Sets the current() context to Replacement, and returns the old context.
+  // Prefer to use WithContext or WithContextValue to do this safely.
+  static Context swapCurrent(Context Replacement);
 
 private:
   struct Data;
@@ -103,7 +87,8 @@ public:
   /// (arguments of std::future<> must be default-construcitble in MSVC).
   Context() = default;
 
-  /// Move-only.
+  /// Copy operations for this class are deleted, use an explicit clone() method
+  /// when you need a copy of the context instead.
   Context(Context const &) = delete;
   Context &operator=(const Context &) = delete;
 
@@ -131,9 +116,8 @@ public:
   }
 
   /// Derives a child context
-  /// It is safe to move or destroy a parent context after calling derive() from
-  /// it. The child context will continue to have access to the data stored in
-  /// the parent context.
+  /// It is safe to move or destroy a parent context after calling derive().
+  /// The child will keep its parent alive, and its data remains accessible.
   template <class Type>
   Context derive(const Key<Type> &Key,
                  typename std::decay<Type>::type Value) const & {
@@ -198,7 +182,40 @@ private:
   };
 
   std::shared_ptr<const Data> DataPtr;
-}; // namespace clangd
+};
+
+/// WithContext replaces Context::current() with a provided scope.
+/// When the WithContext is destroyed, the original scope is restored.
+/// For extending the current context with new value, prefer WithContextValue.
+class LLVM_NODISCARD WithContext {
+public:
+  WithContext(Context C) : Restore(Context::swapCurrent(std::move(C))) {}
+  ~WithContext() { Context::swapCurrent(std::move(Restore)); }
+  WithContext(const WithContext &) = delete;
+  WithContext &operator=(const WithContext &) = delete;
+  WithContext(WithContext &&) = delete;
+  WithContext &operator=(WithContext &&) = delete;
+
+private:
+  Context Restore;
+};
+
+/// WithContextValue extends Context::current() with a single value.
+/// When the WithContextValue is destroyed, the original scope is restored.
+class LLVM_NODISCARD WithContextValue {
+public:
+  template <typename T>
+  WithContextValue(const Key<T> &K, typename std::decay<T>::type V)
+      : Restore(Context::current().derive(K, std::move(V))) {}
+
+  // Anonymous values can be used for the destructor side-effect.
+  template <typename T>
+  WithContextValue(T &&V)
+      : Restore(Context::current().derive(std::forward<T>(V))) {}
+
+private:
+  WithContext Restore;
+};
 
 } // namespace clangd
 } // namespace clang

Modified: clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp (original)
+++ clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp Wed Jan 31 05:40:48 2018
@@ -38,8 +38,7 @@ DirectoryBasedGlobalCompilationDatabase:
       return std::move(Candidates.front());
     }
   } else {
-    log(Context::empty(), // FIXME(ibiryukov): pass a proper Context here.
-        "Failed to find compilation database for " + Twine(File));
+    log("Failed to find compilation database for " + Twine(File));
   }
   return llvm::None;
 }

Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp Wed Jan 31 05:40:48 2018
@@ -34,14 +34,14 @@ class RequestSpan {
 public:
   // Return a context that's aware of the enclosing request, identified by Span.
   static Context stash(const trace::Span &Span) {
-    return Span.Ctx.derive(RSKey, std::unique_ptr<RequestSpan>(
-                                                 new RequestSpan(Span.Args)));
+    return Context::current().derive(
+        RSKey, std::unique_ptr<RequestSpan>(new RequestSpan(Span.Args)));
   }
 
   // If there's an enclosing request and the tracer is interested, calls \p F
   // with a json::obj where request info can be added.
-  template <typename Func> static void attach(const Context &Ctx, Func &&F) {
-    auto *RequestArgs = Ctx.get(RSKey);
+  template <typename Func> static void attach(Func &&F) {
+    auto *RequestArgs = Context::current().get(RSKey);
     if (!RequestArgs || !*RequestArgs || !(*RequestArgs)->Args)
       return;
     std::lock_guard<std::mutex> Lock((*RequestArgs)->Mu);
@@ -70,8 +70,8 @@ void JSONOutput::writeMessage(const json
   Outs.flush();
 }
 
-void JSONOutput::log(const Context &Ctx, const Twine &Message) {
-  trace::log(Ctx, Message);
+void JSONOutput::log(const Twine &Message) {
+  trace::log(Message);
   std::lock_guard<std::mutex> Guard(StreamMutex);
   Logs << Message << '\n';
   Logs.flush();
@@ -85,16 +85,15 @@ void JSONOutput::mirrorInput(const Twine
   InputMirror->flush();
 }
 
-void clangd::reply(const Context &Ctx, json::Expr &&Result) {
-  auto ID = Ctx.get(RequestID);
+void clangd::reply(json::Expr &&Result) {
+  auto ID = Context::current().get(RequestID);
   if (!ID) {
-    log(Ctx, "Attempted to reply to a notification!");
+    log("Attempted to reply to a notification!");
     return;
   }
-
-  RequestSpan::attach(Ctx, [&](json::obj &Args) { Args["Reply"] = Result; });
-
-  Ctx.getExisting(RequestOut)
+  RequestSpan::attach([&](json::obj &Args) { Args["Reply"] = Result; });
+  Context::current()
+      .getExisting(RequestOut)
       ->writeMessage(json::obj{
           {"jsonrpc", "2.0"},
           {"id", *ID},
@@ -102,16 +101,16 @@ void clangd::reply(const Context &Ctx, j
       });
 }
 
-void clangd::replyError(const Context &Ctx, ErrorCode code,
-                        const llvm::StringRef &Message) {
-  log(Ctx, "Error " + Twine(static_cast<int>(code)) + ": " + Message);
-  RequestSpan::attach(Ctx, [&](json::obj &Args) {
+void clangd::replyError(ErrorCode code, const llvm::StringRef &Message) {
+  log("Error " + Twine(static_cast<int>(code)) + ": " + Message);
+  RequestSpan::attach([&](json::obj &Args) {
     Args["Error"] =
         json::obj{{"code", static_cast<int>(code)}, {"message", Message.str()}};
   });
 
-  if (auto ID = Ctx.get(RequestID)) {
-    Ctx.getExisting(RequestOut)
+  if (auto ID = Context::current().get(RequestID)) {
+    Context::current()
+        .getExisting(RequestOut)
         ->writeMessage(json::obj{
             {"jsonrpc", "2.0"},
             {"id", *ID},
@@ -121,13 +120,14 @@ void clangd::replyError(const Context &C
   }
 }
 
-void clangd::call(const Context &Ctx, StringRef Method, json::Expr &&Params) {
+void clangd::call(StringRef Method, json::Expr &&Params) {
   // FIXME: Generate/Increment IDs for every request so that we can get proper
   // replies once we need to.
-  RequestSpan::attach(Ctx, [&](json::obj &Args) {
+  RequestSpan::attach([&](json::obj &Args) {
     Args["Call"] = json::obj{{"method", Method.str()}, {"params", Params}};
   });
-  Ctx.getExisting(RequestOut)
+  Context::current()
+      .getExisting(RequestOut)
       ->writeMessage(json::obj{
           {"jsonrpc", "2.0"},
           {"id", 1},
@@ -163,18 +163,20 @@ bool JSONRPCDispatcher::call(const json:
   auto &Handler = I != Handlers.end() ? I->second : UnknownHandler;
 
   // Create a Context that contains request information.
-  auto Ctx = Context::empty().derive(RequestOut, &Out);
+  WithContextValue WithRequestOut(RequestOut, &Out);
+  llvm::Optional<WithContextValue> WithID;
   if (ID)
-    Ctx = std::move(Ctx).derive(RequestID, *ID);
+    WithID.emplace(RequestID, *ID);
 
   // Create a tracing Span covering the whole request lifetime.
-  trace::Span Tracer(Ctx, *Method);
+  trace::Span Tracer(*Method);
   if (ID)
     SPAN_ATTACH(Tracer, "ID", *ID);
   SPAN_ATTACH(Tracer, "Params", Params);
 
   // Stash a reference to the span args, so later calls can add metadata.
-  Handler(RequestSpan::stash(Tracer), std::move(Params));
+  WithContext WithRequestSpan(RequestSpan::stash(Tracer));
+  Handler(std::move(Params));
   return true;
 }
 
@@ -216,10 +218,9 @@ void clangd::runLanguageServerLoop(std::
       // The end of headers is signified by an empty line.
       if (LineRef.consume_front("Content-Length: ")) {
         if (ContentLength != 0) {
-          log(Context::empty(),
-              "Warning: Duplicate Content-Length header received. "
+          log("Warning: Duplicate Content-Length header received. "
               "The previous value for this message (" +
-                  llvm::Twine(ContentLength) + ") was ignored.\n");
+              llvm::Twine(ContentLength) + ") was ignored.\n");
         }
 
         llvm::getAsUnsignedInteger(LineRef.trim(), 0, ContentLength);
@@ -238,8 +239,8 @@ void clangd::runLanguageServerLoop(std::
     // and we don't want to crash downstream because of it.
     if (ContentLength > 1 << 30) { // 1024M
       In.ignore(ContentLength);
-      log(Context::empty(), "Skipped overly large message of " +
-                                Twine(ContentLength) + " bytes.\n");
+      log("Skipped overly large message of " + Twine(ContentLength) +
+          " bytes.\n");
       continue;
     }
 
@@ -253,9 +254,8 @@ void clangd::runLanguageServerLoop(std::
         // If the stream is aborted before we read ContentLength bytes, In
         // will have eofbit and failbit set.
         if (!In) {
-          log(Context::empty(),
-              "Input was aborted. Read only " + llvm::Twine(In.gcount()) +
-                  " bytes of expected " + llvm::Twine(ContentLength) + ".\n");
+          log("Input was aborted. Read only " + llvm::Twine(In.gcount()) +
+              " bytes of expected " + llvm::Twine(ContentLength) + ".\n");
           break;
         }
 
@@ -264,24 +264,22 @@ void clangd::runLanguageServerLoop(std::
 
       if (auto Doc = json::parse(JSONRef)) {
         // Log the formatted message.
-        log(Context::empty(),
-            llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc));
+        log(llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc));
         // Finally, execute the action for this JSON message.
         if (!Dispatcher.call(*Doc, Out))
-          log(Context::empty(), "JSON dispatch failed!\n");
+          log("JSON dispatch failed!\n");
       } else {
         // Parse error. Log the raw message.
-        log(Context::empty(), "<-- " + JSONRef + "\n");
-        log(Context::empty(), llvm::Twine("JSON parse error: ") +
-                                  llvm::toString(Doc.takeError()) + "\n");
+        log("<-- " + JSONRef + "\n");
+        log(llvm::Twine("JSON parse error: ") +
+            llvm::toString(Doc.takeError()) + "\n");
       }
 
       // If we're done, exit the loop.
       if (IsDone)
         break;
     } else {
-      log(Context::empty(),
-          "Warning: Missing Content-Length header, or message has zero "
+      log("Warning: Missing Content-Length header, or message has zero "
           "length.\n");
     }
   }

Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h Wed Jan 31 05:40:48 2018
@@ -10,7 +10,6 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_JSONRPCDISPATCHER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_JSONRPCDISPATCHER_H
 
-#include "Context.h"
 #include "JSONExpr.h"
 #include "Logger.h"
 #include "Protocol.h"
@@ -38,7 +37,7 @@ public:
   void writeMessage(const json::Expr &Result);
 
   /// Write a line to the logging stream.
-  void log(const Context &Ctx, const Twine &Message) override;
+  void log(const Twine &Message) override;
 
   /// Mirror \p Message into InputMirror stream. Does nothing if InputMirror is
   /// null.
@@ -56,23 +55,22 @@ private:
   std::mutex StreamMutex;
 };
 
-/// Sends a successful reply. \p Ctx must either be the Context accepted by
-/// JSONRPCDispatcher::Handler or be derived from it.
-void reply(const Context &Ctx, json::Expr &&Result);
-/// Sends an error response to the client, and logs it. \p Ctx must either be
-/// the Context accepted by JSONRPCDispatcher::Handler or be derived from it.
-void replyError(const Context &Ctx, ErrorCode code,
-                const llvm::StringRef &Message);
-/// Sends a request to the client. \p Ctx must either be the Context accepted by
-/// JSONRPCDispatcher::Handler or be derived from it.
-void call(const Context &Ctx, llvm::StringRef Method, json::Expr &&Params);
+/// Sends a successful reply.
+/// Current context must derive from JSONRPCDispatcher::Handler.
+void reply(json::Expr &&Result);
+/// Sends an error response to the client, and logs it.
+/// Current context must derive from JSONRPCDispatcher::Handler.
+void replyError(ErrorCode code, const llvm::StringRef &Message);
+/// Sends a request to the client.
+/// Current context must derive from JSONRPCDispatcher::Handler.
+void call(llvm::StringRef Method, json::Expr &&Params);
 
 /// Main JSONRPC entry point. This parses the JSONRPC "header" and calls the
 /// registered Handler for the method received.
 class JSONRPCDispatcher {
 public:
   // A handler responds to requests for a particular method name.
-  using Handler = std::function<void(Context, const json::Expr &)>;
+  using Handler = std::function<void(const json::Expr &)>;
 
   /// Create a new JSONRPCDispatcher. UnknownHandler is called when an unknown
   /// method is received.

Modified: clang-tools-extra/trunk/clangd/Logger.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Logger.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Logger.cpp (original)
+++ clang-tools-extra/trunk/clangd/Logger.cpp Wed Jan 31 05:40:48 2018
@@ -25,9 +25,9 @@ LoggingSession::LoggingSession(clangd::L
 
 LoggingSession::~LoggingSession() { L = nullptr; }
 
-void log(const Context &Ctx, const llvm::Twine &Message) {
+void log(const llvm::Twine &Message) {
   if (L)
-    L->log(Ctx, Message);
+    L->log(Message);
   else {
     static std::mutex Mu;
     std::lock_guard<std::mutex> Guard(Mu);

Modified: clang-tools-extra/trunk/clangd/Logger.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Logger.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Logger.h (original)
+++ clang-tools-extra/trunk/clangd/Logger.h Wed Jan 31 05:40:48 2018
@@ -10,7 +10,6 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_LOGGER_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_LOGGER_H
 
-#include "Context.h"
 #include "llvm/ADT/Twine.h"
 
 namespace clang {
@@ -19,7 +18,7 @@ namespace clangd {
 /// Main logging function.
 /// Logs messages to a global logger, which can be set up by LoggingSesssion.
 /// If no logger is registered, writes to llvm::errs().
-void log(const Context &Ctx, const llvm::Twine &Message);
+void log(const llvm::Twine &Message);
 
 /// Interface to allow custom logging in clangd.
 class Logger {
@@ -27,7 +26,7 @@ public:
   virtual ~Logger() = default;
 
   /// Implementations of this method must be thread-safe.
-  virtual void log(const Context &Ctx, const llvm::Twine &Message) = 0;
+  virtual void log(const llvm::Twine &Message) = 0;
 };
 
 /// Only one LoggingSession can be active at a time.

Modified: clang-tools-extra/trunk/clangd/Protocol.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Protocol.cpp (original)
+++ clang-tools-extra/trunk/clangd/Protocol.cpp Wed Jan 31 05:40:48 2018
@@ -28,18 +28,16 @@ bool fromJSON(const json::Expr &E, URIFo
   if (auto S = E.asString()) {
     auto U = URI::parse(*S);
     if (!U) {
-      log(Context::empty(),
-          "Failed to parse URI " + *S + ": " + llvm::toString(U.takeError()));
+      log("Failed to parse URI " + *S + ": " + llvm::toString(U.takeError()));
       return false;
     }
     if (U->scheme() != "file") {
-      log(Context::empty(),
-          "Clangd only supports 'file' URI scheme for workspace files: " + *S);
+      log("Clangd only supports 'file' URI scheme for workspace files: " + *S);
       return false;
     }
     auto Path = URI::resolve(*U);
     if (!Path) {
-      log(Context::empty(), llvm::toString(Path.takeError()));
+      log(llvm::toString(Path.takeError()));
       return false;
     }
     R.file = *Path;

Modified: clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp (original)
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp Wed Jan 31 05:40:48 2018
@@ -24,19 +24,17 @@ namespace {
 // FooParams should have a fromJSON function.
 struct HandlerRegisterer {
   template <typename Param>
-  void operator()(StringRef Method,
-                  void (ProtocolCallbacks::*Handler)(Context, Param)) {
+  void operator()(StringRef Method, void (ProtocolCallbacks::*Handler)(Param)) {
     // Capture pointers by value, as the lambda will outlive this object.
     auto *Callbacks = this->Callbacks;
-    Dispatcher.registerHandler(
-        Method, [=](Context C, const json::Expr &RawParams) {
-          typename std::remove_reference<Param>::type P;
-          if (fromJSON(RawParams, P)) {
-            (Callbacks->*Handler)(std::move(C), P);
-          } else {
-            log(C, "Failed to decode " + Method + " request.");
-          }
-        });
+    Dispatcher.registerHandler(Method, [=](const json::Expr &RawParams) {
+      typename std::remove_reference<Param>::type P;
+      if (fromJSON(RawParams, P)) {
+        (Callbacks->*Handler)(P);
+      } else {
+        log("Failed to decode " + Method + " request.");
+      }
+    });
   }
 
   JSONRPCDispatcher &Dispatcher;

Modified: clang-tools-extra/trunk/clangd/ProtocolHandlers.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.h (original)
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.h Wed Jan 31 05:40:48 2018
@@ -29,34 +29,28 @@ namespace clangd {
 // The interface implemented by ClangLSPServer to handle incoming requests.
 class ProtocolCallbacks {
 public:
-  // FIXME(ibiryukov): remove this typedef, inline its usages.
-  using Ctx = Context;
   virtual ~ProtocolCallbacks() = default;
 
-  virtual void onInitialize(Ctx C, InitializeParams &Params) = 0;
-  virtual void onShutdown(Ctx C, ShutdownParams &Params) = 0;
-  virtual void onExit(Ctx C, ExitParams &Params) = 0;
-  virtual void onDocumentDidOpen(Ctx C, DidOpenTextDocumentParams &Params) = 0;
-  virtual void onDocumentDidChange(Ctx C,
-                                   DidChangeTextDocumentParams &Params) = 0;
-  virtual void onDocumentDidClose(Ctx C,
-                                  DidCloseTextDocumentParams &Params) = 0;
-  virtual void onDocumentFormatting(Ctx C,
-                                    DocumentFormattingParams &Params) = 0;
+  virtual void onInitialize(InitializeParams &Params) = 0;
+  virtual void onShutdown(ShutdownParams &Params) = 0;
+  virtual void onExit(ExitParams &Params) = 0;
+  virtual void onDocumentDidOpen(DidOpenTextDocumentParams &Params) = 0;
+  virtual void onDocumentDidChange(DidChangeTextDocumentParams &Params) = 0;
+  virtual void onDocumentDidClose(DidCloseTextDocumentParams &Params) = 0;
+  virtual void onDocumentFormatting(DocumentFormattingParams &Params) = 0;
   virtual void
-  onDocumentOnTypeFormatting(Ctx C, DocumentOnTypeFormattingParams &Params) = 0;
+  onDocumentOnTypeFormatting(DocumentOnTypeFormattingParams &Params) = 0;
   virtual void
-  onDocumentRangeFormatting(Ctx C, DocumentRangeFormattingParams &Params) = 0;
-  virtual void onCodeAction(Ctx C, CodeActionParams &Params) = 0;
-  virtual void onCompletion(Ctx C, TextDocumentPositionParams &Params) = 0;
-  virtual void onSignatureHelp(Ctx C, TextDocumentPositionParams &Params) = 0;
-  virtual void onGoToDefinition(Ctx C, TextDocumentPositionParams &Params) = 0;
-  virtual void onSwitchSourceHeader(Ctx C, TextDocumentIdentifier &Params) = 0;
-  virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) = 0;
-  virtual void onCommand(Ctx C, ExecuteCommandParams &Params) = 0;
-  virtual void onRename(Ctx C, RenameParams &Parames) = 0;
-  virtual void onDocumentHighlight(Ctx C,
-                                   TextDocumentPositionParams &Params) = 0;
+  onDocumentRangeFormatting(DocumentRangeFormattingParams &Params) = 0;
+  virtual void onCodeAction(CodeActionParams &Params) = 0;
+  virtual void onCompletion(TextDocumentPositionParams &Params) = 0;
+  virtual void onSignatureHelp(TextDocumentPositionParams &Params) = 0;
+  virtual void onGoToDefinition(TextDocumentPositionParams &Params) = 0;
+  virtual void onSwitchSourceHeader(TextDocumentIdentifier &Params) = 0;
+  virtual void onFileEvent(DidChangeWatchedFilesParams &Params) = 0;
+  virtual void onCommand(ExecuteCommandParams &Params) = 0;
+  virtual void onRename(RenameParams &Parames) = 0;
+  virtual void onDocumentHighlight(TextDocumentPositionParams &Params) = 0;
 };
 
 void registerCallbackHandlers(JSONRPCDispatcher &Dispatcher, JSONOutput &Out,

Modified: clang-tools-extra/trunk/clangd/TUScheduler.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/TUScheduler.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/TUScheduler.cpp (original)
+++ clang-tools-extra/trunk/clangd/TUScheduler.cpp Wed Jan 31 05:40:48 2018
@@ -23,9 +23,8 @@ TUScheduler::TUScheduler(unsigned AsyncT
       Threads(AsyncThreadsCount) {}
 
 void TUScheduler::update(
-    Context Ctx, PathRef File, ParseInputs Inputs,
-    UniqueFunction<void(Context Ctx,
-                        llvm::Optional<std::vector<DiagWithFixIts>>)>
+    PathRef File, ParseInputs Inputs,
+    UniqueFunction<void(llvm::Optional<std::vector<DiagWithFixIts>>)>
         OnUpdated) {
   CachedInputs[File] = Inputs;
 
@@ -33,12 +32,12 @@ void TUScheduler::update(
   auto DeferredRebuild = Resources->deferRebuild(std::move(Inputs));
 
   Threads.addToFront(
-      [](Context Ctx, decltype(OnUpdated) OnUpdated,
+      [](decltype(OnUpdated) OnUpdated,
          decltype(DeferredRebuild) DeferredRebuild) {
-        auto Diags = DeferredRebuild(Ctx);
-        OnUpdated(std::move(Ctx), Diags);
+        auto Diags = DeferredRebuild();
+        OnUpdated(Diags);
       },
-      std::move(Ctx), std::move(OnUpdated), std::move(DeferredRebuild));
+      std::move(OnUpdated), std::move(DeferredRebuild));
 }
 
 void TUScheduler::remove(PathRef File,

Modified: clang-tools-extra/trunk/clangd/TUScheduler.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/TUScheduler.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/TUScheduler.h (original)
+++ clang-tools-extra/trunk/clangd/TUScheduler.h Wed Jan 31 05:40:48 2018
@@ -50,10 +50,9 @@ public:
   /// Schedule an update for \p File. Adds \p File to a list of tracked files if
   /// \p File was not part of it before.
   /// FIXME(ibiryukov): remove the callback from this function.
-  void update(
-      Context Ctx, PathRef File, ParseInputs Inputs,
-      UniqueFunction<void(Context, llvm::Optional<std::vector<DiagWithFixIts>>)>
-          OnUpdated);
+  void update(PathRef File, ParseInputs Inputs,
+              UniqueFunction<void(llvm::Optional<std::vector<DiagWithFixIts>>)>
+                  OnUpdated);
 
   /// Remove \p File from the list of tracked files and schedule removal of its
   /// resources. \p Action will be called when resources are freed.

Modified: clang-tools-extra/trunk/clangd/Threading.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Threading.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Threading.cpp (original)
+++ clang-tools-extra/trunk/clangd/Threading.cpp Wed Jan 31 05:40:48 2018
@@ -17,6 +17,7 @@ ThreadPool::ThreadPool(unsigned AsyncThr
       llvm::set_thread_name(llvm::formatv("scheduler/{0}", I));
       while (true) {
         UniqueFunction<void()> Request;
+        Context Ctx;
 
         // Pick request from the queue
         {
@@ -33,10 +34,11 @@ ThreadPool::ThreadPool(unsigned AsyncThr
           // ThreadPool have a way to prioritise their requests by putting
           // them to the either side of the queue (using either addToEnd or
           // addToFront).
-          Request = std::move(RequestQueue.front());
+          std::tie(Request, Ctx) = std::move(RequestQueue.front());
           RequestQueue.pop_front();
         } // unlock Mutex
 
+        WithContext WithCtx(std::move(Ctx));
         Request();
       }
     }));

Modified: clang-tools-extra/trunk/clangd/Threading.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Threading.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Threading.h (original)
+++ clang-tools-extra/trunk/clangd/Threading.h Wed Jan 31 05:40:48 2018
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
 
+#include "Context.h"
 #include "Function.h"
 #include <condition_variable>
 #include <deque>
@@ -42,8 +43,9 @@ public:
 
     {
       std::lock_guard<std::mutex> Lock(Mutex);
-      RequestQueue.push_front(
-          BindWithForward(std::forward<Func>(F), std::forward<Args>(As)...));
+      RequestQueue.emplace_front(
+          BindWithForward(std::forward<Func>(F), std::forward<Args>(As)...),
+          Context::current().clone());
     }
     RequestCV.notify_one();
   }
@@ -58,8 +60,9 @@ public:
 
     {
       std::lock_guard<std::mutex> Lock(Mutex);
-      RequestQueue.push_back(
-          BindWithForward(std::forward<Func>(F), std::forward<Args>(As)...));
+      RequestQueue.emplace_back(
+          BindWithForward(std::forward<Func>(F), std::forward<Args>(As)...),
+          Context::current().clone());
     }
     RequestCV.notify_one();
   }
@@ -74,7 +77,7 @@ private:
   /// Setting Done to true will make the worker threads terminate.
   bool Done = false;
   /// A queue of requests.
-  std::deque<UniqueFunction<void()>> RequestQueue;
+  std::deque<std::pair<UniqueFunction<void()>, Context>> RequestQueue;
   /// Condition variable to wake up worker threads.
   std::condition_variable RequestCV;
 };

Modified: clang-tools-extra/trunk/clangd/Trace.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Trace.cpp (original)
+++ clang-tools-extra/trunk/clangd/Trace.cpp Wed Jan 31 05:40:48 2018
@@ -46,16 +46,14 @@ public:
     Out.flush();
   }
 
-  Context beginSpan(const Context &Ctx, llvm::StringRef Name,
-                    json::obj *Args) override {
+  Context beginSpan(llvm::StringRef Name, json::obj *Args) override {
     jsonEvent("B", json::obj{{"name", Name}});
-    return Ctx.derive(make_scope_exit([this, Args] {
+    return Context::current().derive(make_scope_exit([this, Args] {
       jsonEvent("E", json::obj{{"args", std::move(*Args)}});
     }));
   }
 
-  void instant(const Context &Ctx, llvm::StringRef Name,
-               json::obj &&Args) override {
+  void instant(llvm::StringRef Name, json::obj &&Args) override {
     jsonEvent("i", json::obj{{"name", Name}, {"args", std::move(Args)}});
   }
 
@@ -120,20 +118,26 @@ std::unique_ptr<EventTracer> createJSONT
   return llvm::make_unique<JSONTracer>(OS, Pretty);
 }
 
-void log(const Context &Ctx, const Twine &Message) {
+void log(const Twine &Message) {
   if (!T)
     return;
-  T->instant(Ctx, "Log", json::obj{{"Message", Message.str()}});
+  T->instant("Log", json::obj{{"Message", Message.str()}});
+}
+
+// Returned context owns Args.
+static Context makeSpanContext(llvm::StringRef Name, json::obj *Args) {
+  if (!T)
+    return Context::current().clone();
+  WithContextValue WithArgs{std::unique_ptr<json::obj>(Args)};
+  return T->beginSpan(Name, Args);
 }
 
 // Span keeps a non-owning pointer to the args, which is how users access them.
 // The args are owned by the context though. They stick around until the
 // beginSpan() context is destroyed, when the tracing engine will consume them.
-Span::Span(const Context &Ctx, llvm::StringRef Name)
+Span::Span(llvm::StringRef Name)
     : Args(T ? new json::obj() : nullptr),
-      Ctx(T ? T->beginSpan(Ctx.derive(std::unique_ptr<json::obj>(Args)), Name,
-                           Args)
-            : Ctx.clone()) {}
+      RestoreCtx(makeSpanContext(Name, Args)) {}
 
 } // namespace trace
 } // namespace clangd

Modified: clang-tools-extra/trunk/clangd/Trace.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Trace.h (original)
+++ clang-tools-extra/trunk/clangd/Trace.h Wed Jan 31 05:40:48 2018
@@ -39,12 +39,10 @@ public:
   /// Usually implementations will store an object in the returned context
   /// whose destructor records the end of the event.
   /// The args are *Args, only complete when the event ends.
-  virtual Context beginSpan(const Context &Ctx, llvm::StringRef Name,
-                            json::obj *Args) = 0;
+  virtual Context beginSpan(llvm::StringRef Name, json::obj *Args) = 0;
 
   /// Called for instant events.
-  virtual void instant(const Context &Ctx, llvm::StringRef Name,
-                       json::obj &&Args) = 0;
+  virtual void instant(llvm::StringRef Name, json::obj &&Args) = 0;
 };
 
 /// Sets up a global EventTracer that consumes events produced by Span and
@@ -65,7 +63,7 @@ std::unique_ptr<EventTracer> createJSONT
                                               bool Pretty = false);
 
 /// Records a single instant event, associated with the current thread.
-void log(const Context &Ctx, const llvm::Twine &Name);
+void log(const llvm::Twine &Name);
 
 /// Records an event whose duration is the lifetime of the Span object.
 /// This lifetime is extended when the span's context is reused.
@@ -78,18 +76,19 @@ void log(const Context &Ctx, const llvm:
 /// SomeJSONExpr is evaluated and copied only if actually needed.
 class Span {
 public:
-  Span(const Context &Ctx, llvm::StringRef Name);
+  Span(llvm::StringRef Name);
 
   /// Mutable metadata, if this span is interested.
   /// Prefer to use SPAN_ATTACH rather than accessing this directly.
   json::obj *const Args;
-  /// Propagating this context will keep the span alive.
-  const Context Ctx;
+
+private:
+  WithContext RestoreCtx;
 };
 
 /// Returns mutable span metadata if this span is interested.
 /// Prefer to use SPAN_ATTACH rather than accessing this directly.
-json::obj *spanArgs(const Context &Ctx);
+json::obj *spanArgs();
 
 /// Attach a key-value pair to a Span event.
 /// This is not threadsafe when used with the same Span.

Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Wed Jan 31 05:40:48 2018
@@ -148,8 +148,7 @@ getDeclarationLocation(ParsedAST &AST, c
 
 } // namespace
 
-std::vector<Location> findDefinitions(const Context &Ctx, ParsedAST &AST,
-                                      Position Pos) {
+std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
   if (!FE)
@@ -260,8 +259,8 @@ private:
 
 } // namespace
 
-std::vector<DocumentHighlight>
-findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos) {
+std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
+                                                      Position Pos) {
   const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
   const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
   if (!FE)

Modified: clang-tools-extra/trunk/clangd/XRefs.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.h (original)
+++ clang-tools-extra/trunk/clangd/XRefs.h Wed Jan 31 05:40:48 2018
@@ -14,7 +14,6 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H
 
 #include "ClangdUnit.h"
-#include "Context.h"
 #include "Protocol.h"
 #include <vector>
 
@@ -22,12 +21,11 @@ namespace clang {
 namespace clangd {
 
 /// Get definition of symbol at a specified \p Pos.
-std::vector<Location> findDefinitions(const Context &Ctx, ParsedAST &AST,
-                                      Position Pos);
+std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos);
 
 /// Returns highlights for all usages of a symbol at \p Pos.
-std::vector<DocumentHighlight>
-findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos);
+std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
+                                                      Position Pos);
 
 } // namespace clangd
 } // namespace clang

Modified: clang-tools-extra/trunk/clangd/index/FileIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/FileIndex.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/FileIndex.cpp Wed Jan 31 05:40:48 2018
@@ -69,7 +69,7 @@ std::shared_ptr<std::vector<const Symbol
   return {std::move(Snap), Pointers};
 }
 
-void FileIndex::update(const Context &Ctx, PathRef Path, ParsedAST *AST) {
+void FileIndex::update(PathRef Path, ParsedAST *AST) {
   if (!AST) {
     FSymbols.update(Path, nullptr);
   } else {
@@ -82,9 +82,9 @@ void FileIndex::update(const Context &Ct
 }
 
 bool FileIndex::fuzzyFind(
-    const Context &Ctx, const FuzzyFindRequest &Req,
+    const FuzzyFindRequest &Req,
     llvm::function_ref<void(const Symbol &)> Callback) const {
-  return Index.fuzzyFind(Ctx, Req, Callback);
+  return Index.fuzzyFind(Req, Callback);
 }
 
 } // namespace clangd

Modified: clang-tools-extra/trunk/clangd/index/FileIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/FileIndex.h (original)
+++ clang-tools-extra/trunk/clangd/index/FileIndex.h Wed Jan 31 05:40:48 2018
@@ -17,7 +17,6 @@
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_FILEINDEX_H
 
 #include "../ClangdUnit.h"
-#include "../Context.h"
 #include "Index.h"
 #include "MemIndex.h"
 
@@ -58,10 +57,10 @@ class FileIndex : public SymbolIndex {
 public:
   /// \brief Update symbols in \p Path with symbols in \p AST. If \p AST is
   /// nullptr, this removes all symbols in the file
-  void update(const Context &Ctx, PathRef Path, ParsedAST *AST);
+  void update(PathRef Path, ParsedAST *AST);
 
   bool
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,
+  fuzzyFind(const FuzzyFindRequest &Req,
             llvm::function_ref<void(const Symbol &)> Callback) const override;
 
 private:

Modified: clang-tools-extra/trunk/clangd/index/Index.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Index.h (original)
+++ clang-tools-extra/trunk/clangd/index/Index.h Wed Jan 31 05:40:48 2018
@@ -10,7 +10,6 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H
 
-#include "../Context.h"
 #include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
@@ -244,7 +243,7 @@ public:
   /// Returns true if the result list is complete, false if it was truncated due
   /// to MaxCandidateCount
   virtual bool
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,
+  fuzzyFind(const FuzzyFindRequest &Req,
             llvm::function_ref<void(const Symbol &)> Callback) const = 0;
 
   // FIXME: add interfaces for more index use cases:

Modified: clang-tools-extra/trunk/clangd/index/MemIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/MemIndex.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/MemIndex.cpp Wed Jan 31 05:40:48 2018
@@ -29,7 +29,7 @@ void MemIndex::build(std::shared_ptr<std
 }
 
 bool MemIndex::fuzzyFind(
-    const Context &Ctx, const FuzzyFindRequest &Req,
+    const FuzzyFindRequest &Req,
     llvm::function_ref<void(const Symbol &)> Callback) const {
   assert(!StringRef(Req.Query).contains("::") &&
          "There must be no :: in query.");

Modified: clang-tools-extra/trunk/clangd/index/MemIndex.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.h?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/MemIndex.h (original)
+++ clang-tools-extra/trunk/clangd/index/MemIndex.h Wed Jan 31 05:40:48 2018
@@ -28,7 +28,7 @@ public:
   static std::unique_ptr<SymbolIndex> build(SymbolSlab Slab);
 
   bool
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,
+  fuzzyFind(const FuzzyFindRequest &Req,
             llvm::function_ref<void(const Symbol &)> Callback) const override;
 
 private:

Modified: clang-tools-extra/trunk/clangd/index/Merge.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Merge.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Merge.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Merge.cpp Wed Jan 31 05:40:48 2018
@@ -24,7 +24,7 @@ class MergedIndex : public SymbolIndex {
    //          - find the generating file from each Symbol which is Static-only
    //          - ask Dynamic if it has that file (needs new SymbolIndex method)
    //          - if so, drop the Symbol.
-   bool fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,
+   bool fuzzyFind(const FuzzyFindRequest &Req,
                   function_ref<void(const Symbol &)> Callback) const override {
      // We can't step through both sources in parallel. So:
      //  1) query all dynamic symbols, slurping results into a slab
@@ -34,13 +34,12 @@ class MergedIndex : public SymbolIndex {
      //  3) now yield all the dynamic symbols we haven't processed.
      bool More = false; // We'll be incomplete if either source was.
      SymbolSlab::Builder DynB;
-     More |=
-         Dynamic->fuzzyFind(Ctx, Req, [&](const Symbol &S) { DynB.insert(S); });
+     More |= Dynamic->fuzzyFind(Req, [&](const Symbol &S) { DynB.insert(S); });
      SymbolSlab Dyn = std::move(DynB).build();
 
      DenseSet<SymbolID> SeenDynamicSymbols;
      Symbol::Details Scratch;
-     More |= Static->fuzzyFind(Ctx, Req, [&](const Symbol &S) {
+     More |= Static->fuzzyFind(Req, [&](const Symbol &S) {
        auto DynS = Dyn.find(S.ID);
        if (DynS == Dyn.end())
          return Callback(S);

Modified: clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp Wed Jan 31 05:40:48 2018
@@ -9,7 +9,6 @@
 
 #include "ClangdLSPServer.h"
 #include "ClangdServer.h"
-#include "Context.h"
 #include "TestFS.h"
 #include "clang/Config/config.h"
 #include "llvm/ADT/SmallVector.h"
@@ -58,7 +57,7 @@ static bool diagsContainErrors(ArrayRef<
 class ErrorCheckingDiagConsumer : public DiagnosticsConsumer {
 public:
   void
-  onDiagnosticsReady(const Context &Ctx, PathRef File,
+  onDiagnosticsReady(PathRef File,
                      Tagged<std::vector<DiagWithFixIts>> Diagnostics) override {
     bool HadError = diagsContainErrors(Diagnostics.Value);
 
@@ -143,8 +142,7 @@ protected:
 
     // Have to sync reparses because requests are processed on the calling
     // thread.
-    auto AddDocFuture =
-        Server.addDocument(Context::empty(), SourceFilename, SourceContents);
+    auto AddDocFuture = Server.addDocument(SourceFilename, SourceContents);
 
     auto Result = dumpASTWithoutMemoryLocs(Server, SourceFilename);
 
@@ -211,21 +209,21 @@ int b = a;
   FS.ExpectedFile = FooCpp;
 
   // To sync reparses before checking for errors.
-  std::future<Context> ParseFuture;
+  std::future<void> ParseFuture;
 
-  ParseFuture = Server.addDocument(Context::empty(), FooCpp, SourceContents);
+  ParseFuture = Server.addDocument(FooCpp, SourceContents);
   auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
-  ParseFuture = Server.addDocument(Context::empty(), FooCpp, "");
+  ParseFuture = Server.addDocument(FooCpp, "");
   auto DumpParseEmpty = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
-  ParseFuture = Server.addDocument(Context::empty(), FooCpp, SourceContents);
+  ParseFuture = Server.addDocument(FooCpp, SourceContents);
   auto DumpParse2 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
@@ -256,23 +254,23 @@ int b = a;
   FS.ExpectedFile = FooCpp;
 
   // To sync reparses before checking for errors.
-  std::future<Context> ParseFuture;
+  std::future<void> ParseFuture;
 
-  ParseFuture = Server.addDocument(Context::empty(), FooCpp, SourceContents);
+  ParseFuture = Server.addDocument(FooCpp, SourceContents);
   auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
   FS.Files[FooH] = "";
-  ParseFuture = Server.forceReparse(Context::empty(), FooCpp);
+  ParseFuture = Server.forceReparse(FooCpp);
   auto DumpParseDifferent = dumpASTWithoutMemoryLocs(Server, FooCpp);
   ASSERT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
 
   FS.Files[FooH] = "int a;";
-  ParseFuture = Server.forceReparse(Context::empty(), FooCpp);
+  ParseFuture = Server.forceReparse(FooCpp);
   auto DumpParse2 = dumpASTWithoutMemoryLocs(Server, FooCpp);
   EXPECT_EQ(ParseFuture.wait_for(DefaultFutureTimeout),
             std::future_status::ready);
@@ -302,22 +300,16 @@ TEST_F(ClangdVFSTest, CheckVersions) {
   // No need to sync reparses, because requests are processed on the calling
   // thread.
   FS.Tag = "123";
-  Server.addDocument(Context::empty(), FooCpp, SourceContents);
-  EXPECT_EQ(
-      Server.codeComplete(Context::empty(), FooCpp, Position{0, 0}, CCOpts)
-          .get()
-          .second.Tag,
-      FS.Tag);
+  Server.addDocument(FooCpp, SourceContents);
+  EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}, CCOpts).get().Tag,
+            FS.Tag);
   EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag);
 
   FS.Tag = "321";
-  Server.addDocument(Context::empty(), FooCpp, SourceContents);
+  Server.addDocument(FooCpp, SourceContents);
   EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag);
-  EXPECT_EQ(
-      Server.codeComplete(Context::empty(), FooCpp, Position{0, 0}, CCOpts)
-          .get()
-          .second.Tag,
-      FS.Tag);
+  EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}, CCOpts).get().Tag,
+            FS.Tag);
 }
 
 // Only enable this test on Unix
@@ -365,14 +357,14 @@ mock_string x;
 
   // No need to sync reparses, because requests are processed on the calling
   // thread.
-  Server.addDocument(Context::empty(), FooCpp, SourceContents);
+  Server.addDocument(FooCpp, SourceContents);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 
   const auto SourceContentsWithError = R"cpp(
 #include <string>
 std::string x;
 )cpp";
-  Server.addDocument(Context::empty(), FooCpp, SourceContentsWithError);
+  Server.addDocument(FooCpp, SourceContentsWithError);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
 }
 #endif // LLVM_ON_UNIX
@@ -402,26 +394,26 @@ struct bar { T x; };
 
   // First parse files in C mode and check they produce errors.
   CDB.ExtraClangFlags = {"-xc"};
-  Server.addDocument(Context::empty(), FooCpp, SourceContents1);
+  Server.addDocument(FooCpp, SourceContents1);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
-  Server.addDocument(Context::empty(), FooCpp, SourceContents2);
+  Server.addDocument(FooCpp, SourceContents2);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
 
   // Now switch to C++ mode.
   CDB.ExtraClangFlags = {"-xc++"};
   // Currently, addDocument never checks if CompileCommand has changed, so we
   // expect to see the errors.
-  Server.addDocument(Context::empty(), FooCpp, SourceContents1);
+  Server.addDocument(FooCpp, SourceContents1);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
-  Server.addDocument(Context::empty(), FooCpp, SourceContents2);
+  Server.addDocument(FooCpp, SourceContents2);
   EXPECT_TRUE(DiagConsumer.hadErrorInLastDiags());
   // But forceReparse should reparse the file with proper flags.
-  Server.forceReparse(Context::empty(), FooCpp);
+  Server.forceReparse(FooCpp);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
   // Subsequent addDocument calls should finish without errors too.
-  Server.addDocument(Context::empty(), FooCpp, SourceContents1);
+  Server.addDocument(FooCpp, SourceContents1);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
-  Server.addDocument(Context::empty(), FooCpp, SourceContents2);
+  Server.addDocument(FooCpp, SourceContents2);
   EXPECT_FALSE(DiagConsumer.hadErrorInLastDiags());
 }
 
@@ -448,16 +440,16 @@ struct Something {
 
   EXPECT_THAT(Server.getUsedBytesPerFile(), IsEmpty());
 
-  Server.addDocument(Context::empty(), FooCpp, SourceContents);
-  Server.addDocument(Context::empty(), BarCpp, SourceContents);
+  Server.addDocument(FooCpp, SourceContents);
+  Server.addDocument(BarCpp, SourceContents);
 
   EXPECT_THAT(Server.getUsedBytesPerFile(),
               UnorderedElementsAre(Pair(FooCpp, Gt(0u)), Pair(BarCpp, Gt(0u))));
 
-  Server.removeDocument(Context::empty(), FooCpp);
+  Server.removeDocument(FooCpp);
   EXPECT_THAT(Server.getUsedBytesPerFile(), ElementsAre(Pair(BarCpp, Gt(0u))));
 
-  Server.removeDocument(Context::empty(), BarCpp);
+  Server.removeDocument(BarCpp);
   EXPECT_THAT(Server.getUsedBytesPerFile(), IsEmpty());
 }
 
@@ -515,7 +507,7 @@ int d;
     TestDiagConsumer() : Stats(FilesCount, FileStat()) {}
 
     void onDiagnosticsReady(
-        const Context &Ctx, PathRef File,
+        PathRef File,
         Tagged<std::vector<DiagWithFixIts>> Diagnostics) override {
       StringRef FileIndexStr = llvm::sys::path::stem(File);
       ASSERT_TRUE(FileIndexStr.consume_front("Foo"));
@@ -547,7 +539,7 @@ int d;
     unsigned RequestsWithErrors = 0;
     bool LastContentsHadErrors = false;
     bool FileIsRemoved = true;
-    std::future<Context> LastRequestFuture;
+    std::future<void> LastRequestFuture;
   };
 
   std::vector<RequestStats> ReqStats;
@@ -574,7 +566,7 @@ int d;
 
     // Some helpers.
     auto UpdateStatsOnAddDocument = [&](unsigned FileIndex, bool HadErrors,
-                                        std::future<Context> Future) {
+                                        std::future<void> Future) {
       auto &Stats = ReqStats[FileIndex];
 
       if (HadErrors)
@@ -587,7 +579,7 @@ int d;
     };
 
     auto UpdateStatsOnRemoveDocument = [&](unsigned FileIndex,
-                                           std::future<Context> Future) {
+                                           std::future<void> Future) {
       auto &Stats = ReqStats[FileIndex];
 
       Stats.FileIsRemoved = true;
@@ -595,7 +587,7 @@ int d;
     };
 
     auto UpdateStatsOnForceReparse = [&](unsigned FileIndex,
-                                         std::future<Context> Future) {
+                                         std::future<void> Future) {
       auto &Stats = ReqStats[FileIndex];
 
       Stats.LastRequestFuture = std::move(Future);
@@ -607,10 +599,9 @@ int d;
 
     auto AddDocument = [&](unsigned FileIndex) {
       bool ShouldHaveErrors = ShouldHaveErrorsDist(RandGen);
-      auto Future =
-          Server.addDocument(Context::empty(), FilePaths[FileIndex],
-                             ShouldHaveErrors ? SourceContentsWithErrors
-                                              : SourceContentsWithoutErrors);
+      auto Future = Server.addDocument(
+          FilePaths[FileIndex], ShouldHaveErrors ? SourceContentsWithErrors
+                                                 : SourceContentsWithoutErrors);
       UpdateStatsOnAddDocument(FileIndex, ShouldHaveErrors, std::move(Future));
     };
 
@@ -626,7 +617,7 @@ int d;
       if (ReqStats[FileIndex].FileIsRemoved)
         AddDocument(FileIndex);
 
-      auto Future = Server.forceReparse(Context::empty(), FilePaths[FileIndex]);
+      auto Future = Server.forceReparse(FilePaths[FileIndex]);
       UpdateStatsOnForceReparse(FileIndex, std::move(Future));
     };
 
@@ -636,8 +627,7 @@ int d;
       if (ReqStats[FileIndex].FileIsRemoved)
         AddDocument(FileIndex);
 
-      auto Future =
-          Server.removeDocument(Context::empty(), FilePaths[FileIndex]);
+      auto Future = Server.removeDocument(FilePaths[FileIndex]);
       UpdateStatsOnRemoveDocument(FileIndex, std::move(Future));
     };
 
@@ -655,7 +645,7 @@ int d;
       // cancelled by any subsequent AddDocument/RemoveDocument request to the
       // same file.
       Server
-          .codeComplete(Context::empty(), FilePaths[FileIndex], Pos,
+          .codeComplete(FilePaths[FileIndex], Pos,
                         clangd::CodeCompleteOptions())
           .wait();
     };
@@ -667,8 +657,7 @@ int d;
         AddDocument(FileIndex);
 
       Position Pos{LineDist(RandGen), ColumnDist(RandGen)};
-      ASSERT_TRUE(!!Server.findDefinitions(Context::empty(),
-                                           FilePaths[FileIndex], Pos));
+      ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos));
     };
 
     std::vector<std::function<void()>> AsyncRequests = {
@@ -803,7 +792,7 @@ TEST_F(ClangdThreadingTest, NoConcurrent
         : StartSecondReparse(std::move(StartSecondReparse)) {}
 
     void onDiagnosticsReady(
-        const Context &Ctx, PathRef File,
+        PathRef File,
         Tagged<std::vector<DiagWithFixIts>> Diagnostics) override {
 
       std::unique_lock<std::mutex> Lock(Mutex, std::try_to_lock_t());
@@ -851,11 +840,10 @@ int d;
   MockCompilationDatabase CDB;
   ClangdServer Server(CDB, DiagConsumer, FS, 4,
                       /*StorePreamblesInMemory=*/true);
-  Server.addDocument(Context::empty(), FooCpp, SourceContentsWithErrors);
+  Server.addDocument(FooCpp, SourceContentsWithErrors);
   StartSecondReparse.wait();
 
-  auto Future =
-      Server.addDocument(Context::empty(), FooCpp, SourceContentsWithoutErrors);
+  auto Future = Server.addDocument(FooCpp, SourceContentsWithoutErrors);
   Future.wait();
 }
 

Modified: clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp Wed Jan 31 05:40:48 2018
@@ -43,9 +43,9 @@ ParsedAST build(StringRef Code, std::vec
   Cmd.insert(Cmd.begin() + 1, Flags.begin(), Flags.end());
   auto CI = createInvocationFromCommandLine(Cmd);
   auto Buf = MemoryBuffer::getMemBuffer(Code);
-  auto AST = ParsedAST::Build(
-      Context::empty(), std::move(CI), nullptr, std::move(Buf),
-      std::make_shared<PCHContainerOperations>(), vfs::getRealFileSystem());
+  auto AST = ParsedAST::Build(std::move(CI), nullptr, std::move(Buf),
+                              std::make_shared<PCHContainerOperations>(),
+                              vfs::getRealFileSystem());
   assert(AST.hasValue());
   return std::move(*AST);
 }

Modified: clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp Wed Jan 31 05:40:48 2018
@@ -11,7 +11,6 @@
 #include "ClangdServer.h"
 #include "CodeComplete.h"
 #include "Compiler.h"
-#include "Context.h"
 #include "Matchers.h"
 #include "Protocol.h"
 #include "SourceCode.h"
@@ -61,10 +60,8 @@ using ::testing::UnorderedElementsAre;
 using ::testing::Field;
 
 class IgnoreDiagnostics : public DiagnosticsConsumer {
-  void
-  onDiagnosticsReady(const Context &Ctx, PathRef File,
-                     Tagged<std::vector<DiagWithFixIts>> Diagnostics) override {
-  }
+  void onDiagnosticsReady(
+      PathRef File, Tagged<std::vector<DiagWithFixIts>> Diagnostics) override {}
 };
 
 // GMock helpers for matching completion items.
@@ -123,11 +120,9 @@ CompletionList completions(StringRef Tex
                       /*StorePreamblesInMemory=*/true);
   auto File = getVirtualTestFilePath("foo.cpp");
   Annotations Test(Text);
-  Server.addDocument(Context::empty(), File, Test.code()).wait();
+  Server.addDocument(File, Test.code()).wait();
   auto CompletionList =
-      Server.codeComplete(Context::empty(), File, Test.point(), Opts)
-          .get()
-          .second.Value;
+      Server.codeComplete(File, Test.point(), Opts).get().Value;
   // Sanity-check that filterText is valid.
   EXPECT_THAT(CompletionList.items, Each(NameContainsFilter()));
   return CompletionList;
@@ -349,15 +344,15 @@ TEST(CompletionTest, CheckContentsOverri
   ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),
                       /*StorePreamblesInMemory=*/true);
   auto File = getVirtualTestFilePath("foo.cpp");
-  Server.addDocument(Context::empty(), File, "ignored text!");
+  Server.addDocument(File, "ignored text!");
 
   Annotations Example("int cbc; int b = ^;");
-  auto Results = Server
-                     .codeComplete(Context::empty(), File, Example.point(),
-                                   clangd::CodeCompleteOptions(),
-                                   StringRef(Example.code()))
-                     .get()
-                     .second.Value;
+  auto Results =
+      Server
+          .codeComplete(File, Example.point(), clangd::CodeCompleteOptions(),
+                        StringRef(Example.code()))
+          .get()
+          .Value;
   EXPECT_THAT(Results.items, Contains(Named("cbc")));
 }
 
@@ -558,28 +553,20 @@ TEST(CompletionTest, IndexSuppressesPrea
       void f() { ns::^; }
       void f() { ns::preamble().$2^; }
   )cpp");
-  Server.addDocument(Context::empty(), File, Test.code()).wait();
+  Server.addDocument(File, Test.code()).wait();
   clangd::CodeCompleteOptions Opts = {};
 
-  auto WithoutIndex =
-      Server.codeComplete(Context::empty(), File, Test.point(), Opts)
-          .get()
-          .second.Value;
+  auto WithoutIndex = Server.codeComplete(File, Test.point(), Opts).get().Value;
   EXPECT_THAT(WithoutIndex.items,
               UnorderedElementsAre(Named("local"), Named("preamble")));
 
   auto I = memIndex({var("ns::index")});
   Opts.Index = I.get();
-  auto WithIndex =
-      Server.codeComplete(Context::empty(), File, Test.point(), Opts)
-          .get()
-          .second.Value;
+  auto WithIndex = Server.codeComplete(File, Test.point(), Opts).get().Value;
   EXPECT_THAT(WithIndex.items,
               UnorderedElementsAre(Named("local"), Named("index")));
   auto ClassFromPreamble =
-      Server.codeComplete(Context::empty(), File, Test.point("2"), Opts)
-          .get()
-          .second.Value;
+      Server.codeComplete(File, Test.point("2"), Opts).get().Value;
   EXPECT_THAT(ClassFromPreamble.items, Contains(Named("member")));
 }
 
@@ -592,7 +579,7 @@ TEST(CompletionTest, DynamicIndexMultiFi
                       /*BuildDynamicSymbolIndex=*/true);
 
   Server
-      .addDocument(Context::empty(), getVirtualTestFilePath("foo.cpp"), R"cpp(
+      .addDocument(getVirtualTestFilePath("foo.cpp"), R"cpp(
       namespace ns { class XYZ {}; void foo(int x) {} }
   )cpp")
       .wait();
@@ -606,11 +593,9 @@ TEST(CompletionTest, DynamicIndexMultiFi
       }
       void f() { ns::^ }
   )cpp");
-  Server.addDocument(Context::empty(), File, Test.code()).wait();
+  Server.addDocument(File, Test.code()).wait();
 
-  auto Results = Server.codeComplete(Context::empty(), File, Test.point(), {})
-                     .get()
-                     .second.Value;
+  auto Results = Server.codeComplete(File, Test.point(), {}).get().Value;
   // "XYZ" and "foo" are not included in the file being completed but are still
   // visible through the index.
   EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));
@@ -637,8 +622,8 @@ SignatureHelp signatures(StringRef Text)
                       /*StorePreamblesInMemory=*/true);
   auto File = getVirtualTestFilePath("foo.cpp");
   Annotations Test(Text);
-  Server.addDocument(Context::empty(), File, Test.code());
-  auto R = Server.signatureHelp(Context::empty(), File, Test.point());
+  Server.addDocument(File, Test.code());
+  auto R = Server.signatureHelp(File, Test.point());
   assert(R);
   return R.get().Value;
 }
@@ -707,7 +692,7 @@ TEST(SignatureHelpTest, ActiveArg) {
 class IndexRequestCollector : public SymbolIndex {
 public:
   bool
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,
+  fuzzyFind(const FuzzyFindRequest &Req,
             llvm::function_ref<void(const Symbol &)> Callback) const override {
     Requests.push_back(Req);
     return false;

Modified: clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp Wed Jan 31 05:40:48 2018
@@ -76,8 +76,7 @@ TEST(FileSymbolsTest, SnapshotAliveAfter
 std::vector<std::string> match(const SymbolIndex &I,
                                const FuzzyFindRequest &Req) {
   std::vector<std::string> Matches;
-  auto Ctx = Context::empty();
-  I.fuzzyFind(Ctx, Req, [&](const Symbol &Sym) {
+  I.fuzzyFind(Req, [&](const Symbol &Sym) {
     Matches.push_back((Sym.Scope + Sym.Name).str());
   });
   return Matches;
@@ -85,7 +84,6 @@ std::vector<std::string> match(const Sym
 
 /// Create an ParsedAST for \p Code. Returns None if \p Code is empty.
 llvm::Optional<ParsedAST> build(std::string Path, llvm::StringRef Code) {
-  Context Ctx = Context::empty();
   if (Code.empty())
     return llvm::None;
   const char *Args[] = {"clang", "-xc++", Path.c_str()};
@@ -93,7 +91,7 @@ llvm::Optional<ParsedAST> build(std::str
   auto CI = createInvocationFromCommandLine(Args);
 
   auto Buf = llvm::MemoryBuffer::getMemBuffer(Code);
-  auto AST = ParsedAST::Build(Ctx, std::move(CI), nullptr, std::move(Buf),
+  auto AST = ParsedAST::Build(std::move(CI), nullptr, std::move(Buf),
                               std::make_shared<PCHContainerOperations>(),
                               vfs::getRealFileSystem());
   assert(AST.hasValue());
@@ -102,9 +100,8 @@ llvm::Optional<ParsedAST> build(std::str
 
 TEST(FileIndexTest, IndexAST) {
   FileIndex M;
-  auto Ctx = Context::empty();
   M.update(
-      Ctx, "f1",
+      "f1",
       build("f1", "namespace ns { void f() {} class X {}; }").getPointer());
 
   FuzzyFindRequest Req;
@@ -115,9 +112,8 @@ TEST(FileIndexTest, IndexAST) {
 
 TEST(FileIndexTest, NoLocal) {
   FileIndex M;
-  auto Ctx = Context::empty();
   M.update(
-      Ctx, "f1",
+      "f1",
       build("f1", "namespace ns { void f() { int local = 0; } class X {}; }")
           .getPointer());
 
@@ -128,12 +124,11 @@ TEST(FileIndexTest, NoLocal) {
 
 TEST(FileIndexTest, IndexMultiASTAndDeduplicate) {
   FileIndex M;
-  auto Ctx = Context::empty();
   M.update(
-      Ctx, "f1",
+      "f1",
       build("f1", "namespace ns { void f() {} class X {}; }").getPointer());
   M.update(
-      Ctx, "f2",
+      "f2",
       build("f2", "namespace ns { void ff() {} class X {}; }").getPointer());
 
   FuzzyFindRequest Req;
@@ -144,9 +139,8 @@ TEST(FileIndexTest, IndexMultiASTAndDedu
 
 TEST(FileIndexTest, RemoveAST) {
   FileIndex M;
-  auto Ctx = Context::empty();
   M.update(
-      Ctx, "f1",
+      "f1",
       build("f1", "namespace ns { void f() {} class X {}; }").getPointer());
 
   FuzzyFindRequest Req;
@@ -154,21 +148,19 @@ TEST(FileIndexTest, RemoveAST) {
   Req.Scopes = {"ns::"};
   EXPECT_THAT(match(M, Req), UnorderedElementsAre("ns::f", "ns::X"));
 
-  M.update(Ctx, "f1", nullptr);
+  M.update("f1", nullptr);
   EXPECT_THAT(match(M, Req), UnorderedElementsAre());
 }
 
 TEST(FileIndexTest, RemoveNonExisting) {
   FileIndex M;
-  auto Ctx = Context::empty();
-  M.update(Ctx, "no", nullptr);
+  M.update("no", nullptr);
   EXPECT_THAT(match(M, FuzzyFindRequest()), UnorderedElementsAre());
 }
 
 TEST(FileIndexTest, IgnoreClassMembers) {
   FileIndex M;
-  auto Ctx = Context::empty();
-  M.update(Ctx, "f1",
+  M.update("f1",
            build("f1", "class X { static int m1; int m2; static void f(); };")
                .getPointer());
 

Modified: clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp Wed Jan 31 05:40:48 2018
@@ -92,8 +92,7 @@ generateNumSymbols(int Begin, int End,
 std::vector<std::string> match(const SymbolIndex &I,
                                const FuzzyFindRequest &Req) {
   std::vector<std::string> Matches;
-  auto Ctx = Context::empty();
-  I.fuzzyFind(Ctx, Req, [&](const Symbol &Sym) {
+  I.fuzzyFind(Req, [&](const Symbol &Sym) {
     Matches.push_back(
         (Sym.Scope + (Sym.Scope.empty() ? "" : "::") + Sym.Name).str());
   });

Modified: clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp Wed Jan 31 05:40:48 2018
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Context.h"
 #include "TUScheduler.h"
 #include "TestFS.h"
 #include "gmock/gmock.h"
@@ -20,7 +21,7 @@ namespace clangd {
 using ::testing::Pair;
 using ::testing::Pointee;
 
-void ignoreUpdate(Context, llvm::Optional<std::vector<DiagWithFixIts>>) {}
+void ignoreUpdate(llvm::Optional<std::vector<DiagWithFixIts>>) {}
 void ignoreError(llvm::Error Err) {
   handleAllErrors(std::move(Err), [](const llvm::ErrorInfoBase &) {});
 }
@@ -52,7 +53,7 @@ TEST_F(TUSchedulerTests, MissingFiles) {
   auto Missing = getVirtualTestFilePath("missing.cpp");
   changeFile(Missing, "");
 
-  S.update(Context::empty(), Added, getInputs(Added, ""), ignoreUpdate);
+  S.update(Added, getInputs(Added, ""), ignoreUpdate);
 
   // Assert each operation for missing file is an error (even if it's available
   // in VFS).
@@ -122,46 +123,61 @@ TEST_F(TUSchedulerTests, ManyUpdates) {
     llvm::StringRef AllContents[] = {Contents1, Contents2, Contents3};
     const int AllContentsSize = 3;
 
+    // Scheduler may run tasks asynchronously, but should propagate the context.
+    // We stash a nonce in the context, and verify it in the task.
+    static Key<int> NonceKey;
+    int Nonce = 0;
+
     for (int FileI = 0; FileI < FilesCount; ++FileI) {
       for (int UpdateI = 0; UpdateI < UpdatesPerFile; ++UpdateI) {
         auto Contents = AllContents[(FileI + UpdateI) % AllContentsSize];
 
         auto File = Files[FileI];
         auto Inputs = getInputs(File, Contents.str());
-        static Key<std::pair<int, int>> FileAndUpdateKey;
-        auto Ctx = Context::empty().derive(FileAndUpdateKey,
-                                           std::make_pair(FileI, UpdateI));
-        S.update(std::move(Ctx), File, Inputs,
-                 [FileI, UpdateI, &Mut, &TotalUpdates](
-                     Context Ctx,
-                     llvm::Optional<std::vector<DiagWithFixIts>> Diags) {
-                   EXPECT_THAT(Ctx.get(FileAndUpdateKey),
-                               Pointee(Pair(FileI, UpdateI)));
-
-                   std::lock_guard<std::mutex> Lock(Mut);
-                   ++TotalUpdates;
-                 });
-
-        S.runWithAST(File, [Inputs, &Mut,
-                            &TotalASTReads](llvm::Expected<InputsAndAST> AST) {
-          ASSERT_TRUE((bool)AST);
-          EXPECT_EQ(AST->Inputs.FS, Inputs.FS);
-          EXPECT_EQ(AST->Inputs.Contents, Inputs.Contents);
-
-          std::lock_guard<std::mutex> Lock(Mut);
-          ++TotalASTReads;
-        });
-
-        S.runWithPreamble(
-            File, [Inputs, &Mut, &TotalPreambleReads](
-                      llvm::Expected<InputsAndPreamble> Preamble) {
-              ASSERT_TRUE((bool)Preamble);
-              EXPECT_EQ(Preamble->Inputs.FS, Inputs.FS);
-              EXPECT_EQ(Preamble->Inputs.Contents, Inputs.Contents);
-
-              std::lock_guard<std::mutex> Lock(Mut);
-              ++TotalPreambleReads;
-            });
+
+        {
+          WithContextValue WithNonce(NonceKey, ++Nonce);
+          S.update(File, Inputs,
+                   [Nonce, &Mut, &TotalUpdates](
+                       llvm::Optional<std::vector<DiagWithFixIts>> Diags) {
+                     EXPECT_THAT(Context::current().get(NonceKey),
+                                 Pointee(Nonce));
+
+                     std::lock_guard<std::mutex> Lock(Mut);
+                     ++TotalUpdates;
+                   });
+        }
+
+        {
+          WithContextValue WithNonce(NonceKey, ++Nonce);
+          S.runWithAST(File, [Inputs, Nonce, &Mut, &TotalASTReads](
+                                 llvm::Expected<InputsAndAST> AST) {
+            EXPECT_THAT(Context::current().get(NonceKey), Pointee(Nonce));
+
+            ASSERT_TRUE((bool)AST);
+            EXPECT_EQ(AST->Inputs.FS, Inputs.FS);
+            EXPECT_EQ(AST->Inputs.Contents, Inputs.Contents);
+
+            std::lock_guard<std::mutex> Lock(Mut);
+            ++TotalASTReads;
+          });
+        }
+
+        {
+          WithContextValue WithNonce(NonceKey, ++Nonce);
+          S.runWithPreamble(
+              File, [Inputs, Nonce, &Mut, &TotalPreambleReads](
+                        llvm::Expected<InputsAndPreamble> Preamble) {
+                EXPECT_THAT(Context::current().get(NonceKey), Pointee(Nonce));
+
+                ASSERT_TRUE((bool)Preamble);
+                EXPECT_EQ(Preamble->Inputs.FS, Inputs.FS);
+                EXPECT_EQ(Preamble->Inputs.Contents, Inputs.Contents);
+
+                std::lock_guard<std::mutex> Lock(Mut);
+                ++TotalPreambleReads;
+              });
+        }
       }
     }
   } // TUScheduler destructor waits for all operations to finish.

Modified: clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp Wed Jan 31 05:40:48 2018
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Context.h"
 #include "Trace.h"
 
 #include "llvm/ADT/DenseMap.h"
@@ -78,8 +77,8 @@ TEST(TraceTest, SmokeTest) {
     auto JSONTracer = trace::createJSONTracer(OS);
     trace::Session Session(*JSONTracer);
     {
-      trace::Span Tracer(Context::empty(), "A");
-      trace::log(Tracer.Ctx, "B");
+      trace::Span Tracer("A");
+      trace::log("B");
     }
   }
 

Modified: clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp?rev=323872&r1=323871&r2=323872&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp Wed Jan 31 05:40:48 2018
@@ -43,9 +43,9 @@ ParsedAST build(StringRef Code) {
   auto CI =
       createInvocationFromCommandLine({"clang", "-xc++", TestFile.c_str()});
   auto Buf = MemoryBuffer::getMemBuffer(Code);
-  auto AST = ParsedAST::Build(
-      Context::empty(), std::move(CI), nullptr, std::move(Buf),
-      std::make_shared<PCHContainerOperations>(), vfs::getRealFileSystem());
+  auto AST = ParsedAST::Build(std::move(CI), nullptr, std::move(Buf),
+                              std::make_shared<PCHContainerOperations>(),
+                              vfs::getRealFileSystem());
   assert(AST.hasValue());
   return std::move(*AST);
 }
@@ -101,8 +101,7 @@ TEST(HighlightsTest, All) {
   for (const char *Test : Tests) {
     Annotations T(Test);
     auto AST = build(T.code());
-    EXPECT_THAT(findDocumentHighlights(Context::empty(), AST, T.point()),
-                HighlightsFrom(T))
+    EXPECT_THAT(findDocumentHighlights(AST, T.point()), HighlightsFrom(T))
         << Test;
   }
 }
@@ -222,7 +221,7 @@ TEST(GoToDefinition, All) {
   for (const char *Test : Tests) {
     Annotations T(Test);
     auto AST = build(T.code());
-    EXPECT_THAT(findDefinitions(Context::empty(), AST, T.point()),
+    EXPECT_THAT(findDefinitions(AST, T.point()),
                 ElementsAre(RangeIs(T.range())))
         << Test;
   }




More information about the cfe-commits mailing list