<div dir="ltr">This uses thread_local and broke at least bots whose runtimes don't support it.<div><br></div><div><a href="https://reviews.llvm.org/D42742">https://reviews.llvm.org/D42742</a> should fix this by using pthread where possible, which should cover the affected platforms.<br></div><div><br></div><div>(Would like to avoid a revert because this patch touches/conflicts with everything in clangd, and we also have out-of-tree dependencies...)</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 31, 2018 at 2:40 PM, Sam McCall via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: sammccall<br>
Date: Wed Jan 31 05:40:48 2018<br>
New Revision: 323872<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=323872&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=323872&view=rev</a><br>
Log:<br>
[clangd] Pass Context implicitly using TLS.<br>
<br>
Summary:<br>
Instead of passing Context explicitly around, we now have a thread-local<br>
Context object `Context::current()` which is an implicit argument to<br>
every function.<br>
Most manipulation of this should use the WithContextValue helper, which<br>
augments the current Context to add a single KV pair, and restores the<br>
old context on destruction.<br>
<br>
Advantages are:<br>
- less boilerplate in functions that just propagate contexts<br>
- reading most code doesn't require understanding context at all, and<br>
  using context as values in fewer places still<br>
- fewer options to pass the "wrong" context when it changes within a<br>
  scope (e.g. when using Span)<br>
- contexts pass through interfaces we can't modify, such as VFS<br>
- propagating contexts across threads was slightly tricky (e.g.<br>
  copy vs move, no move-init in lambdas), and is now encapsulated in<br>
  the threadpool<br>
<br>
Disadvantages are all the usual TLS stuff - hidden magic, and<br>
potential for higher memory usage on threads that don't use the<br>
context. (In practice, it's just one pointer)<br>
<br>
Reviewers: ilya-biryukov<br>
<br>
Subscribers: klimek, jkorous-apple, ioeric, cfe-commits<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D42517" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D42517</a><br>
<br>
Modified:<br>
    clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.h<br>
    clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/ClangdServer.h<br>
    clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h<br>
    clang-tools-extra/trunk/<wbr>clangd/CodeComplete.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/CodeComplete.h<br>
    clang-tools-extra/trunk/<wbr>clangd/Context.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/Context.h<br>
    clang-tools-extra/trunk/<wbr>clangd/<wbr>GlobalCompilationDatabase.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.h<br>
    clang-tools-extra/trunk/<wbr>clangd/Logger.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/Logger.h<br>
    clang-tools-extra/trunk/<wbr>clangd/Protocol.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.h<br>
    clang-tools-extra/trunk/<wbr>clangd/TUScheduler.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/TUScheduler.h<br>
    clang-tools-extra/trunk/<wbr>clangd/Threading.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/Threading.h<br>
    clang-tools-extra/trunk/<wbr>clangd/Trace.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/Trace.h<br>
    clang-tools-extra/trunk/<wbr>clangd/XRefs.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/XRefs.h<br>
    clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.h<br>
    clang-tools-extra/trunk/<wbr>clangd/index/Index.h<br>
    clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.cpp<br>
    clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.h<br>
    clang-tools-extra/trunk/<wbr>clangd/index/Merge.cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/ClangdTests.<wbr>cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>ClangdUnitTests.cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>CodeCompleteTests.cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>FileIndexTests.cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/IndexTests.<wbr>cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>TUSchedulerTests.cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/TraceTests.<wbr>cpp<br>
    clang-tools-extra/trunk/<wbr>unittests/clangd/XRefsTests.<wbr>cpp<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ClangdLSPServer.<wbr>cpp?rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.cpp Wed Jan 31 05:40:48 2018<br>
@@ -46,8 +46,8 @@ std::vector<TextEdit> replacementsToEdit<br>
<br>
 } // namespace<br>
<br>
-void ClangdLSPServer::onInitialize(<wbr>Ctx C, InitializeParams &Params) {<br>
-  reply(C, json::obj{<br>
+void ClangdLSPServer::onInitialize(<wbr>InitializeParams &Params) {<br>
+  reply(json::obj{<br>
       {{"capabilities",<br>
         json::obj{<br>
             {"textDocumentSync", 1},<br>
@@ -82,38 +82,35 @@ void ClangdLSPServer::onInitialize(<wbr>Ctx C<br>
     Server.setRootPath(*Params.<wbr>rootPath);<br>
 }<br>
<br>
-void ClangdLSPServer::onShutdown(<wbr>Ctx C, ShutdownParams &Params) {<br>
+void ClangdLSPServer::onShutdown(<wbr>ShutdownParams &Params) {<br>
   // Do essentially nothing, just say we're ready to exit.<br>
   ShutdownRequestReceived = true;<br>
-  reply(C, nullptr);<br>
+  reply(nullptr);<br>
 }<br>
<br>
-void ClangdLSPServer::onExit(Ctx C, ExitParams &Params) { IsDone = true; }<br>
+void ClangdLSPServer::onExit(<wbr>ExitParams &Params) { IsDone = true; }<br>
<br>
-void ClangdLSPServer::<wbr>onDocumentDidOpen(Ctx C,<br>
-                                        DidOpenTextDocumentParams &Params) {<br>
+void ClangdLSPServer::<wbr>onDocumentDidOpen(<wbr>DidOpenTextDocumentParams &Params) {<br>
   if (Params.metadata && !Params.metadata->extraFlags.<wbr>empty())<br>
     CDB.setExtraFlagsForFile(<wbr>Params.textDocument.uri.file,<br>
                              std::move(Params.metadata-><wbr>extraFlags));<br>
-  Server.addDocument(std::move(<wbr>C), Params.textDocument.uri.file,<br>
-                     Params.textDocument.text);<br>
+  Server.addDocument(Params.<wbr>textDocument.uri.file, Params.textDocument.text);<br>
 }<br>
<br>
-void ClangdLSPServer::<wbr>onDocumentDidChange(Ctx C,<br>
-                                          DidChangeTextDocumentParams &Params) {<br>
+void ClangdLSPServer::<wbr>onDocumentDidChange(<wbr>DidChangeTextDocumentParams &Params) {<br>
   if (Params.contentChanges.size() != 1)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       "can only apply one change at a time");<br>
   // We only support full syncing right now.<br>
-  Server.addDocument(std::move(<wbr>C), Params.textDocument.uri.file,<br>
+  Server.addDocument(Params.<wbr>textDocument.uri.file,<br>
                      Params.contentChanges[0].text)<wbr>;<br>
 }<br>
<br>
-void ClangdLSPServer::onFileEvent(<wbr>Ctx C, DidChangeWatchedFilesParams &Params) {<br>
+void ClangdLSPServer::onFileEvent(<wbr>DidChangeWatchedFilesParams &Params) {<br>
   Server.onFileEvent(Params);<br>
 }<br>
<br>
-void ClangdLSPServer::onCommand(Ctx C, ExecuteCommandParams &Params) {<br>
+void ClangdLSPServer::onCommand(<wbr>ExecuteCommandParams &Params) {<br>
   if (Params.command == ExecuteCommandParams::CLANGD_<wbr>APPLY_FIX_COMMAND &&<br>
       Params.workspaceEdit) {<br>
     // The flow for "apply-fix" :<br>
@@ -127,31 +124,31 @@ void ClangdLSPServer::onCommand(Ctx C, E<br>
<br>
     ApplyWorkspaceEditParams ApplyEdit;<br>
     ApplyEdit.edit = *Params.workspaceEdit;<br>
-    reply(C, "Fix applied.");<br>
+    reply("Fix applied.");<br>
     // We don't need the response so id == 1 is OK.<br>
     // Ideally, we would wait for the response and if there is no error, we<br>
     // would reply success/failure to the original RPC.<br>
-    call(C, "workspace/applyEdit", ApplyEdit);<br>
+    call("workspace/applyEdit", ApplyEdit);<br>
   } else {<br>
     // We should not get here because ExecuteCommandParams would not have<br>
     // parsed in the first place and this handler should not be called. But if<br>
     // more commands are added, this will be here has a safe guard.<br>
     replyError(<br>
-        C, ErrorCode::InvalidParams,<br>
+        ErrorCode::InvalidParams,<br>
         llvm::formatv("Unsupported command \"{0}\".", Params.command).str());<br>
   }<br>
 }<br>
<br>
-void ClangdLSPServer::onRename(Ctx C, RenameParams &Params) {<br>
+void ClangdLSPServer::onRename(<wbr>RenameParams &Params) {<br>
   auto File = Params.textDocument.uri.file;<br>
   auto Code = Server.getDocument(File);<br>
   if (!Code)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       "onRename called for non-added file");<br>
<br>
-  auto Replacements = Server.rename(C, File, Params.position, Params.newName);<br>
+  auto Replacements = Server.rename(File, Params.position, Params.newName);<br>
   if (!Replacements) {<br>
-    replyError(C, ErrorCode::InternalError,<br>
+    replyError(ErrorCode::<wbr>InternalError,<br>
                llvm::toString(Replacements.<wbr>takeError()));<br>
     return;<br>
   }<br>
@@ -159,68 +156,66 @@ void ClangdLSPServer::onRename(Ctx C, Re<br>
   std::vector<TextEdit> Edits = replacementsToEdits(*Code, *Replacements);<br>
   WorkspaceEdit WE;<br>
   WE.changes = {{Params.textDocument.uri.uri(<wbr>), Edits}};<br>
-  reply(C, WE);<br>
+  reply(WE);<br>
 }<br>
<br>
-void ClangdLSPServer::<wbr>onDocumentDidClose(Ctx C,<br>
-                                         DidCloseTextDocumentParams &Params) {<br>
-  Server.removeDocument(std::<wbr>move(C), Params.textDocument.uri.file);<br>
+void ClangdLSPServer::<wbr>onDocumentDidClose(<wbr>DidCloseTextDocumentParams &Params) {<br>
+  Server.removeDocument(Params.<wbr>textDocument.uri.file);<br>
 }<br>
<br>
 void ClangdLSPServer::<wbr>onDocumentOnTypeFormatting(<br>
-    Ctx C, DocumentOnTypeFormattingParams &Params) {<br>
+    DocumentOnTypeFormattingParams &Params) {<br>
   auto File = Params.textDocument.uri.file;<br>
   auto Code = Server.getDocument(File);<br>
   if (!Code)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       "onDocumentOnTypeFormatting called for non-added file");<br>
<br>
   auto ReplacementsOrError = Server.formatOnType(*Code, File, Params.position);<br>
   if (ReplacementsOrError)<br>
-    reply(C, json::ary(replacementsToEdits(<wbr>*Code, ReplacementsOrError.get())));<br>
+    reply(json::ary(<wbr>replacementsToEdits(*Code, ReplacementsOrError.get())));<br>
   else<br>
-    replyError(C, ErrorCode::UnknownErrorCode,<br>
+    replyError(ErrorCode::<wbr>UnknownErrorCode,<br>
                llvm::toString(<wbr>ReplacementsOrError.takeError(<wbr>)));<br>
 }<br>
<br>
 void ClangdLSPServer::<wbr>onDocumentRangeFormatting(<br>
-    Ctx C, DocumentRangeFormattingParams &Params) {<br>
+    DocumentRangeFormattingParams &Params) {<br>
   auto File = Params.textDocument.uri.file;<br>
   auto Code = Server.getDocument(File);<br>
   if (!Code)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       "onDocumentRangeFormatting called for non-added file");<br>
<br>
   auto ReplacementsOrError = Server.formatRange(*Code, File, Params.range);<br>
   if (ReplacementsOrError)<br>
-    reply(C, json::ary(replacementsToEdits(<wbr>*Code, ReplacementsOrError.get())));<br>
+    reply(json::ary(<wbr>replacementsToEdits(*Code, ReplacementsOrError.get())));<br>
   else<br>
-    replyError(C, ErrorCode::UnknownErrorCode,<br>
+    replyError(ErrorCode::<wbr>UnknownErrorCode,<br>
                llvm::toString(<wbr>ReplacementsOrError.takeError(<wbr>)));<br>
 }<br>
<br>
-void ClangdLSPServer::<wbr>onDocumentFormatting(Ctx C,<br>
-                                           DocumentFormattingParams &Params) {<br>
+void ClangdLSPServer::<wbr>onDocumentFormatting(<wbr>DocumentFormattingParams &Params) {<br>
   auto File = Params.textDocument.uri.file;<br>
   auto Code = Server.getDocument(File);<br>
   if (!Code)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       "onDocumentFormatting called for non-added file");<br>
<br>
   auto ReplacementsOrError = Server.formatFile(*Code, File);<br>
   if (ReplacementsOrError)<br>
-    reply(C, json::ary(replacementsToEdits(<wbr>*Code, ReplacementsOrError.get())));<br>
+    reply(json::ary(<wbr>replacementsToEdits(*Code, ReplacementsOrError.get())));<br>
   else<br>
-    replyError(C, ErrorCode::UnknownErrorCode,<br>
+    replyError(ErrorCode::<wbr>UnknownErrorCode,<br>
                llvm::toString(<wbr>ReplacementsOrError.takeError(<wbr>)));<br>
 }<br>
<br>
-void ClangdLSPServer::onCodeAction(<wbr>Ctx C, CodeActionParams &Params) {<br>
+void ClangdLSPServer::onCodeAction(<wbr>CodeActionParams &Params) {<br>
   // We provide a code action for each diagnostic at the requested location<br>
   // which has FixIts available.<br>
   auto Code = Server.getDocument(Params.<wbr>textDocument.uri.file);<br>
   if (!Code)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       "onCodeAction called for non-added file");<br>
<br>
   json::ary Commands;<br>
@@ -236,67 +231,53 @@ void ClangdLSPServer::onCodeAction(<wbr>Ctx C<br>
       });<br>
     }<br>
   }<br>
-  reply(C, std::move(Commands));<br>
+  reply(std::move(Commands));<br>
 }<br>
<br>
-void ClangdLSPServer::onCompletion(<wbr>Ctx C, TextDocumentPositionParams &Params) {<br>
-  auto Reply = Server<br>
-                   .codeComplete(std::move(C), Params.textDocument.uri.file,<br>
-                                 Position{Params.position.line,<br>
-                                          Params.position.character},<br>
-                                 CCOpts)<br>
-                   .get(); // FIXME(ibiryukov): This could be made async if we<br>
-                           // had an API that would allow to attach callbacks to<br>
-                           // futures returned by ClangdServer.<br>
-<br>
-  // We have std::move'd from C, now restore it from response of codeComplete.<br>
-  C = std::move(Reply.first);<br>
-  auto List = std::move(Reply.second.Value);<br>
-  reply(C, List);<br>
+void ClangdLSPServer::onCompletion(<wbr>TextDocumentPositionParams &Params) {<br>
+  Server.codeComplete(Params.<wbr>textDocument.uri.file,<br>
+                      Position{Params.position.line, Params.position.character},<br>
+                      CCOpts,<br>
+                      [](Tagged<CompletionList> List) { reply(List.Value); });<br>
 }<br>
<br>
-void ClangdLSPServer::<wbr>onSignatureHelp(Ctx C,<br>
-                                      TextDocumentPositionParams &Params) {<br>
+void ClangdLSPServer::<wbr>onSignatureHelp(<wbr>TextDocumentPositionParams &Params) {<br>
   auto SignatureHelp = Server.signatureHelp(<br>
-      C, Params.textDocument.uri.file,<br>
+      Params.textDocument.uri.file,<br>
       Position{Params.position.line, Params.position.character});<br>
   if (!SignatureHelp)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       llvm::toString(SignatureHelp.<wbr>takeError()));<br>
-  reply(C, SignatureHelp->Value);<br>
+  reply(SignatureHelp->Value);<br>
 }<br>
<br>
-void ClangdLSPServer::<wbr>onGoToDefinition(Ctx C,<br>
-                                       TextDocumentPositionParams &Params) {<br>
+void ClangdLSPServer::<wbr>onGoToDefinition(<wbr>TextDocumentPositionParams &Params) {<br>
   auto Items = Server.findDefinitions(<br>
-      C, Params.textDocument.uri.file,<br>
+      Params.textDocument.uri.file,<br>
       Position{Params.position.line, Params.position.character});<br>
   if (!Items)<br>
-    return replyError(C, ErrorCode::InvalidParams,<br>
+    return replyError(ErrorCode::<wbr>InvalidParams,<br>
                       llvm::toString(Items.<wbr>takeError()));<br>
-  reply(C, json::ary(Items->Value));<br>
+  reply(json::ary(Items->Value))<wbr>;<br>
 }<br>
<br>
-void ClangdLSPServer::<wbr>onSwitchSourceHeader(Ctx C,<br>
-                                           TextDocumentIdentifier &Params) {<br>
+void ClangdLSPServer::<wbr>onSwitchSourceHeader(<wbr>TextDocumentIdentifier &Params) {<br>
   llvm::Optional<Path> Result = Server.switchSourceHeader(<wbr>Params.uri.file);<br>
-  reply(C, Result ? URI::createFile(*Result).<wbr>toString() : "");<br>
+  reply(Result ? URI::createFile(*Result).<wbr>toString() : "");<br>
 }<br>
<br>
-void ClangdLSPServer::<wbr>onDocumentHighlight(Ctx C,<br>
-                                          TextDocumentPositionParams &Params) {<br>
-<br>
+void ClangdLSPServer::<wbr>onDocumentHighlight(<wbr>TextDocumentPositionParams &Params) {<br>
   auto Highlights = Server.findDocumentHighlights(<br>
-      C, Params.textDocument.uri.file,<br>
+      Params.textDocument.uri.file,<br>
       Position{Params.position.line, Params.position.character});<br>
<br>
   if (!Highlights) {<br>
-    replyError(C, ErrorCode::InternalError,<br>
+    replyError(ErrorCode::<wbr>InternalError,<br>
                llvm::toString(Highlights.<wbr>takeError()));<br>
     return;<br>
   }<br>
<br>
-  reply(C, json::ary(Highlights->Value));<br>
+  reply(json::ary(Highlights-><wbr>Value));<br>
 }<br>
<br>
 ClangdLSPServer::<wbr>ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount,<br>
@@ -315,8 +296,8 @@ bool ClangdLSPServer::run(std::<wbr>istream &<br>
   assert(!IsDone && "Run was called before");<br>
<br>
   // Set up JSONRPCDispatcher.<br>
-  JSONRPCDispatcher Dispatcher([](Context Ctx, const json::Expr &Params) {<br>
-    replyError(Ctx, ErrorCode::MethodNotFound, "method not found");<br>
+  JSONRPCDispatcher Dispatcher([](const json::Expr &Params) {<br>
+    replyError(ErrorCode::<wbr>MethodNotFound, "method not found");<br>
   });<br>
   registerCallbackHandlers(<wbr>Dispatcher, Out, /*Callbacks=*/*this);<br>
<br>
@@ -346,8 +327,7 @@ std::vector<TextEdit> ClangdLSPServer::g<br>
 }<br>
<br>
 void ClangdLSPServer::<wbr>onDiagnosticsReady(<br>
-    const Context &Ctx, PathRef File,<br>
-    Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) {<br>
+    PathRef File, Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) {<br>
   json::ary DiagnosticsJSON;<br>
<br>
   DiagnosticToReplacementMap LocalFixIts; // Temporary storage<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ClangdLSPServer.<wbr>h?rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.h Wed Jan 31 05:40:48 2018<br>
@@ -50,32 +50,30 @@ public:<br>
 private:<br>
   // Implement DiagnosticsConsumer.<br>
   virtual void<br>
-  onDiagnosticsReady(const Context &Ctx, PathRef File,<br>
+  onDiagnosticsReady(PathRef File,<br>
                      Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) override;<br>
<br>
   // Implement ProtocolCallbacks.<br>
-  void onInitialize(Ctx C, InitializeParams &Params) override;<br>
-  void onShutdown(Ctx C, ShutdownParams &Params) override;<br>
-  void onExit(Ctx C, ExitParams &Params) override;<br>
-  void onDocumentDidOpen(Ctx C, DidOpenTextDocumentParams &Params) override;<br>
-  void onDocumentDidChange(Ctx C, DidChangeTextDocumentParams &Params) override;<br>
-  void onDocumentDidClose(Ctx C, DidCloseTextDocumentParams &Params) override;<br>
+  void onInitialize(InitializeParams &Params) override;<br>
+  void onShutdown(ShutdownParams &Params) override;<br>
+  void onExit(ExitParams &Params) override;<br>
+  void onDocumentDidOpen(<wbr>DidOpenTextDocumentParams &Params) override;<br>
+  void onDocumentDidChange(<wbr>DidChangeTextDocumentParams &Params) override;<br>
+  void onDocumentDidClose(<wbr>DidCloseTextDocumentParams &Params) override;<br>
   void<br>
-  onDocumentOnTypeFormatting(Ctx C,<br>
-                             DocumentOnTypeFormattingParams &Params) override;<br>
+  onDocumentOnTypeFormatting(<wbr>DocumentOnTypeFormattingParams &Params) override;<br>
   void<br>
-  onDocumentRangeFormatting(Ctx C,<br>
-                            DocumentRangeFormattingParams &Params) override;<br>
-  void onDocumentFormatting(Ctx C, DocumentFormattingParams &Params) override;<br>
-  void onCodeAction(Ctx C, CodeActionParams &Params) override;<br>
-  void onCompletion(Ctx C, TextDocumentPositionParams &Params) override;<br>
-  void onSignatureHelp(Ctx C, TextDocumentPositionParams &Params) override;<br>
-  void onGoToDefinition(Ctx C, TextDocumentPositionParams &Params) override;<br>
-  void onSwitchSourceHeader(Ctx C, TextDocumentIdentifier &Params) override;<br>
-  void onDocumentHighlight(Ctx C, TextDocumentPositionParams &Params) override;<br>
-  void onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) override;<br>
-  void onCommand(Ctx C, ExecuteCommandParams &Params) override;<br>
-  void onRename(Ctx C, RenameParams &Parames) override;<br>
+  onDocumentRangeFormatting(<wbr>DocumentRangeFormattingParams &Params) override;<br>
+  void onDocumentFormatting(<wbr>DocumentFormattingParams &Params) override;<br>
+  void onCodeAction(CodeActionParams &Params) override;<br>
+  void onCompletion(<wbr>TextDocumentPositionParams &Params) override;<br>
+  void onSignatureHelp(<wbr>TextDocumentPositionParams &Params) override;<br>
+  void onGoToDefinition(<wbr>TextDocumentPositionParams &Params) override;<br>
+  void onSwitchSourceHeader(<wbr>TextDocumentIdentifier &Params) override;<br>
+  void onDocumentHighlight(<wbr>TextDocumentPositionParams &Params) override;<br>
+  void onFileEvent(<wbr>DidChangeWatchedFilesParams &Params) override;<br>
+  void onCommand(ExecuteCommandParams &Params) override;<br>
+  void onRename(RenameParams &Parames) override;<br>
<br>
   std::vector<TextEdit> getFixIts(StringRef File, const clangd::Diagnostic &D);<br>
<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ClangdServer.cpp?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp Wed Jan 31 05:40:48 2018<br>
@@ -116,11 +116,11 @@ ClangdServer::ClangdServer(<wbr>GlobalCompila<br>
       // is parsed.<br>
       // FIXME(ioeric): this can be slow and we may be able to index on less<br>
       // critical paths.<br>
-      WorkScheduler(<br>
-          AsyncThreadsCount, StorePreamblesInMemory,<br>
-          FileIdx ? [this](const Context &Ctx, PathRef Path,<br>
-                           ParsedAST *AST) { FileIdx->update(Ctx, Path, AST); }<br>
-                  : ASTParsedCallback()) {<br>
+      WorkScheduler(<wbr>AsyncThreadsCount, StorePreamblesInMemory,<br>
+                    FileIdx<br>
+                        ? [this](PathRef Path,<br>
+                                 ParsedAST *AST) { FileIdx->update(Path, AST); }<br>
+                        : ASTParsedCallback()) {<br>
   if (FileIdx && StaticIdx) {<br>
     MergedIndex = mergeIndex(FileIdx.get(), StaticIdx);<br>
     Index = MergedIndex.get();<br>
@@ -139,35 +139,33 @@ void ClangdServer::setRootPath(<wbr>PathRef R<br>
     this->RootPath = NewRootPath;<br>
 }<br>
<br>
-std::future<Context> ClangdServer::addDocument(<wbr>Context Ctx, PathRef File,<br>
-                                               StringRef Contents) {<br>
+std::future<void> ClangdServer::addDocument(<wbr>PathRef File, StringRef Contents) {<br>
   DocVersion Version = DraftMgr.updateDraft(File, Contents);<br>
   auto TaggedFS = FSProvider.<wbr>getTaggedFileSystem(File);<br>
-  return scheduleReparseAndDiags(std::<wbr>move(Ctx), File,<br>
-                                 VersionedDraft{Version, Contents.str()},<br>
+  return scheduleReparseAndDiags(File, VersionedDraft{Version, Contents.str()},<br>
                                  std::move(TaggedFS));<br>
 }<br>
<br>
-std::future<Context> ClangdServer::removeDocument(<wbr>Context Ctx, PathRef File) {<br>
+std::future<void> ClangdServer::removeDocument(<wbr>PathRef File) {<br>
   DraftMgr.removeDraft(File);<br>
   CompileArgs.invalidate(File);<br>
<br>
-  std::promise<Context> DonePromise;<br>
-  std::future<Context> DoneFuture = DonePromise.get_future();<br>
+  std::promise<void> DonePromise;<br>
+  std::future<void> DoneFuture = DonePromise.get_future();<br>
<br>
   auto Callback = BindWithForward(<br>
-      [](Context Ctx, std::promise<Context> DonePromise, llvm::Error Err) {<br>
+      [](std::promise<void> DonePromise, llvm::Error Err) {<br>
         if (Err)<br>
           ignoreError(std::move(Err));<br>
-        DonePromise.set_value(std::<wbr>move(Ctx));<br>
+        DonePromise.set_value();<br>
       },<br>
-      std::move(Ctx), std::move(DonePromise));<br>
+      std::move(DonePromise));<br>
<br>
   WorkScheduler.remove(File, std::move(Callback));<br>
   return DoneFuture;<br>
 }<br>
<br>
-std::future<Context> ClangdServer::forceReparse(<wbr>Context Ctx, PathRef File) {<br>
+std::future<void> ClangdServer::forceReparse(<wbr>PathRef File) {<br>
   auto FileContents = DraftMgr.getDraft(File);<br>
   assert(FileContents.Draft &&<br>
          "forceReparse() was called for non-added document");<br>
@@ -177,38 +175,34 @@ std::future<Context> ClangdServer::force<br>
   CompileArgs.invalidate(File);<br>
<br>
   auto TaggedFS = FSProvider.<wbr>getTaggedFileSystem(File);<br>
-  return scheduleReparseAndDiags(std::<wbr>move(Ctx), File, std::move(FileContents),<br>
+  return scheduleReparseAndDiags(File, std::move(FileContents),<br>
                                  std::move(TaggedFS));<br>
 }<br>
<br>
-std::future<std::pair<<wbr>Context, Tagged<CompletionList>>><br>
-ClangdServer::codeComplete(<wbr>Context Ctx, PathRef File, Position Pos,<br>
+std::future<Tagged<<wbr>CompletionList>><br>
+ClangdServer::codeComplete(<wbr>PathRef File, Position Pos,<br>
                            const clangd::CodeCompleteOptions &Opts,<br>
                            llvm::Optional<StringRef> OverridenContents,<br>
                            IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS) {<br>
-  using ResultType = std::pair<Context, Tagged<CompletionList>>;<br>
-<br>
-  std::promise<ResultType> ResultPromise;<br>
-<br>
-  auto Callback = [](std::promise<ResultType> ResultPromise, Context Ctx,<br>
+  std::promise<Tagged<<wbr>CompletionList>> ResultPromise;<br>
+  auto Callback = [](std::promise<Tagged<<wbr>CompletionList>> ResultPromise,<br>
                      Tagged<CompletionList> Result) -> void {<br>
-    ResultPromise.set_value({std::<wbr>move(Ctx), std::move(Result)});<br>
+    ResultPromise.set_value(std::<wbr>move(Result));<br>
   };<br>
<br>
-  std::future<ResultType> ResultFuture = ResultPromise.get_future();<br>
-  codeComplete(std::move(Ctx), File, Pos, Opts,<br>
+  auto ResultFuture = ResultPromise.get_future();<br>
+  codeComplete(File, Pos, Opts,<br>
                BindWithForward(Callback, std::move(ResultPromise)),<br>
                OverridenContents, UsedFS);<br>
   return ResultFuture;<br>
 }<br>
<br>
 void ClangdServer::codeComplete(<br>
-    Context Ctx, PathRef File, Position Pos,<br>
-    const clangd::CodeCompleteOptions &Opts,<br>
-    UniqueFunction<void(Context, Tagged<CompletionList>)> Callback,<br>
+    PathRef File, Position Pos, const clangd::CodeCompleteOptions &Opts,<br>
+    UniqueFunction<void(Tagged<<wbr>CompletionList>)> Callback,<br>
     llvm::Optional<StringRef> OverridenContents,<br>
     IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS) {<br>
-  using CallbackType = UniqueFunction<void(Context, Tagged<CompletionList>)>;<br>
+  using CallbackType = UniqueFunction<void(Tagged<<wbr>CompletionList>)>;<br>
<br>
   auto TaggedFS = FSProvider.<wbr>getTaggedFileSystem(File);<br>
   if (UsedFS)<br>
@@ -231,8 +225,8 @@ void ClangdServer::codeComplete(<br>
   // Copy PCHs to avoid accessing this->PCHs concurrently<br>
   std::shared_ptr<<wbr>PCHContainerOperations> PCHs = this->PCHs;<br>
   auto Task = [PCHs, Pos, TaggedFS, CodeCompleteOpts](<br>
-                  Context Ctx, std::string Contents, Path File,<br>
-                  CallbackType Callback, llvm::Expected<<wbr>InputsAndPreamble> IP) {<br>
+                  std::string Contents, Path File, CallbackType Callback,<br>
+                  llvm::Expected<<wbr>InputsAndPreamble> IP) {<br>
     assert(IP && "error when trying to read preamble for codeComplete");<br>
     auto PreambleData = IP->Preamble;<br>
     auto &Command = IP->Inputs.CompileCommand;<br>
@@ -240,20 +234,19 @@ void ClangdServer::codeComplete(<br>
     // FIXME(ibiryukov): even if Preamble is non-null, we may want to check<br>
     // both the old and the new version in case only one of them matches.<br>
     CompletionList Result = clangd::codeComplete(<br>
-        Ctx, File, Command, PreambleData ? &PreambleData->Preamble : nullptr,<br>
+        File, Command, PreambleData ? &PreambleData->Preamble : nullptr,<br>
         Contents, Pos, TaggedFS.Value, PCHs, CodeCompleteOpts);<br>
<br>
-    Callback(std::move(Ctx),<br>
-             make_tagged(std::move(Result), std::move(TaggedFS.Tag)));<br>
+    Callback(make_tagged(std::<wbr>move(Result), std::move(TaggedFS.Tag)));<br>
   };<br>
<br>
-  WorkScheduler.runWithPreamble(<br>
-      File, BindWithForward(Task, std::move(Ctx), std::move(Contents),<br>
-                            File.str(), std::move(Callback)));<br>
+  WorkScheduler.runWithPreamble(<wbr>File, BindWithForward(Task, std::move(Contents),<br>
+                                                      File.str(),<br>
+                                                      std::move(Callback)));<br>
 }<br>
<br>
 llvm::Expected<Tagged<<wbr>SignatureHelp>><br>
-ClangdServer::signatureHelp(<wbr>const Context &Ctx, PathRef File, Position Pos,<br>
+ClangdServer::signatureHelp(<wbr>PathRef File, Position Pos,<br>
                             llvm::Optional<StringRef> OverridenContents,<br>
                             IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS) {<br>
   auto TaggedFS = FSProvider.<wbr>getTaggedFileSystem(File);<br>
@@ -272,7 +265,7 @@ ClangdServer::signatureHelp(<wbr>const Contex<br>
     Contents = std::move(*Latest.Draft);<br>
   }<br>
<br>
-  auto Action = [=, &Ctx](llvm::Expected<<wbr>InputsAndPreamble> IP)<br>
+  auto Action = [=](llvm::Expected<<wbr>InputsAndPreamble> IP)<br>
       -> Expected<Tagged<SignatureHelp><wbr>> {<br>
     if (!IP)<br>
       return IP.takeError();<br>
@@ -280,7 +273,7 @@ ClangdServer::signatureHelp(<wbr>const Contex<br>
     auto &Command = IP->Inputs.CompileCommand;<br>
<br>
     return make_tagged(<br>
-        clangd::signatureHelp(Ctx, File, Command,<br>
+        clangd::signatureHelp(File, Command,<br>
                               PreambleData ? &PreambleData->Preamble : nullptr,<br>
                               Contents, Pos, TaggedFS.Value, PCHs),<br>
         TaggedFS.Tag);<br>
@@ -316,8 +309,7 @@ ClangdServer::formatOnType(<wbr>StringRef Cod<br>
 }<br>
<br>
 Expected<std::vector<tooling::<wbr>Replacement>><br>
-ClangdServer::rename(const Context &Ctx, PathRef File, Position Pos,<br>
-                     llvm::StringRef NewName) {<br>
+ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName) {<br>
   using RetType = Expected<std::vector<tooling::<wbr>Replacement>>;<br>
   auto Action = [=](Expected<InputsAndAST> InpAST) -> RetType {<br>
     if (!InpAST)<br>
@@ -396,14 +388,14 @@ std::string ClangdServer::dumpAST(PathRe<br>
 }<br>
<br>
 llvm::Expected<Tagged<std::<wbr>vector<Location>>><br>
-ClangdServer::<wbr>findDefinitions(const Context &Ctx, PathRef File, Position Pos) {<br>
+ClangdServer::<wbr>findDefinitions(PathRef File, Position Pos) {<br>
   auto TaggedFS = FSProvider.<wbr>getTaggedFileSystem(File);<br>
<br>
   using RetType = llvm::Expected<Tagged<std::<wbr>vector<Location>>>;<br>
-  auto Action = [=, &Ctx](llvm::Expected<<wbr>InputsAndAST> InpAST) -> RetType {<br>
+  auto Action = [=](llvm::Expected<<wbr>InputsAndAST> InpAST) -> RetType {<br>
     if (!InpAST)<br>
       return InpAST.takeError();<br>
-    auto Result = clangd::findDefinitions(Ctx, InpAST->AST, Pos);<br>
+    auto Result = clangd::findDefinitions(<wbr>InpAST->AST, Pos);<br>
     return make_tagged(std::move(Result), TaggedFS.Tag);<br>
   };<br>
   return blockingRunWithAST<RetType>(<wbr>WorkScheduler, File, Action);<br>
@@ -483,8 +475,7 @@ ClangdServer::formatCode(llvm:<wbr>:StringRef<br>
 }<br>
<br>
 llvm::Expected<Tagged<std::<wbr>vector<DocumentHighlight>>><br>
-ClangdServer::<wbr>findDocumentHighlights(const Context &Ctx, PathRef File,<br>
-                                     Position Pos) {<br>
+ClangdServer::<wbr>findDocumentHighlights(PathRef File, Position Pos) {<br>
   auto FileContents = DraftMgr.getDraft(File);<br>
   if (!FileContents.Draft)<br>
     return llvm::make_error<llvm::<wbr>StringError>(<br>
@@ -494,17 +485,17 @@ ClangdServer::<wbr>findDocumentHighlights(con<br>
   auto TaggedFS = FSProvider.<wbr>getTaggedFileSystem(File);<br>
<br>
   using RetType = llvm::Expected<Tagged<std::<wbr>vector<DocumentHighlight>>>;<br>
-  auto Action = [=, &Ctx](llvm::Expected<<wbr>InputsAndAST> InpAST) -> RetType {<br>
+  auto Action = [=](llvm::Expected<<wbr>InputsAndAST> InpAST) -> RetType {<br>
     if (!InpAST)<br>
       return InpAST.takeError();<br>
-    auto Result = clangd::<wbr>findDocumentHighlights(Ctx, InpAST->AST, Pos);<br>
+    auto Result = clangd::<wbr>findDocumentHighlights(InpAST-<wbr>>AST, Pos);<br>
     return make_tagged(std::move(Result), TaggedFS.Tag);<br>
   };<br>
   return blockingRunWithAST<RetType>(<wbr>WorkScheduler, File, Action);<br>
 }<br>
<br>
-std::future<Context> ClangdServer::<wbr>scheduleReparseAndDiags(<br>
-    Context Ctx, PathRef File, VersionedDraft Contents,<br>
+std::future<void> ClangdServer::<wbr>scheduleReparseAndDiags(<br>
+    PathRef File, VersionedDraft Contents,<br>
     Tagged<IntrusiveRefCntPtr<vfs:<wbr>:FileSystem>> TaggedFS) {<br>
   tooling::CompileCommand Command = CompileArgs.getCompileCommand(<wbr>File);<br>
<br>
@@ -514,14 +505,12 @@ std::future<Context> ClangdServer::sched<br>
   Path FileStr = File.str();<br>
   VFSTag Tag = std::move(TaggedFS.Tag);<br>
<br>
-  std::promise<Context> DonePromise;<br>
-  std::future<Context> DoneFuture = DonePromise.get_future();<br>
+  std::promise<void> DonePromise;<br>
+  std::future<void> DoneFuture = DonePromise.get_future();<br>
<br>
-  auto Callback = [this, Version, FileStr,<br>
-                   Tag](std::promise<Context> DonePromise, Context Ctx,<br>
-                        OptDiags Diags) {<br>
-    auto Guard =<br>
-        llvm::make_scope_exit([&]() { DonePromise.set_value(std::<wbr>move(Ctx)); });<br>
+  auto Callback = [this, Version, FileStr, Tag](std::promise<void> DonePromise,<br>
+                                                OptDiags Diags) {<br>
+    auto Guard = llvm::make_scope_exit([&]() { DonePromise.set_value(); });<br>
     if (!Diags)<br>
       return; // A new reparse was requested before this one completed.<br>
<br>
@@ -538,10 +527,10 @@ std::future<Context> ClangdServer::sched<br>
     LastReportedDiagsVersion = Version;<br>
<br>
     DiagConsumer.<wbr>onDiagnosticsReady(<br>
-        Ctx, FileStr, make_tagged(std::move(*Diags), std::move(Tag)));<br>
+        FileStr, make_tagged(std::move(*Diags), std::move(Tag)));<br>
   };<br>
<br>
-  WorkScheduler.update(std::<wbr>move(Ctx), File,<br>
+  WorkScheduler.update(File,<br>
                        ParseInputs{std::move(Command)<wbr>,<br>
                                    std::move(TaggedFS.Value),<br>
                                    std::move(*Contents.Draft)},<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdServer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ClangdServer.h?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ClangdServer.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ClangdServer.h Wed Jan 31 05:40:48 2018<br>
@@ -71,7 +71,7 @@ public:<br>
<br>
   /// Called by ClangdServer when \p Diagnostics for \p File are ready.<br>
   virtual void<br>
-  onDiagnosticsReady(const Context &Ctx, PathRef File,<br>
+  onDiagnosticsReady(PathRef File,<br>
                      Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) = 0;<br>
 };<br>
<br>
@@ -95,8 +95,6 @@ public:<br>
   getTaggedFileSystem(PathRef File) override;<br>
 };<br>
<br>
-class ClangdServer;<br>
-<br>
 /// Provides API to manage ASTs for a collection of C++ files and request<br>
 /// various language features.<br>
 /// Currently supports async diagnostics, code completion, formatting and goto<br>
@@ -156,30 +154,26 @@ public:<br>
   /// diagnostics) is finished.<br>
   /// FIXME: don't return futures here, LSP does not require a response for this<br>
   /// request.<br>
-  std::future<Context> addDocument(Context Ctx, PathRef File,<br>
-                                   StringRef Contents);<br>
+  std::future<void> addDocument(PathRef File, StringRef Contents);<br>
+<br>
   /// Remove \p File from list of tracked files, schedule a request to free<br>
   /// resources associated with it.<br>
   /// \return A future that will become ready when the file is removed and all<br>
   /// associated resources are freed.<br>
   /// FIXME: don't return futures here, LSP does not require a response for this<br>
   /// request.<br>
-  std::future<Context> removeDocument(Context Ctx, PathRef File);<br>
+  std::future<void> removeDocument(PathRef File);<br>
+<br>
   /// Force \p File to be reparsed using the latest contents.<br>
   /// Will also check if CompileCommand, provided by GlobalCompilationDatabase<br>
   /// for \p File has changed. If it has, will remove currently stored Preamble<br>
   /// and AST and rebuild them from scratch.<br>
   /// FIXME: don't return futures here, LSP does not require a response for this<br>
   /// request.<br>
-  std::future<Context> forceReparse(Context Ctx, PathRef File);<br>
+  std::future<void> forceReparse(PathRef File);<br>
<br>
-  /// DEPRECATED. Please use a callback-based version, this API is deprecated<br>
-  /// and will soon be removed.<br>
-  ///<br>
   /// Run code completion for \p File at \p Pos.<br>
-  ///<br>
-  /// Request is processed asynchronously. You can use the returned future to<br>
-  /// wait for the results of the async request.<br>
+  /// Request is processed asynchronously.<br>
   ///<br>
   /// If \p OverridenContents is not None, they will used only for code<br>
   /// completion, i.e. no diagnostics update will be scheduled and a draft for<br>
@@ -190,18 +184,18 @@ public:<br>
   /// This method should only be called for currently tracked files. However, it<br>
   /// is safe to call removeDocument for \p File after this method returns, even<br>
   /// while returned future is not yet ready.<br>
-  std::future<std::pair<Context, Tagged<CompletionList>>><br>
-  codeComplete(Context Ctx, PathRef File, Position Pos,<br>
-               const clangd::CodeCompleteOptions &Opts,<br>
-               llvm::Optional<StringRef> OverridenContents = llvm::None,<br>
-               IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS = nullptr);<br>
-<br>
   /// A version of `codeComplete` that runs \p Callback on the processing thread<br>
   /// when codeComplete results become available.<br>
-  void<br>
-  codeComplete(Context Ctx, PathRef File, Position Pos,<br>
+  void codeComplete(PathRef File, Position Pos,<br>
+                    const clangd::CodeCompleteOptions &Opts,<br>
+                    UniqueFunction<void(Tagged<<wbr>CompletionList>)> Callback,<br>
+                    llvm::Optional<StringRef> OverridenContents = llvm::None,<br>
+                    IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS = nullptr);<br>
+<br>
+  /// DEPRECATED: Please use the callback-based version of codeComplete.<br>
+  std::future<Tagged<<wbr>CompletionList>><br>
+  codeComplete(PathRef File, Position Pos,<br>
                const clangd::CodeCompleteOptions &Opts,<br>
-               UniqueFunction<void(Context, Tagged<CompletionList>)> Callback,<br>
                llvm::Optional<StringRef> OverridenContents = llvm::None,<br>
                IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS = nullptr);<br>
<br>
@@ -213,13 +207,13 @@ public:<br>
   /// vfs::FileSystem used for signature help. This method should only be called<br>
   /// for currently tracked files.<br>
   llvm::Expected<Tagged<<wbr>SignatureHelp>><br>
-  signatureHelp(const Context &Ctx, PathRef File, Position Pos,<br>
+  signatureHelp(PathRef File, Position Pos,<br>
                 llvm::Optional<StringRef> OverridenContents = llvm::None,<br>
                 IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS = nullptr);<br>
<br>
   /// Get definition of symbol at a specified \p Line and \p Column in \p File.<br>
-  llvm::Expected<Tagged<std::<wbr>vector<Location>>><br>
-  findDefinitions(const Context &Ctx, PathRef File, Position Pos);<br>
+  llvm::Expected<Tagged<std::<wbr>vector<Location>>> findDefinitions(PathRef File,<br>
+                                                                Position Pos);<br>
<br>
   /// Helper function that returns a path to the corresponding source file when<br>
   /// given a header file and vice versa.<br>
@@ -227,7 +221,7 @@ public:<br>
<br>
   /// Get document highlights for a given position.<br>
   llvm::Expected<Tagged<std::<wbr>vector<DocumentHighlight>>><br>
-  findDocumentHighlights(const Context &Ctx, PathRef File, Position Pos);<br>
+  findDocumentHighlights(PathRef File, Position Pos);<br>
<br>
   /// Run formatting for \p Rng inside \p File with content \p Code.<br>
   llvm::Expected<tooling::<wbr>Replacements> formatRange(StringRef Code,<br>
@@ -244,8 +238,7 @@ public:<br>
<br>
   /// Rename all occurrences of the symbol at the \p Pos in \p File to<br>
   /// \p NewName.<br>
-  Expected<std::vector<tooling::<wbr>Replacement>> rename(const Context &Ctx,<br>
-                                                     PathRef File, Position Pos,<br>
+  Expected<std::vector<tooling::<wbr>Replacement>> rename(PathRef File, Position Pos,<br>
                                                      llvm::StringRef NewName);<br>
<br>
   /// Gets current document contents for \p File. Returns None if \p File is not<br>
@@ -277,8 +270,8 @@ private:<br>
   formatCode(llvm::StringRef Code, PathRef File,<br>
              ArrayRef<tooling::Range> Ranges);<br>
<br>
-  std::future<Context><br>
-  scheduleReparseAndDiags(<wbr>Context Ctx, PathRef File, VersionedDraft Contents,<br>
+  std::future<void><br>
+  scheduleReparseAndDiags(<wbr>PathRef File, VersionedDraft Contents,<br>
                           Tagged<IntrusiveRefCntPtr<vfs:<wbr>:FileSystem>> TaggedFS);<br>
<br>
   CompileArgsCache CompileArgs;<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ClangdUnit.cpp?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp Wed Jan 31 05:40:48 2018<br>
@@ -229,8 +229,7 @@ void clangd::dumpAST(ParsedAST &AST, llv<br>
 }<br>
<br>
 llvm::Optional<ParsedAST><br>
-ParsedAST::Build(const Context &Ctx,<br>
-                 std::unique_ptr<clang::<wbr>CompilerInvocation> CI,<br>
+ParsedAST::Build(std::unique_<wbr>ptr<clang::CompilerInvocation> CI,<br>
                  std::shared_ptr<const PreambleData> Preamble,<br>
                  std::unique_ptr<llvm::<wbr>MemoryBuffer> Buffer,<br>
                  std::shared_ptr<<wbr>PCHContainerOperations> PCHs,<br>
@@ -254,12 +253,12 @@ ParsedAST::Build(const Context &Ctx,<br>
   auto Action = llvm::make_unique<<wbr>ClangdFrontendAction>();<br>
   const FrontendInputFile &MainInput = Clang->getFrontendOpts().<wbr>Inputs[0];<br>
   if (!Action->BeginSourceFile(*<wbr>Clang, MainInput)) {<br>
-    log(Ctx, "BeginSourceFile() failed when building AST for " +<br>
-                 MainInput.getFile());<br>
+    log("BeginSourceFile() failed when building AST for " +<br>
+        MainInput.getFile());<br>
     return llvm::None;<br>
   }<br>
   if (!Action->Execute())<br>
-    log(Ctx, "Execute() failed when building AST for " + MainInput.getFile());<br>
+    log("Execute() failed when building AST for " + MainInput.getFile());<br>
<br>
   // UnitDiagsConsumer is local, we can not store it in CompilerInstance that<br>
   // has a longer lifetime.<br>
@@ -387,8 +386,7 @@ CppFile::CppFile(PathRef FileName, bool<br>
       RebuildCounter(0), RebuildInProgress(false), ASTMemUsage(0),<br>
       PreambleMemUsage(0), PCHs(std::move(PCHs)),<br>
       ASTCallback(std::move(<wbr>ASTCallback)) {<br>
-  // FIXME(ibiryukov): we should pass a proper Context here.<br>
-  log(Context::empty(), "Created CppFile for " + FileName);<br>
+  log("Created CppFile for " + FileName);<br>
<br>
   std::lock_guard<std::mutex> Lock(Mutex);<br>
   LatestAvailablePreamble = nullptr;<br>
@@ -442,11 +440,11 @@ UniqueFunction<void()> CppFile::deferCan<br>
 }<br>
<br>
 llvm::Optional<std::vector<<wbr>DiagWithFixIts>><br>
-CppFile::rebuild(const Context &Ctx, ParseInputs &&Inputs) {<br>
-  return deferRebuild(std::move(Inputs)<wbr>)(Ctx);<br>
+CppFile::rebuild(ParseInputs &&Inputs) {<br>
+  return deferRebuild(std::move(Inputs)<wbr>)();<br>
 }<br>
<br>
-UniqueFunction<llvm::<wbr>Optional<std::vector<<wbr>DiagWithFixIts>>(const Context &)><br>
+UniqueFunction<llvm::<wbr>Optional<std::vector<<wbr>DiagWithFixIts>>()><br>
 CppFile::deferRebuild(<wbr>ParseInputs &&Inputs) {<br>
   std::shared_ptr<const PreambleData> OldPreamble;<br>
   std::shared_ptr<<wbr>PCHContainerOperations> PCHs;<br>
@@ -483,13 +481,11 @@ CppFile::deferRebuild(<wbr>ParseInputs &&Inpu<br>
   std::shared_ptr<CppFile> That = shared_from_this();<br>
   auto FinishRebuild =<br>
       [OldPreamble, RequestRebuildCounter, PCHs,<br>
-       That](ParseInputs Inputs,<br>
-             const Context &Ctx) mutable /* to allow changing OldPreamble. */<br>
+       That](ParseInputs Inputs) mutable /* to allow changing OldPreamble. */<br>
       -> llvm::Optional<std::vector<<wbr>DiagWithFixIts>> {<br>
-    log(Context::empty(),<br>
-        "Rebuilding file " + That->FileName + " with command [" +<br>
-            Inputs.CompileCommand.<wbr>Directory + "] " +<br>
-            llvm::join(Inputs.<wbr>CompileCommand.CommandLine, " "));<br>
+    log("Rebuilding file " + That->FileName + " with command [" +<br>
+        Inputs.CompileCommand.<wbr>Directory + "] " +<br>
+        llvm::join(Inputs.<wbr>CompileCommand.CommandLine, " "));<br>
<br>
     // Only one execution of this method is possible at a time.<br>
     // RebuildGuard will wait for any ongoing rebuilds to finish and will put us<br>
@@ -532,16 +528,16 @@ CppFile::deferRebuild(<wbr>ParseInputs &&Inpu<br>
       if (OldPreamble &&<br>
           OldPreamble->Preamble.<wbr>CanReuse(*CI, ContentsBuffer.get(), Bounds,<br>
                                          Inputs.FS.get())) {<br>
-        log(Ctx, "Reusing preamble for file " + Twine(That->FileName));<br>
+        log("Reusing preamble for file " + Twine(That->FileName));<br>
         return OldPreamble;<br>
       }<br>
-      log(Ctx, "Premble for file " + Twine(That->FileName) +<br>
-                   " cannot be reused. Attempting to rebuild it.");<br>
+      log("Premble for file " + Twine(That->FileName) +<br>
+          " cannot be reused. Attempting to rebuild it.");<br>
       // We won't need the OldPreamble anymore, release it so it can be<br>
       // deleted (if there are no other references to it).<br>
       OldPreamble.reset();<br>
<br>
-      trace::Span Tracer(Ctx, "Preamble");<br>
+      trace::Span Tracer("Preamble");<br>
       SPAN_ATTACH(Tracer, "File", That->FileName);<br>
       std::vector<DiagWithFixIts> PreambleDiags;<br>
       StoreDiagsConsumer PreambleDiagnosticsConsumer(/*<wbr>ref*/ PreambleDiags);<br>
@@ -566,17 +562,15 @@ CppFile::deferRebuild(<wbr>ParseInputs &&Inpu<br>
       CI->getFrontendOpts().<wbr>SkipFunctionBodies = false;<br>
<br>
       if (BuiltPreamble) {<br>
-        log(Tracer.Ctx, "Built preamble of size " +<br>
-                            Twine(BuiltPreamble->getSize()<wbr>) + " for file " +<br>
-                            Twine(That->FileName));<br>
+        log("Built preamble of size " + Twine(BuiltPreamble->getSize()<wbr>) +<br>
+            " for file " + Twine(That->FileName));<br>
<br>
         return std::make_shared<PreambleData><wbr>(<br>
             std::move(*BuiltPreamble),<br>
             SerializedDeclsCollector.<wbr>takeTopLevelDeclIDs(),<br>
             std::move(PreambleDiags));<br>
       } else {<br>
-        log(Tracer.Ctx,<br>
-            "Could not build a preamble for file " + Twine(That->FileName));<br>
+        log("Could not build a preamble for file " + Twine(That->FileName));<br>
         return nullptr;<br>
       }<br>
     };<br>
@@ -606,18 +600,17 @@ CppFile::deferRebuild(<wbr>ParseInputs &&Inpu<br>
     // Compute updated AST.<br>
     llvm::Optional<ParsedAST> NewAST;<br>
     {<br>
-      trace::Span Tracer(Ctx, "Build");<br>
+      trace::Span Tracer("Build");<br>
       SPAN_ATTACH(Tracer, "File", That->FileName);<br>
-      NewAST =<br>
-          ParsedAST::Build(Tracer.Ctx, std::move(CI), std::move(NewPreamble),<br>
-                           std::move(ContentsBuffer), PCHs, Inputs.FS);<br>
+      NewAST = ParsedAST::Build(std::move(CI)<wbr>, std::move(NewPreamble),<br>
+                                std::move(ContentsBuffer), PCHs, Inputs.FS);<br>
     }<br>
<br>
     if (NewAST) {<br>
       Diagnostics.insert(<wbr>Diagnostics.end(), NewAST->getDiagnostics().<wbr>begin(),<br>
                          NewAST->getDiagnostics().end()<wbr>);<br>
       if (That->ASTCallback)<br>
-        That->ASTCallback(Ctx, That->FileName, NewAST.getPointer());<br>
+        That->ASTCallback(That-><wbr>FileName, NewAST.getPointer());<br>
     } else {<br>
       // Don't report even Preamble diagnostics if we coulnd't build AST.<br>
       Diagnostics.clear();<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ClangdUnit.h?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h Wed Jan 31 05:40:48 2018<br>
@@ -10,7 +10,6 @@<br>
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>CLANGDUNIT_H<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>CLANGDUNIT_H<br>
<br>
-#include "Context.h"<br>
 #include "Function.h"<br>
 #include "Path.h"<br>
 #include "Protocol.h"<br>
@@ -71,7 +70,7 @@ public:<br>
   /// Attempts to run Clang and store parsed AST. If \p Preamble is non-null<br>
   /// it is reused during parsing.<br>
   static llvm::Optional<ParsedAST><br>
-  Build(const Context &Ctx, std::unique_ptr<clang::<wbr>CompilerInvocation> CI,<br>
+  Build(std::unique_ptr<clang::<wbr>CompilerInvocation> CI,<br>
         std::shared_ptr<const PreambleData> Preamble,<br>
         std::unique_ptr<llvm::<wbr>MemoryBuffer> Buffer,<br>
         std::shared_ptr<<wbr>PCHContainerOperations> PCHs,<br>
@@ -148,8 +147,7 @@ private:<br>
   mutable llvm::Optional<ParsedAST> AST;<br>
 };<br>
<br>
-using ASTParsedCallback =<br>
-    std::function<void(const Context &Ctx, PathRef Path, ParsedAST *)>;<br>
+using ASTParsedCallback = std::function<void(PathRef Path, ParsedAST *)>;<br>
<br>
 /// Manages resources, required by clangd. Allows to rebuild file with new<br>
 /// contents, and provides AST and Preamble for it.<br>
@@ -186,8 +184,7 @@ public:<br>
   /// Returns a list of diagnostics or a llvm::None, if another rebuild was<br>
   /// requested in parallel (effectively cancelling this rebuild) before<br>
   /// diagnostics were produced.<br>
-  llvm::Optional<std::vector<<wbr>DiagWithFixIts>> rebuild(const Context &Ctx,<br>
-                                                      ParseInputs &&Inputs);<br>
+  llvm::Optional<std::vector<<wbr>DiagWithFixIts>> rebuild(ParseInputs &&Inputs);<br>
<br>
   /// Schedule a rebuild and return a deferred computation that will finish the<br>
   /// rebuild, that can be called on a different thread.<br>
@@ -203,7 +200,7 @@ public:<br>
   /// The future to finish rebuild returns a list of diagnostics built during<br>
   /// reparse, or None, if another deferRebuild was called before this<br>
   /// rebuild was finished.<br>
-  UniqueFunction<llvm::Optional<<wbr>std::vector<DiagWithFixIts>>(<wbr>const Context &)><br>
+  UniqueFunction<llvm::Optional<<wbr>std::vector<DiagWithFixIts>>()<wbr>><br>
   deferRebuild(ParseInputs &&Inputs);<br>
<br>
   /// Returns a future to get the most fresh PreambleData for a file. The<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/CodeComplete.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/CodeComplete.cpp?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/CodeComplete.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/CodeComplete.cpp Wed Jan 31 05:40:48 2018<br>
@@ -633,12 +633,11 @@ struct SemaCompleteInput {<br>
<br>
 // Invokes Sema code completion on a file.<br>
 // Callback will be invoked once completion is done, but before cleaning up.<br>
-bool semaCodeComplete(const Context &Ctx,<br>
-                      std::unique_ptr<<wbr>CodeCompleteConsumer> Consumer,<br>
+bool semaCodeComplete(std::unique_<wbr>ptr<CodeCompleteConsumer> Consumer,<br>
                       const clang::CodeCompleteOptions &Options,<br>
                       const SemaCompleteInput &Input,<br>
                       llvm::function_ref<void()> Callback = nullptr) {<br>
-  auto Tracer = llvm::make_unique<trace::Span><wbr>(Ctx, "Sema completion");<br>
+  auto Tracer = llvm::make_unique<trace::Span><wbr>("Sema completion");<br>
   std::vector<const char *> ArgStrs;<br>
   for (const auto &S : Input.Command.CommandLine)<br>
     ArgStrs.push_back(S.c_str());<br>
@@ -690,13 +689,12 @@ bool semaCodeComplete(const Context &Ctx<br>
<br>
   SyntaxOnlyAction Action;<br>
   if (!Action.BeginSourceFile(*<wbr>Clang, Clang->getFrontendOpts().<wbr>Inputs[0])) {<br>
-    log(Ctx, "BeginSourceFile() failed when running codeComplete for " +<br>
-                 Input.FileName);<br>
+    log("BeginSourceFile() failed when running codeComplete for " +<br>
+        Input.FileName);<br>
     return false;<br>
   }<br>
   if (!Action.Execute()) {<br>
-    log(Ctx,<br>
-        "Execute() failed when running codeComplete for " + Input.FileName);<br>
+    log("Execute() failed when running codeComplete for " + Input.FileName);<br>
     return false;<br>
   }<br>
   Tracer.reset();<br>
@@ -704,7 +702,7 @@ bool semaCodeComplete(const Context &Ctx<br>
   if (Callback)<br>
     Callback();<br>
<br>
-  Tracer = llvm::make_unique<trace::Span><wbr>(Ctx, "Sema completion cleanup");<br>
+  Tracer = llvm::make_unique<trace::Span><wbr>("Sema completion cleanup");<br>
   Action.EndSourceFile();<br>
<br>
   return true;<br>
@@ -801,8 +799,6 @@ clang::CodeCompleteOptions CodeCompleteO<br>
 //     This score is combined with the result quality score for the final score.<br>
 //   - TopN determines the results with the best score.<br>
 class CodeCompleteFlow {<br>
-  trace::Span Tracer;<br>
-  const Context &Ctx;<br>
   const CodeCompleteOptions &Opts;<br>
   // Sema takes ownership of Recorder. Recorder is valid until Sema cleanup.<br>
   std::unique_ptr<<wbr>CompletionRecorder> RecorderOwner;<br>
@@ -813,21 +809,22 @@ class CodeCompleteFlow {<br>
<br>
 public:<br>
   // A CodeCompleteFlow object is only useful for calling run() exactly once.<br>
-  CodeCompleteFlow(const Context &Ctx, const CodeCompleteOptions &Opts)<br>
-      : Tracer(Ctx, "CodeCompleteFlow"), Ctx(Tracer.Ctx), Opts(Opts),<br>
-        RecorderOwner(new CompletionRecorder(Opts)), Recorder(*RecorderOwner) {}<br>
+  CodeCompleteFlow(const CodeCompleteOptions &Opts)<br>
+      : Opts(Opts), RecorderOwner(new CompletionRecorder(Opts)),<br>
+        Recorder(*RecorderOwner) {}<br>
<br>
   CompletionList run(const SemaCompleteInput &SemaCCInput) && {<br>
+    trace::Span Tracer("CodeCompleteFlow");<br>
     // We run Sema code completion first. It builds an AST and calculates:<br>
     //   - completion results based on the AST. These are saved for merging.<br>
     //   - partial identifier and context. We need these for the index query.<br>
     CompletionList Output;<br>
-    semaCodeComplete(Ctx, std::move(RecorderOwner), Opts.getClangCompleteOpts(),<br>
+    semaCodeComplete(std::move(<wbr>RecorderOwner), Opts.getClangCompleteOpts(),<br>
                      SemaCCInput, [&] {<br>
                        if (Recorder.CCSema)<br>
                          Output = runWithSema();<br>
                        else<br>
-                         log(Ctx, "Code complete: no Sema callback, 0 results");<br>
+                         log("Code complete: no Sema callback, 0 results");<br>
                      });<br>
<br>
     SPAN_ATTACH(Tracer, "sema_results", NSema);<br>
@@ -835,8 +832,7 @@ public:<br>
     SPAN_ATTACH(Tracer, "merged_results", NBoth);<br>
     SPAN_ATTACH(Tracer, "returned_results", Output.items.size());<br>
     SPAN_ATTACH(Tracer, "incomplete", Output.isIncomplete);<br>
-    log(Ctx,<br>
-        llvm::formatv("Code complete: {0} results from Sema, {1} from Index, "<br>
+    log(llvm::formatv("Code complete: {0} results from Sema, {1} from Index, "<br>
                       "{2} matched, {3} returned{4}.",<br>
                       NSema, NIndex, NBoth, Output.items.size(),<br>
                       Output.isIncomplete ? " (incomplete)" : ""));<br>
@@ -871,7 +867,7 @@ private:<br>
   SymbolSlab queryIndex() {<br>
     if (!Opts.Index || !allowIndex(Recorder.<wbr>CCContext.getKind()))<br>
       return SymbolSlab();<br>
-    trace::Span Tracer(Ctx, "Query index");<br>
+    trace::Span Tracer("Query index");<br>
     SPAN_ATTACH(Tracer, "limit", Opts.Limit);<br>
<br>
     SymbolSlab::Builder ResultsBuilder;<br>
@@ -882,15 +878,12 @@ private:<br>
     Req.Query = Filter->pattern();<br>
     Req.Scopes =<br>
         getQueryScopes(Recorder.<wbr>CCContext, Recorder.CCSema-><wbr>getSourceManager());<br>
-    log(Tracer.Ctx,<br>
-        llvm::formatv("Code complete: fuzzyFind(\"{0}\", Scopes: [{1}]",<br>
+    log(llvm::formatv("Code complete: fuzzyFind(\"{0}\", scopes=[{1}])",<br>
                       Req.Query,<br>
                       llvm::join(Req.Scopes.begin(), Req.Scopes.end(), ",")));<br>
     // Run the query against the index.<br>
-    Incomplete |=<br>
-        !Opts.Index->fuzzyFind(Tracer.<wbr>Ctx, Req, [&](const Symbol &Sym) {<br>
-          ResultsBuilder.insert(Sym);<br>
-        });<br>
+    Incomplete |= !Opts.Index->fuzzyFind(<br>
+        Req, [&](const Symbol &Sym) { ResultsBuilder.insert(Sym); });<br>
     return std::move(ResultsBuilder).<wbr>build();<br>
   }<br>
<br>
@@ -899,7 +892,7 @@ private:<br>
   std::vector<std::pair<<wbr>CompletionCandidate, CompletionItemScores>><br>
   mergeResults(const std::vector<<wbr>CodeCompletionResult> &SemaResults,<br>
                const SymbolSlab &IndexResults) {<br>
-    trace::Span Tracer(Ctx, "Merge and score results");<br>
+    trace::Span Tracer("Merge and score results");<br>
     // We only keep the best N results at any time, in "native" format.<br>
     TopN Top(Opts.Limit == 0 ? TopN::Unbounded : Opts.Limit);<br>
     llvm::DenseSet<const Symbol *> UsedIndexResults;<br>
@@ -960,18 +953,18 @@ private:<br>
   }<br>
 };<br>
<br>
-CompletionList codeComplete(const Context &Ctx, PathRef FileName,<br>
+CompletionList codeComplete(PathRef FileName,<br>
                             const tooling::CompileCommand &Command,<br>
                             PrecompiledPreamble const *Preamble,<br>
                             StringRef Contents, Position Pos,<br>
                             IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS,<br>
                             std::shared_ptr<<wbr>PCHContainerOperations> PCHs,<br>
                             CodeCompleteOptions Opts) {<br>
-  return CodeCompleteFlow(Ctx, Opts).run(<br>
+  return CodeCompleteFlow(Opts).run(<br>
       {FileName, Command, Preamble, Contents, Pos, VFS, PCHs});<br>
 }<br>
<br>
-SignatureHelp signatureHelp(const Context &Ctx, PathRef FileName,<br>
+SignatureHelp signatureHelp(PathRef FileName,<br>
                             const tooling::CompileCommand &Command,<br>
                             PrecompiledPreamble const *Preamble,<br>
                             StringRef Contents, Position Pos,<br>
@@ -983,10 +976,10 @@ SignatureHelp signatureHelp(const Contex<br>
   Options.IncludeMacros = false;<br>
   Options.IncludeCodePatterns = false;<br>
   Options.IncludeBriefComments = true;<br>
-  semaCodeComplete(<br>
-      Ctx, llvm::make_unique<<wbr>SignatureHelpCollector>(<wbr>Options, Result), Options,<br>
-      {FileName, Command, Preamble, Contents, Pos, std::move(VFS),<br>
-       std::move(PCHs)});<br>
+  semaCodeComplete(llvm::make_<wbr>unique<SignatureHelpCollector><wbr>(Options, Result),<br>
+                   Options,<br>
+                   {FileName, Command, Preamble, Contents, Pos, std::move(VFS),<br>
+                    std::move(PCHs)});<br>
   return Result;<br>
 }<br>
<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/CodeComplete.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/CodeComplete.h?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/CodeComplete.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/CodeComplete.h Wed Jan 31 05:40:48 2018<br>
@@ -15,7 +15,6 @@<br>
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>CODECOMPLETE_H<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>CODECOMPLETE_H<br>
<br>
-#include "Context.h"<br>
 #include "Logger.h"<br>
 #include "Path.h"<br>
 #include "Protocol.h"<br>
@@ -67,7 +66,7 @@ struct CodeCompleteOptions {<br>
 };<br>
<br>
 /// Get code completions at a specified \p Pos in \p FileName.<br>
-CompletionList codeComplete(const Context &Ctx, PathRef FileName,<br>
+CompletionList codeComplete(PathRef FileName,<br>
                             const tooling::CompileCommand &Command,<br>
                             PrecompiledPreamble const *Preamble,<br>
                             StringRef Contents, Position Pos,<br>
@@ -76,7 +75,7 @@ CompletionList codeComplete(const Contex<br>
                             CodeCompleteOptions Opts);<br>
<br>
 /// Get signature help at a specified \p Pos in \p FileName.<br>
-SignatureHelp signatureHelp(const Context &Ctx, PathRef FileName,<br>
+SignatureHelp signatureHelp(PathRef FileName,<br>
                             const tooling::CompileCommand &Command,<br>
                             PrecompiledPreamble const *Preamble,<br>
                             StringRef Contents, Position Pos,<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Context.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Context.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Context.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Context.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Context.cpp Wed Jan 31 05:40:48 2018<br>
@@ -20,5 +20,19 @@ Context::Context(std::shared_<wbr>ptr<const D<br>
<br>
 Context Context::clone() const { return Context(DataPtr); }<br>
<br>
+// The thread-local Context is scoped in a function to avoid<br>
+// initialization-order issues. It's created when first needed.<br>
+static Context &currentContext() {<br>
+  static thread_local Context C = Context::empty();<br>
+  return C;<br>
+}<br>
+<br>
+const Context &Context::current() { return currentContext(); }<br>
+<br>
+Context Context::swapCurrent(Context Replacement) {<br>
+  std::swap(Replacement, currentContext());<br>
+  return Replacement;<br>
+}<br>
+<br>
 } // namespace clangd<br>
 } // namespace clang<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Context.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Context.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Context.h?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Context.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Context.h Wed Jan 31 05:40:48 2018<br>
@@ -16,15 +16,28 @@<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>CONTEXT_H_<br>
<br>
 #include "llvm/ADT/STLExtras.h"<br>
+#include "llvm/Support/Compiler.h"<br>
 #include <memory><br>
 #include <type_traits><br>
<br>
 namespace clang {<br>
 namespace clangd {<br>
<br>
-/// A key for a value of type \p Type, stored inside a context. Keys are<br>
-/// non-movable and non-copyable. See documentation of the Context class for<br>
-/// more details and usage examples.<br>
+/// Values in a Context are indexed by typed keys.<br>
+/// Key<T> serves two purposes:<br>
+///   - it provides a lookup key for the context (each Key is unique),<br>
+///   - it makes lookup type-safe: a Key<T> can only map to a T (or nothing).<br>
+///<br>
+/// Example:<br>
+///    Key<int> RequestID;<br>
+///    Key<int> Version;<br>
+///<br>
+///    Context Ctx = Context::empty().derive(<wbr>RequestID, 10).derive(Version, 3);<br>
+///    assert(*Ctx.get(RequestID) == 10);<br>
+///    assert(*Ctx.get(Version) == 3);<br>
+///<br>
+/// Keys are typically used across multiple functions, so most of the time you<br>
+/// would want to make them static class members or global variables.<br>
 template <class Type> class Key {<br>
 public:<br>
   static_assert(!std::is_<wbr>reference<Type>::value,<br>
@@ -45,53 +58,24 @@ public:<br>
 /// Conceptually, a context is a heterogeneous map<Key<T>, T>. Each key has<br>
 /// an associated value type, which allows the map to be typesafe.<br>
 ///<br>
+/// There is an "ambient" context for each thread, Context::current().<br>
+/// Most functions should read from this, and use WithContextValue or<br>
+/// WithContext to extend or replace the context within a block scope.<br>
+/// Only code dealing with threads and extension points should need to use<br>
+/// other Context objects.<br>
+///<br>
 /// You can't add data to an existing context, instead you create a new<br>
 /// immutable context derived from it with extra data added. When you retrieve<br>
 /// data, the context will walk up the parent chain until the key is found.<br>
-///<br>
-/// Contexts should be:<br>
-///  - passed by reference when calling synchronous functions<br>
-///  - passed by value (move) when calling asynchronous functions. The result<br>
-///    callback of async operations will receive the context again.<br>
-///  - cloned only when 'forking' an asynchronous computation that we don't wait<br>
-///    for.<br>
-///<br>
-/// Copy operations for this class are deleted, use an explicit clone() method<br>
-/// when you need a copy of the context instead.<br>
-///<br>
-/// To derive a child context use derive() function, e.g.<br>
-///     Context ChildCtx = ParentCtx.derive(RequestIdKey, 123);<br>
-///<br>
-/// To create a new root context, derive() from empty Context.<br>
-/// e.g.:<br>
-///     Context Ctx = Context::empty().derive(<wbr>RequestIdKey, 123);<br>
-///<br>
-/// Values in the context are indexed by typed keys (instances of Key<T> class).<br>
-/// Key<T> serves two purposes:<br>
-///   - it provides a lookup key for the context (each instance of a key is<br>
-///   unique),<br>
-///   - it keeps the type information about the value stored in the context map<br>
-///   in the template arguments.<br>
-/// This provides a type-safe interface to store and access values of multiple<br>
-/// types inside a single context.<br>
-/// For example,<br>
-///    Key<int> RequestID;<br>
-///    Key<int> Version;<br>
-///<br>
-///    Context Ctx = Context::empty().derive(<wbr>RequestID, 10).derive(Version, 3);<br>
-///    assert(*Ctx.get(RequestID) == 10);<br>
-///    assert(*Ctx.get(Version) == 3);<br>
-///<br>
-/// Keys are typically used across multiple functions, so most of the time you<br>
-/// would want to make them static class members or global variables.<br>
-///<br>
-/// FIXME: Rather than manual plumbing, pass Context using thread-local storage<br>
-/// by default, and make thread boundaries deal with propagation explicitly.<br>
 class Context {<br>
 public:<br>
-  /// Returns an empty context that contains no data. Useful for calling<br>
-  /// functions that require a context when no explicit context is available.<br>
+  /// Returns an empty root context that contains no data.<br>
   static Context empty();<br>
+  /// Returns the context for the current thread, creating it if needed.<br>
+  static const Context &current();<br>
+  // Sets the current() context to Replacement, and returns the old context.<br>
+  // Prefer to use WithContext or WithContextValue to do this safely.<br>
+  static Context swapCurrent(Context Replacement);<br>
<br>
 private:<br>
   struct Data;<br>
@@ -103,7 +87,8 @@ public:<br>
   /// (arguments of std::future<> must be default-construcitble in MSVC).<br>
   Context() = default;<br>
<br>
-  /// Move-only.<br>
+  /// Copy operations for this class are deleted, use an explicit clone() method<br>
+  /// when you need a copy of the context instead.<br>
   Context(Context const &) = delete;<br>
   Context &operator=(const Context &) = delete;<br>
<br>
@@ -131,9 +116,8 @@ public:<br>
   }<br>
<br>
   /// Derives a child context<br>
-  /// It is safe to move or destroy a parent context after calling derive() from<br>
-  /// it. The child context will continue to have access to the data stored in<br>
-  /// the parent context.<br>
+  /// It is safe to move or destroy a parent context after calling derive().<br>
+  /// The child will keep its parent alive, and its data remains accessible.<br>
   template <class Type><br>
   Context derive(const Key<Type> &Key,<br>
                  typename std::decay<Type>::type Value) const & {<br>
@@ -198,7 +182,40 @@ private:<br>
   };<br>
<br>
   std::shared_ptr<const Data> DataPtr;<br>
-}; // namespace clangd<br>
+};<br>
+<br>
+/// WithContext replaces Context::current() with a provided scope.<br>
+/// When the WithContext is destroyed, the original scope is restored.<br>
+/// For extending the current context with new value, prefer WithContextValue.<br>
+class LLVM_NODISCARD WithContext {<br>
+public:<br>
+  WithContext(Context C) : Restore(Context::swapCurrent(<wbr>std::move(C))) {}<br>
+  ~WithContext() { Context::swapCurrent(std::<wbr>move(Restore)); }<br>
+  WithContext(const WithContext &) = delete;<br>
+  WithContext &operator=(const WithContext &) = delete;<br>
+  WithContext(WithContext &&) = delete;<br>
+  WithContext &operator=(WithContext &&) = delete;<br>
+<br>
+private:<br>
+  Context Restore;<br>
+};<br>
+<br>
+/// WithContextValue extends Context::current() with a single value.<br>
+/// When the WithContextValue is destroyed, the original scope is restored.<br>
+class LLVM_NODISCARD WithContextValue {<br>
+public:<br>
+  template <typename T><br>
+  WithContextValue(const Key<T> &K, typename std::decay<T>::type V)<br>
+      : Restore(Context::current().<wbr>derive(K, std::move(V))) {}<br>
+<br>
+  // Anonymous values can be used for the destructor side-effect.<br>
+  template <typename T><br>
+  WithContextValue(T &&V)<br>
+      : Restore(Context::current().<wbr>derive(std::forward<T>(V))) {}<br>
+<br>
+private:<br>
+  WithContext Restore;<br>
+};<br>
<br>
 } // namespace clangd<br>
 } // namespace clang<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/<wbr>GlobalCompilationDatabase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/GlobalCompilationDatabase.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/<wbr>GlobalCompilationDatabase.cpp?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/<wbr>GlobalCompilationDatabase.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/<wbr>GlobalCompilationDatabase.cpp Wed Jan 31 05:40:48 2018<br>
@@ -38,8 +38,7 @@ DirectoryBasedGlobalCompilatio<wbr>nDatabase:<br>
       return std::move(Candidates.front());<br>
     }<br>
   } else {<br>
-    log(Context::empty(), // FIXME(ibiryukov): pass a proper Context here.<br>
-        "Failed to find compilation database for " + Twine(File));<br>
+    log("Failed to find compilation database for " + Twine(File));<br>
   }<br>
   return llvm::None;<br>
 }<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/<wbr>JSONRPCDispatcher.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.cpp Wed Jan 31 05:40:48 2018<br>
@@ -34,14 +34,14 @@ class RequestSpan {<br>
 public:<br>
   // Return a context that's aware of the enclosing request, identified by Span.<br>
   static Context stash(const trace::Span &Span) {<br>
-    return Span.Ctx.derive(RSKey, std::unique_ptr<RequestSpan>(<br>
-                                                 new RequestSpan(Span.Args)));<br>
+    return Context::current().derive(<br>
+        RSKey, std::unique_ptr<RequestSpan>(<wbr>new RequestSpan(Span.Args)));<br>
   }<br>
<br>
   // If there's an enclosing request and the tracer is interested, calls \p F<br>
   // with a json::obj where request info can be added.<br>
-  template <typename Func> static void attach(const Context &Ctx, Func &&F) {<br>
-    auto *RequestArgs = Ctx.get(RSKey);<br>
+  template <typename Func> static void attach(Func &&F) {<br>
+    auto *RequestArgs = Context::current().get(RSKey);<br>
     if (!RequestArgs || !*RequestArgs || !(*RequestArgs)->Args)<br>
       return;<br>
     std::lock_guard<std::mutex> Lock((*RequestArgs)->Mu);<br>
@@ -70,8 +70,8 @@ void JSONOutput::writeMessage(const json<br>
   Outs.flush();<br>
 }<br>
<br>
-void JSONOutput::log(const Context &Ctx, const Twine &Message) {<br>
-  trace::log(Ctx, Message);<br>
+void JSONOutput::log(const Twine &Message) {<br>
+  trace::log(Message);<br>
   std::lock_guard<std::mutex> Guard(StreamMutex);<br>
   Logs << Message << '\n';<br>
   Logs.flush();<br>
@@ -85,16 +85,15 @@ void JSONOutput::mirrorInput(const Twine<br>
   InputMirror->flush();<br>
 }<br>
<br>
-void clangd::reply(const Context &Ctx, json::Expr &&Result) {<br>
-  auto ID = Ctx.get(RequestID);<br>
+void clangd::reply(json::Expr &&Result) {<br>
+  auto ID = Context::current().get(<wbr>RequestID);<br>
   if (!ID) {<br>
-    log(Ctx, "Attempted to reply to a notification!");<br>
+    log("Attempted to reply to a notification!");<br>
     return;<br>
   }<br>
-<br>
-  RequestSpan::attach(Ctx, [&](json::obj &Args) { Args["Reply"] = Result; });<br>
-<br>
-  Ctx.getExisting(RequestOut)<br>
+  RequestSpan::attach([&](json::<wbr>obj &Args) { Args["Reply"] = Result; });<br>
+  Context::current()<br>
+      .getExisting(RequestOut)<br>
       ->writeMessage(json::obj{<br>
           {"jsonrpc", "2.0"},<br>
           {"id", *ID},<br>
@@ -102,16 +101,16 @@ void clangd::reply(const Context &Ctx, j<br>
       });<br>
 }<br>
<br>
-void clangd::replyError(const Context &Ctx, ErrorCode code,<br>
-                        const llvm::StringRef &Message) {<br>
-  log(Ctx, "Error " + Twine(static_cast<int>(code)) + ": " + Message);<br>
-  RequestSpan::attach(Ctx, [&](json::obj &Args) {<br>
+void clangd::replyError(ErrorCode code, const llvm::StringRef &Message) {<br>
+  log("Error " + Twine(static_cast<int>(code)) + ": " + Message);<br>
+  RequestSpan::attach([&](json::<wbr>obj &Args) {<br>
     Args["Error"] =<br>
         json::obj{{"code", static_cast<int>(code)}, {"message", Message.str()}};<br>
   });<br>
<br>
-  if (auto ID = Ctx.get(RequestID)) {<br>
-    Ctx.getExisting(RequestOut)<br>
+  if (auto ID = Context::current().get(<wbr>RequestID)) {<br>
+    Context::current()<br>
+        .getExisting(RequestOut)<br>
         ->writeMessage(json::obj{<br>
             {"jsonrpc", "2.0"},<br>
             {"id", *ID},<br>
@@ -121,13 +120,14 @@ void clangd::replyError(const Context &C<br>
   }<br>
 }<br>
<br>
-void clangd::call(const Context &Ctx, StringRef Method, json::Expr &&Params) {<br>
+void clangd::call(StringRef Method, json::Expr &&Params) {<br>
   // FIXME: Generate/Increment IDs for every request so that we can get proper<br>
   // replies once we need to.<br>
-  RequestSpan::attach(Ctx, [&](json::obj &Args) {<br>
+  RequestSpan::attach([&](json::<wbr>obj &Args) {<br>
     Args["Call"] = json::obj{{"method", Method.str()}, {"params", Params}};<br>
   });<br>
-  Ctx.getExisting(RequestOut)<br>
+  Context::current()<br>
+      .getExisting(RequestOut)<br>
       ->writeMessage(json::obj{<br>
           {"jsonrpc", "2.0"},<br>
           {"id", 1},<br>
@@ -163,18 +163,20 @@ bool JSONRPCDispatcher::call(const json:<br>
   auto &Handler = I != Handlers.end() ? I->second : UnknownHandler;<br>
<br>
   // Create a Context that contains request information.<br>
-  auto Ctx = Context::empty().derive(<wbr>RequestOut, &Out);<br>
+  WithContextValue WithRequestOut(RequestOut, &Out);<br>
+  llvm::Optional<<wbr>WithContextValue> WithID;<br>
   if (ID)<br>
-    Ctx = std::move(Ctx).derive(<wbr>RequestID, *ID);<br>
+    WithID.emplace(RequestID, *ID);<br>
<br>
   // Create a tracing Span covering the whole request lifetime.<br>
-  trace::Span Tracer(Ctx, *Method);<br>
+  trace::Span Tracer(*Method);<br>
   if (ID)<br>
     SPAN_ATTACH(Tracer, "ID", *ID);<br>
   SPAN_ATTACH(Tracer, "Params", Params);<br>
<br>
   // Stash a reference to the span args, so later calls can add metadata.<br>
-  Handler(RequestSpan::stash(<wbr>Tracer), std::move(Params));<br>
+  WithContext WithRequestSpan(RequestSpan::<wbr>stash(Tracer));<br>
+  Handler(std::move(Params));<br>
   return true;<br>
 }<br>
<br>
@@ -216,10 +218,9 @@ void clangd::runLanguageServerLoop(<wbr>std::<br>
       // The end of headers is signified by an empty line.<br>
       if (LineRef.consume_front("<wbr>Content-Length: ")) {<br>
         if (ContentLength != 0) {<br>
-          log(Context::empty(),<br>
-              "Warning: Duplicate Content-Length header received. "<br>
+          log("Warning: Duplicate Content-Length header received. "<br>
               "The previous value for this message (" +<br>
-                  llvm::Twine(ContentLength) + ") was ignored.\n");<br>
+              llvm::Twine(ContentLength) + ") was ignored.\n");<br>
         }<br>
<br>
         llvm::getAsUnsignedInteger(<wbr>LineRef.trim(), 0, ContentLength);<br>
@@ -238,8 +239,8 @@ void clangd::runLanguageServerLoop(<wbr>std::<br>
     // and we don't want to crash downstream because of it.<br>
     if (ContentLength > 1 << 30) { // 1024M<br>
       In.ignore(ContentLength);<br>
-      log(Context::empty(), "Skipped overly large message of " +<br>
-                                Twine(ContentLength) + " bytes.\n");<br>
+      log("Skipped overly large message of " + Twine(ContentLength) +<br>
+          " bytes.\n");<br>
       continue;<br>
     }<br>
<br>
@@ -253,9 +254,8 @@ void clangd::runLanguageServerLoop(<wbr>std::<br>
         // If the stream is aborted before we read ContentLength bytes, In<br>
         // will have eofbit and failbit set.<br>
         if (!In) {<br>
-          log(Context::empty(),<br>
-              "Input was aborted. Read only " + llvm::Twine(In.gcount()) +<br>
-                  " bytes of expected " + llvm::Twine(ContentLength) + ".\n");<br>
+          log("Input was aborted. Read only " + llvm::Twine(In.gcount()) +<br>
+              " bytes of expected " + llvm::Twine(ContentLength) + ".\n");<br>
           break;<br>
         }<br>
<br>
@@ -264,24 +264,22 @@ void clangd::runLanguageServerLoop(<wbr>std::<br>
<br>
       if (auto Doc = json::parse(JSONRef)) {<br>
         // Log the formatted message.<br>
-        log(Context::empty(),<br>
-            llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc));<br>
+        log(llvm::formatv(Out.Pretty ? "<-- {0:2}\n" : "<-- {0}\n", *Doc));<br>
         // Finally, execute the action for this JSON message.<br>
         if (!Dispatcher.call(*Doc, Out))<br>
-          log(Context::empty(), "JSON dispatch failed!\n");<br>
+          log("JSON dispatch failed!\n");<br>
       } else {<br>
         // Parse error. Log the raw message.<br>
-        log(Context::empty(), "<-- " + JSONRef + "\n");<br>
-        log(Context::empty(), llvm::Twine("JSON parse error: ") +<br>
-                                  llvm::toString(Doc.takeError()<wbr>) + "\n");<br>
+        log("<-- " + JSONRef + "\n");<br>
+        log(llvm::Twine("JSON parse error: ") +<br>
+            llvm::toString(Doc.takeError()<wbr>) + "\n");<br>
       }<br>
<br>
       // If we're done, exit the loop.<br>
       if (IsDone)<br>
         break;<br>
     } else {<br>
-      log(Context::empty(),<br>
-          "Warning: Missing Content-Length header, or message has zero "<br>
+      log("Warning: Missing Content-Length header, or message has zero "<br>
           "length.\n");<br>
     }<br>
   }<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/<wbr>JSONRPCDispatcher.h?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/JSONRPCDispatcher.h Wed Jan 31 05:40:48 2018<br>
@@ -10,7 +10,6 @@<br>
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>JSONRPCDISPATCHER_H<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>JSONRPCDISPATCHER_H<br>
<br>
-#include "Context.h"<br>
 #include "JSONExpr.h"<br>
 #include "Logger.h"<br>
 #include "Protocol.h"<br>
@@ -38,7 +37,7 @@ public:<br>
   void writeMessage(const json::Expr &Result);<br>
<br>
   /// Write a line to the logging stream.<br>
-  void log(const Context &Ctx, const Twine &Message) override;<br>
+  void log(const Twine &Message) override;<br>
<br>
   /// Mirror \p Message into InputMirror stream. Does nothing if InputMirror is<br>
   /// null.<br>
@@ -56,23 +55,22 @@ private:<br>
   std::mutex StreamMutex;<br>
 };<br>
<br>
-/// Sends a successful reply. \p Ctx must either be the Context accepted by<br>
-/// JSONRPCDispatcher::Handler or be derived from it.<br>
-void reply(const Context &Ctx, json::Expr &&Result);<br>
-/// Sends an error response to the client, and logs it. \p Ctx must either be<br>
-/// the Context accepted by JSONRPCDispatcher::Handler or be derived from it.<br>
-void replyError(const Context &Ctx, ErrorCode code,<br>
-                const llvm::StringRef &Message);<br>
-/// Sends a request to the client. \p Ctx must either be the Context accepted by<br>
-/// JSONRPCDispatcher::Handler or be derived from it.<br>
-void call(const Context &Ctx, llvm::StringRef Method, json::Expr &&Params);<br>
+/// Sends a successful reply.<br>
+/// Current context must derive from JSONRPCDispatcher::Handler.<br>
+void reply(json::Expr &&Result);<br>
+/// Sends an error response to the client, and logs it.<br>
+/// Current context must derive from JSONRPCDispatcher::Handler.<br>
+void replyError(ErrorCode code, const llvm::StringRef &Message);<br>
+/// Sends a request to the client.<br>
+/// Current context must derive from JSONRPCDispatcher::Handler.<br>
+void call(llvm::StringRef Method, json::Expr &&Params);<br>
<br>
 /// Main JSONRPC entry point. This parses the JSONRPC "header" and calls the<br>
 /// registered Handler for the method received.<br>
 class JSONRPCDispatcher {<br>
 public:<br>
   // A handler responds to requests for a particular method name.<br>
-  using Handler = std::function<void(Context, const json::Expr &)>;<br>
+  using Handler = std::function<void(const json::Expr &)>;<br>
<br>
   /// Create a new JSONRPCDispatcher. UnknownHandler is called when an unknown<br>
   /// method is received.<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Logger.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Logger.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Logger.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Logger.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Logger.cpp Wed Jan 31 05:40:48 2018<br>
@@ -25,9 +25,9 @@ LoggingSession::<wbr>LoggingSession(clangd::L<br>
<br>
 LoggingSession::~<wbr>LoggingSession() { L = nullptr; }<br>
<br>
-void log(const Context &Ctx, const llvm::Twine &Message) {<br>
+void log(const llvm::Twine &Message) {<br>
   if (L)<br>
-    L->log(Ctx, Message);<br>
+    L->log(Message);<br>
   else {<br>
     static std::mutex Mu;<br>
     std::lock_guard<std::mutex> Guard(Mu);<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Logger.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Logger.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Logger.h?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Logger.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Logger.h Wed Jan 31 05:40:48 2018<br>
@@ -10,7 +10,6 @@<br>
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>LOGGER_H<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>LOGGER_H<br>
<br>
-#include "Context.h"<br>
 #include "llvm/ADT/Twine.h"<br>
<br>
 namespace clang {<br>
@@ -19,7 +18,7 @@ namespace clangd {<br>
 /// Main logging function.<br>
 /// Logs messages to a global logger, which can be set up by LoggingSesssion.<br>
 /// If no logger is registered, writes to llvm::errs().<br>
-void log(const Context &Ctx, const llvm::Twine &Message);<br>
+void log(const llvm::Twine &Message);<br>
<br>
 /// Interface to allow custom logging in clangd.<br>
 class Logger {<br>
@@ -27,7 +26,7 @@ public:<br>
   virtual ~Logger() = default;<br>
<br>
   /// Implementations of this method must be thread-safe.<br>
-  virtual void log(const Context &Ctx, const llvm::Twine &Message) = 0;<br>
+  virtual void log(const llvm::Twine &Message) = 0;<br>
 };<br>
<br>
 /// Only one LoggingSession can be active at a time.<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Protocol.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Protocol.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Protocol.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Protocol.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Protocol.cpp Wed Jan 31 05:40:48 2018<br>
@@ -28,18 +28,16 @@ bool fromJSON(const json::Expr &E, URIFo<br>
   if (auto S = E.asString()) {<br>
     auto U = URI::parse(*S);<br>
     if (!U) {<br>
-      log(Context::empty(),<br>
-          "Failed to parse URI " + *S + ": " + llvm::toString(U.takeError()))<wbr>;<br>
+      log("Failed to parse URI " + *S + ": " + llvm::toString(U.takeError()))<wbr>;<br>
       return false;<br>
     }<br>
     if (U->scheme() != "file") {<br>
-      log(Context::empty(),<br>
-          "Clangd only supports 'file' URI scheme for workspace files: " + *S);<br>
+      log("Clangd only supports 'file' URI scheme for workspace files: " + *S);<br>
       return false;<br>
     }<br>
     auto Path = URI::resolve(*U);<br>
     if (!Path) {<br>
-      log(Context::empty(), llvm::toString(Path.takeError(<wbr>)));<br>
+      log(llvm::toString(Path.<wbr>takeError()));<br>
       return false;<br>
     }<br>
     R.file = *Path;<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ProtocolHandlers.<wbr>cpp?rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.cpp Wed Jan 31 05:40:48 2018<br>
@@ -24,19 +24,17 @@ namespace {<br>
 // FooParams should have a fromJSON function.<br>
 struct HandlerRegisterer {<br>
   template <typename Param><br>
-  void operator()(StringRef Method,<br>
-                  void (ProtocolCallbacks::*Handler)(<wbr>Context, Param)) {<br>
+  void operator()(StringRef Method, void (ProtocolCallbacks::*Handler)(<wbr>Param)) {<br>
     // Capture pointers by value, as the lambda will outlive this object.<br>
     auto *Callbacks = this->Callbacks;<br>
-    Dispatcher.registerHandler(<br>
-        Method, [=](Context C, const json::Expr &RawParams) {<br>
-          typename std::remove_reference<Param>::<wbr>type P;<br>
-          if (fromJSON(RawParams, P)) {<br>
-            (Callbacks->*Handler)(std::<wbr>move(C), P);<br>
-          } else {<br>
-            log(C, "Failed to decode " + Method + " request.");<br>
-          }<br>
-        });<br>
+    Dispatcher.registerHandler(<wbr>Method, [=](const json::Expr &RawParams) {<br>
+      typename std::remove_reference<Param>::<wbr>type P;<br>
+      if (fromJSON(RawParams, P)) {<br>
+        (Callbacks->*Handler)(P);<br>
+      } else {<br>
+        log("Failed to decode " + Method + " request.");<br>
+      }<br>
+    });<br>
   }<br>
<br>
   JSONRPCDispatcher &Dispatcher;<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/ProtocolHandlers.<wbr>h?rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/ProtocolHandlers.h Wed Jan 31 05:40:48 2018<br>
@@ -29,34 +29,28 @@ namespace clangd {<br>
 // The interface implemented by ClangLSPServer to handle incoming requests.<br>
 class ProtocolCallbacks {<br>
 public:<br>
-  // FIXME(ibiryukov): remove this typedef, inline its usages.<br>
-  using Ctx = Context;<br>
   virtual ~ProtocolCallbacks() = default;<br>
<br>
-  virtual void onInitialize(Ctx C, InitializeParams &Params) = 0;<br>
-  virtual void onShutdown(Ctx C, ShutdownParams &Params) = 0;<br>
-  virtual void onExit(Ctx C, ExitParams &Params) = 0;<br>
-  virtual void onDocumentDidOpen(Ctx C, DidOpenTextDocumentParams &Params) = 0;<br>
-  virtual void onDocumentDidChange(Ctx C,<br>
-                                   DidChangeTextDocumentParams &Params) = 0;<br>
-  virtual void onDocumentDidClose(Ctx C,<br>
-                                  DidCloseTextDocumentParams &Params) = 0;<br>
-  virtual void onDocumentFormatting(Ctx C,<br>
-                                    DocumentFormattingParams &Params) = 0;<br>
+  virtual void onInitialize(InitializeParams &Params) = 0;<br>
+  virtual void onShutdown(ShutdownParams &Params) = 0;<br>
+  virtual void onExit(ExitParams &Params) = 0;<br>
+  virtual void onDocumentDidOpen(<wbr>DidOpenTextDocumentParams &Params) = 0;<br>
+  virtual void onDocumentDidChange(<wbr>DidChangeTextDocumentParams &Params) = 0;<br>
+  virtual void onDocumentDidClose(<wbr>DidCloseTextDocumentParams &Params) = 0;<br>
+  virtual void onDocumentFormatting(<wbr>DocumentFormattingParams &Params) = 0;<br>
   virtual void<br>
-  onDocumentOnTypeFormatting(Ctx C, DocumentOnTypeFormattingParams &Params) = 0;<br>
+  onDocumentOnTypeFormatting(<wbr>DocumentOnTypeFormattingParams &Params) = 0;<br>
   virtual void<br>
-  onDocumentRangeFormatting(Ctx C, DocumentRangeFormattingParams &Params) = 0;<br>
-  virtual void onCodeAction(Ctx C, CodeActionParams &Params) = 0;<br>
-  virtual void onCompletion(Ctx C, TextDocumentPositionParams &Params) = 0;<br>
-  virtual void onSignatureHelp(Ctx C, TextDocumentPositionParams &Params) = 0;<br>
-  virtual void onGoToDefinition(Ctx C, TextDocumentPositionParams &Params) = 0;<br>
-  virtual void onSwitchSourceHeader(Ctx C, TextDocumentIdentifier &Params) = 0;<br>
-  virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) = 0;<br>
-  virtual void onCommand(Ctx C, ExecuteCommandParams &Params) = 0;<br>
-  virtual void onRename(Ctx C, RenameParams &Parames) = 0;<br>
-  virtual void onDocumentHighlight(Ctx C,<br>
-                                   TextDocumentPositionParams &Params) = 0;<br>
+  onDocumentRangeFormatting(<wbr>DocumentRangeFormattingParams &Params) = 0;<br>
+  virtual void onCodeAction(CodeActionParams &Params) = 0;<br>
+  virtual void onCompletion(<wbr>TextDocumentPositionParams &Params) = 0;<br>
+  virtual void onSignatureHelp(<wbr>TextDocumentPositionParams &Params) = 0;<br>
+  virtual void onGoToDefinition(<wbr>TextDocumentPositionParams &Params) = 0;<br>
+  virtual void onSwitchSourceHeader(<wbr>TextDocumentIdentifier &Params) = 0;<br>
+  virtual void onFileEvent(<wbr>DidChangeWatchedFilesParams &Params) = 0;<br>
+  virtual void onCommand(ExecuteCommandParams &Params) = 0;<br>
+  virtual void onRename(RenameParams &Parames) = 0;<br>
+  virtual void onDocumentHighlight(<wbr>TextDocumentPositionParams &Params) = 0;<br>
 };<br>
<br>
 void registerCallbackHandlers(<wbr>JSONRPCDispatcher &Dispatcher, JSONOutput &Out,<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/TUScheduler.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/TUScheduler.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/TUScheduler.cpp?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/TUScheduler.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/TUScheduler.cpp Wed Jan 31 05:40:48 2018<br>
@@ -23,9 +23,8 @@ TUScheduler::TUScheduler(<wbr>unsigned AsyncT<br>
       Threads(AsyncThreadsCount) {}<br>
<br>
 void TUScheduler::update(<br>
-    Context Ctx, PathRef File, ParseInputs Inputs,<br>
-    UniqueFunction<void(Context Ctx,<br>
-                        llvm::Optional<std::vector<<wbr>DiagWithFixIts>>)><br>
+    PathRef File, ParseInputs Inputs,<br>
+    UniqueFunction<void(llvm::<wbr>Optional<std::vector<<wbr>DiagWithFixIts>>)><br>
         OnUpdated) {<br>
   CachedInputs[File] = Inputs;<br>
<br>
@@ -33,12 +32,12 @@ void TUScheduler::update(<br>
   auto DeferredRebuild = Resources->deferRebuild(std::<wbr>move(Inputs));<br>
<br>
   Threads.addToFront(<br>
-      [](Context Ctx, decltype(OnUpdated) OnUpdated,<br>
+      [](decltype(OnUpdated) OnUpdated,<br>
          decltype(DeferredRebuild) DeferredRebuild) {<br>
-        auto Diags = DeferredRebuild(Ctx);<br>
-        OnUpdated(std::move(Ctx), Diags);<br>
+        auto Diags = DeferredRebuild();<br>
+        OnUpdated(Diags);<br>
       },<br>
-      std::move(Ctx), std::move(OnUpdated), std::move(DeferredRebuild));<br>
+      std::move(OnUpdated), std::move(DeferredRebuild));<br>
 }<br>
<br>
 void TUScheduler::remove(PathRef File,<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/TUScheduler.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/TUScheduler.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/TUScheduler.h?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/TUScheduler.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/TUScheduler.h Wed Jan 31 05:40:48 2018<br>
@@ -50,10 +50,9 @@ public:<br>
   /// Schedule an update for \p File. Adds \p File to a list of tracked files if<br>
   /// \p File was not part of it before.<br>
   /// FIXME(ibiryukov): remove the callback from this function.<br>
-  void update(<br>
-      Context Ctx, PathRef File, ParseInputs Inputs,<br>
-      UniqueFunction<void(Context, llvm::Optional<std::vector<<wbr>DiagWithFixIts>>)><br>
-          OnUpdated);<br>
+  void update(PathRef File, ParseInputs Inputs,<br>
+              UniqueFunction<void(llvm::<wbr>Optional<std::vector<<wbr>DiagWithFixIts>>)><br>
+                  OnUpdated);<br>
<br>
   /// Remove \p File from the list of tracked files and schedule removal of its<br>
   /// resources. \p Action will be called when resources are freed.<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Threading.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Threading.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Threading.cpp?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Threading.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Threading.cpp Wed Jan 31 05:40:48 2018<br>
@@ -17,6 +17,7 @@ ThreadPool::ThreadPool(<wbr>unsigned AsyncThr<br>
       llvm::set_thread_name(llvm::<wbr>formatv("scheduler/{0}", I));<br>
       while (true) {<br>
         UniqueFunction<void()> Request;<br>
+        Context Ctx;<br>
<br>
         // Pick request from the queue<br>
         {<br>
@@ -33,10 +34,11 @@ ThreadPool::ThreadPool(<wbr>unsigned AsyncThr<br>
           // ThreadPool have a way to prioritise their requests by putting<br>
           // them to the either side of the queue (using either addToEnd or<br>
           // addToFront).<br>
-          Request = std::move(RequestQueue.front()<wbr>);<br>
+          std::tie(Request, Ctx) = std::move(RequestQueue.front()<wbr>);<br>
           RequestQueue.pop_front();<br>
         } // unlock Mutex<br>
<br>
+        WithContext WithCtx(std::move(Ctx));<br>
         Request();<br>
       }<br>
     }));<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Threading.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Threading.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Threading.h?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Threading.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Threading.h Wed Jan 31 05:40:48 2018<br>
@@ -10,6 +10,7 @@<br>
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>THREADING_H<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>THREADING_H<br>
<br>
+#include "Context.h"<br>
 #include "Function.h"<br>
 #include <condition_variable><br>
 #include <deque><br>
@@ -42,8 +43,9 @@ public:<br>
<br>
     {<br>
       std::lock_guard<std::mutex> Lock(Mutex);<br>
-      RequestQueue.push_front(<br>
-          BindWithForward(std::forward<<wbr>Func>(F), std::forward<Args>(As)...));<br>
+      RequestQueue.emplace_front(<br>
+          BindWithForward(std::forward<<wbr>Func>(F), std::forward<Args>(As)...),<br>
+          Context::current().clone());<br>
     }<br>
     RequestCV.notify_one();<br>
   }<br>
@@ -58,8 +60,9 @@ public:<br>
<br>
     {<br>
       std::lock_guard<std::mutex> Lock(Mutex);<br>
-      RequestQueue.push_back(<br>
-          BindWithForward(std::forward<<wbr>Func>(F), std::forward<Args>(As)...));<br>
+      RequestQueue.emplace_back(<br>
+          BindWithForward(std::forward<<wbr>Func>(F), std::forward<Args>(As)...),<br>
+          Context::current().clone());<br>
     }<br>
     RequestCV.notify_one();<br>
   }<br>
@@ -74,7 +77,7 @@ private:<br>
   /// Setting Done to true will make the worker threads terminate.<br>
   bool Done = false;<br>
   /// A queue of requests.<br>
-  std::deque<UniqueFunction<<wbr>void()>> RequestQueue;<br>
+  std::deque<std::pair<<wbr>UniqueFunction<void()>, Context>> RequestQueue;<br>
   /// Condition variable to wake up worker threads.<br>
   std::condition_variable RequestCV;<br>
 };<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Trace.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Trace.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Trace.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Trace.cpp Wed Jan 31 05:40:48 2018<br>
@@ -46,16 +46,14 @@ public:<br>
     Out.flush();<br>
   }<br>
<br>
-  Context beginSpan(const Context &Ctx, llvm::StringRef Name,<br>
-                    json::obj *Args) override {<br>
+  Context beginSpan(llvm::StringRef Name, json::obj *Args) override {<br>
     jsonEvent("B", json::obj{{"name", Name}});<br>
-    return Ctx.derive(make_scope_exit([<wbr>this, Args] {<br>
+    return Context::current().derive(<wbr>make_scope_exit([this, Args] {<br>
       jsonEvent("E", json::obj{{"args", std::move(*Args)}});<br>
     }));<br>
   }<br>
<br>
-  void instant(const Context &Ctx, llvm::StringRef Name,<br>
-               json::obj &&Args) override {<br>
+  void instant(llvm::StringRef Name, json::obj &&Args) override {<br>
     jsonEvent("i", json::obj{{"name", Name}, {"args", std::move(Args)}});<br>
   }<br>
<br>
@@ -120,20 +118,26 @@ std::unique_ptr<EventTracer> createJSONT<br>
   return llvm::make_unique<JSONTracer>(<wbr>OS, Pretty);<br>
 }<br>
<br>
-void log(const Context &Ctx, const Twine &Message) {<br>
+void log(const Twine &Message) {<br>
   if (!T)<br>
     return;<br>
-  T->instant(Ctx, "Log", json::obj{{"Message", Message.str()}});<br>
+  T->instant("Log", json::obj{{"Message", Message.str()}});<br>
+}<br>
+<br>
+// Returned context owns Args.<br>
+static Context makeSpanContext(llvm::<wbr>StringRef Name, json::obj *Args) {<br>
+  if (!T)<br>
+    return Context::current().clone();<br>
+  WithContextValue WithArgs{std::unique_ptr<json:<wbr>:obj>(Args)};<br>
+  return T->beginSpan(Name, Args);<br>
 }<br>
<br>
 // Span keeps a non-owning pointer to the args, which is how users access them.<br>
 // The args are owned by the context though. They stick around until the<br>
 // beginSpan() context is destroyed, when the tracing engine will consume them.<br>
-Span::Span(const Context &Ctx, llvm::StringRef Name)<br>
+Span::Span(llvm::StringRef Name)<br>
     : Args(T ? new json::obj() : nullptr),<br>
-      Ctx(T ? T->beginSpan(Ctx.derive(std::<wbr>unique_ptr<json::obj>(Args)), Name,<br>
-                           Args)<br>
-            : Ctx.clone()) {}<br>
+      RestoreCtx(makeSpanContext(<wbr>Name, Args)) {}<br>
<br>
 } // namespace trace<br>
 } // namespace clangd<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/Trace.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Trace.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/Trace.h?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/Trace.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/Trace.h Wed Jan 31 05:40:48 2018<br>
@@ -39,12 +39,10 @@ public:<br>
   /// Usually implementations will store an object in the returned context<br>
   /// whose destructor records the end of the event.<br>
   /// The args are *Args, only complete when the event ends.<br>
-  virtual Context beginSpan(const Context &Ctx, llvm::StringRef Name,<br>
-                            json::obj *Args) = 0;<br>
+  virtual Context beginSpan(llvm::StringRef Name, json::obj *Args) = 0;<br>
<br>
   /// Called for instant events.<br>
-  virtual void instant(const Context &Ctx, llvm::StringRef Name,<br>
-                       json::obj &&Args) = 0;<br>
+  virtual void instant(llvm::StringRef Name, json::obj &&Args) = 0;<br>
 };<br>
<br>
 /// Sets up a global EventTracer that consumes events produced by Span and<br>
@@ -65,7 +63,7 @@ std::unique_ptr<EventTracer> createJSONT<br>
                                               bool Pretty = false);<br>
<br>
 /// Records a single instant event, associated with the current thread.<br>
-void log(const Context &Ctx, const llvm::Twine &Name);<br>
+void log(const llvm::Twine &Name);<br>
<br>
 /// Records an event whose duration is the lifetime of the Span object.<br>
 /// This lifetime is extended when the span's context is reused.<br>
@@ -78,18 +76,19 @@ void log(const Context &Ctx, const llvm:<br>
 /// SomeJSONExpr is evaluated and copied only if actually needed.<br>
 class Span {<br>
 public:<br>
-  Span(const Context &Ctx, llvm::StringRef Name);<br>
+  Span(llvm::StringRef Name);<br>
<br>
   /// Mutable metadata, if this span is interested.<br>
   /// Prefer to use SPAN_ATTACH rather than accessing this directly.<br>
   json::obj *const Args;<br>
-  /// Propagating this context will keep the span alive.<br>
-  const Context Ctx;<br>
+<br>
+private:<br>
+  WithContext RestoreCtx;<br>
 };<br>
<br>
 /// Returns mutable span metadata if this span is interested.<br>
 /// Prefer to use SPAN_ATTACH rather than accessing this directly.<br>
-json::obj *spanArgs(const Context &Ctx);<br>
+json::obj *spanArgs();<br>
<br>
 /// Attach a key-value pair to a Span event.<br>
 /// This is not threadsafe when used with the same Span.<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/XRefs.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/XRefs.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/XRefs.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/XRefs.cpp Wed Jan 31 05:40:48 2018<br>
@@ -148,8 +148,7 @@ getDeclarationLocation(<wbr>ParsedAST &AST, c<br>
<br>
 } // namespace<br>
<br>
-std::vector<Location> findDefinitions(const Context &Ctx, ParsedAST &AST,<br>
-                                      Position Pos) {<br>
+std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos) {<br>
   const SourceManager &SourceMgr = AST.getASTContext().<wbr>getSourceManager();<br>
   const FileEntry *FE = SourceMgr.getFileEntryForID(<wbr>SourceMgr.getMainFileID());<br>
   if (!FE)<br>
@@ -260,8 +259,8 @@ private:<br>
<br>
 } // namespace<br>
<br>
-std::vector<<wbr>DocumentHighlight><br>
-findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos) {<br>
+std::vector<<wbr>DocumentHighlight> findDocumentHighlights(<wbr>ParsedAST &AST,<br>
+                                                      Position Pos) {<br>
   const SourceManager &SourceMgr = AST.getASTContext().<wbr>getSourceManager();<br>
   const FileEntry *FE = SourceMgr.getFileEntryForID(<wbr>SourceMgr.getMainFileID());<br>
   if (!FE)<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/XRefs.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/XRefs.h?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/XRefs.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/XRefs.h Wed Jan 31 05:40:48 2018<br>
@@ -14,7 +14,6 @@<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>XREFS_H<br>
<br>
 #include "ClangdUnit.h"<br>
-#include "Context.h"<br>
 #include "Protocol.h"<br>
 #include <vector><br>
<br>
@@ -22,12 +21,11 @@ namespace clang {<br>
 namespace clangd {<br>
<br>
 /// Get definition of symbol at a specified \p Pos.<br>
-std::vector<Location> findDefinitions(const Context &Ctx, ParsedAST &AST,<br>
-                                      Position Pos);<br>
+std::vector<Location> findDefinitions(ParsedAST &AST, Position Pos);<br>
<br>
 /// Returns highlights for all usages of a symbol at \p Pos.<br>
-std::vector<<wbr>DocumentHighlight><br>
-findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos);<br>
+std::vector<<wbr>DocumentHighlight> findDocumentHighlights(<wbr>ParsedAST &AST,<br>
+                                                      Position Pos);<br>
<br>
 } // namespace clangd<br>
 } // namespace clang<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/index/FileIndex.<wbr>cpp?rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.cpp Wed Jan 31 05:40:48 2018<br>
@@ -69,7 +69,7 @@ std::shared_ptr<std::vector<<wbr>const Symbol<br>
   return {std::move(Snap), Pointers};<br>
 }<br>
<br>
-void FileIndex::update(const Context &Ctx, PathRef Path, ParsedAST *AST) {<br>
+void FileIndex::update(PathRef Path, ParsedAST *AST) {<br>
   if (!AST) {<br>
     FSymbols.update(Path, nullptr);<br>
   } else {<br>
@@ -82,9 +82,9 @@ void FileIndex::update(const Context &Ct<br>
 }<br>
<br>
 bool FileIndex::fuzzyFind(<br>
-    const Context &Ctx, const FuzzyFindRequest &Req,<br>
+    const FuzzyFindRequest &Req,<br>
     llvm::function_ref<void(const Symbol &)> Callback) const {<br>
-  return Index.fuzzyFind(Ctx, Req, Callback);<br>
+  return Index.fuzzyFind(Req, Callback);<br>
 }<br>
<br>
 } // namespace clangd<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/index/FileIndex.<wbr>h?rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/index/FileIndex.h Wed Jan 31 05:40:48 2018<br>
@@ -17,7 +17,6 @@<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>INDEX_FILEINDEX_H<br>
<br>
 #include "../ClangdUnit.h"<br>
-#include "../Context.h"<br>
 #include "Index.h"<br>
 #include "MemIndex.h"<br>
<br>
@@ -58,10 +57,10 @@ class FileIndex : public SymbolIndex {<br>
 public:<br>
   /// \brief Update symbols in \p Path with symbols in \p AST. If \p AST is<br>
   /// nullptr, this removes all symbols in the file<br>
-  void update(const Context &Ctx, PathRef Path, ParsedAST *AST);<br>
+  void update(PathRef Path, ParsedAST *AST);<br>
<br>
   bool<br>
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,<br>
+  fuzzyFind(const FuzzyFindRequest &Req,<br>
             llvm::function_ref<void(const Symbol &)> Callback) const override;<br>
<br>
 private:<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/index/Index.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Index.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/index/Index.h?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/index/Index.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/index/Index.h Wed Jan 31 05:40:48 2018<br>
@@ -10,7 +10,6 @@<br>
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>INDEX_INDEX_H<br>
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_<wbr>INDEX_INDEX_H<br>
<br>
-#include "../Context.h"<br>
 #include "clang/Index/IndexSymbol.h"<br>
 #include "llvm/ADT/DenseMap.h"<br>
 #include "llvm/ADT/DenseSet.h"<br>
@@ -244,7 +243,7 @@ public:<br>
   /// Returns true if the result list is complete, false if it was truncated due<br>
   /// to MaxCandidateCount<br>
   virtual bool<br>
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,<br>
+  fuzzyFind(const FuzzyFindRequest &Req,<br>
             llvm::function_ref<void(const Symbol &)> Callback) const = 0;<br>
<br>
   // FIXME: add interfaces for more index use cases:<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/index/MemIndex.<wbr>cpp?rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.cpp Wed Jan 31 05:40:48 2018<br>
@@ -29,7 +29,7 @@ void MemIndex::build(std::shared_<wbr>ptr<std<br>
 }<br>
<br>
 bool MemIndex::fuzzyFind(<br>
-    const Context &Ctx, const FuzzyFindRequest &Req,<br>
+    const FuzzyFindRequest &Req,<br>
     llvm::function_ref<void(const Symbol &)> Callback) const {<br>
   assert(!StringRef(Req.Query).<wbr>contains("::") &&<br>
          "There must be no :: in query.");<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.h?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/index/MemIndex.h?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.h (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/index/MemIndex.h Wed Jan 31 05:40:48 2018<br>
@@ -28,7 +28,7 @@ public:<br>
   static std::unique_ptr<SymbolIndex> build(SymbolSlab Slab);<br>
<br>
   bool<br>
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,<br>
+  fuzzyFind(const FuzzyFindRequest &Req,<br>
             llvm::function_ref<void(const Symbol &)> Callback) const override;<br>
<br>
 private:<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>clangd/index/Merge.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Merge.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/clangd/index/Merge.cpp?<wbr>rev=323872&r1=323871&r2=<wbr>323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>clangd/index/Merge.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>clangd/index/Merge.cpp Wed Jan 31 05:40:48 2018<br>
@@ -24,7 +24,7 @@ class MergedIndex : public SymbolIndex {<br>
    //          - find the generating file from each Symbol which is Static-only<br>
    //          - ask Dynamic if it has that file (needs new SymbolIndex method)<br>
    //          - if so, drop the Symbol.<br>
-   bool fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,<br>
+   bool fuzzyFind(const FuzzyFindRequest &Req,<br>
                   function_ref<void(const Symbol &)> Callback) const override {<br>
      // We can't step through both sources in parallel. So:<br>
      //  1) query all dynamic symbols, slurping results into a slab<br>
@@ -34,13 +34,12 @@ class MergedIndex : public SymbolIndex {<br>
      //  3) now yield all the dynamic symbols we haven't processed.<br>
      bool More = false; // We'll be incomplete if either source was.<br>
      SymbolSlab::Builder DynB;<br>
-     More |=<br>
-         Dynamic->fuzzyFind(Ctx, Req, [&](const Symbol &S) { DynB.insert(S); });<br>
+     More |= Dynamic->fuzzyFind(Req, [&](const Symbol &S) { DynB.insert(S); });<br>
      SymbolSlab Dyn = std::move(DynB).build();<br>
<br>
      DenseSet<SymbolID> SeenDynamicSymbols;<br>
      Symbol::Details Scratch;<br>
-     More |= Static->fuzzyFind(Ctx, Req, [&](const Symbol &S) {<br>
+     More |= Static->fuzzyFind(Req, [&](const Symbol &S) {<br>
        auto DynS = Dyn.find(<a href="http://S.ID" rel="noreferrer" target="_blank">S.ID</a>);<br>
        if (DynS == Dyn.end())<br>
          return Callback(S);<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/ClangdTests.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>ClangdTests.cpp?rev=323872&r1=<wbr>323871&r2=323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/ClangdTests.<wbr>cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/ClangdTests.<wbr>cpp Wed Jan 31 05:40:48 2018<br>
@@ -9,7 +9,6 @@<br>
<br>
 #include "ClangdLSPServer.h"<br>
 #include "ClangdServer.h"<br>
-#include "Context.h"<br>
 #include "TestFS.h"<br>
 #include "clang/Config/config.h"<br>
 #include "llvm/ADT/SmallVector.h"<br>
@@ -58,7 +57,7 @@ static bool diagsContainErrors(ArrayRef<<br>
 class ErrorCheckingDiagConsumer : public DiagnosticsConsumer {<br>
 public:<br>
   void<br>
-  onDiagnosticsReady(const Context &Ctx, PathRef File,<br>
+  onDiagnosticsReady(PathRef File,<br>
                      Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) override {<br>
     bool HadError = diagsContainErrors(<wbr>Diagnostics.Value);<br>
<br>
@@ -143,8 +142,7 @@ protected:<br>
<br>
     // Have to sync reparses because requests are processed on the calling<br>
     // thread.<br>
-    auto AddDocFuture =<br>
-        Server.addDocument(Context::<wbr>empty(), SourceFilename, SourceContents);<br>
+    auto AddDocFuture = Server.addDocument(<wbr>SourceFilename, SourceContents);<br>
<br>
     auto Result = dumpASTWithoutMemoryLocs(<wbr>Server, SourceFilename);<br>
<br>
@@ -211,21 +209,21 @@ int b = a;<br>
   FS.ExpectedFile = FooCpp;<br>
<br>
   // To sync reparses before checking for errors.<br>
-  std::future<Context> ParseFuture;<br>
+  std::future<void> ParseFuture;<br>
<br>
-  ParseFuture = Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents);<br>
+  ParseFuture = Server.addDocument(FooCpp, SourceContents);<br>
   auto DumpParse1 = dumpASTWithoutMemoryLocs(<wbr>Server, FooCpp);<br>
   ASSERT_EQ(ParseFuture.wait_<wbr>for(DefaultFutureTimeout),<br>
             std::future_status::ready);<br>
   EXPECT_FALSE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
<br>
-  ParseFuture = Server.addDocument(Context::<wbr>empty(), FooCpp, "");<br>
+  ParseFuture = Server.addDocument(FooCpp, "");<br>
   auto DumpParseEmpty = dumpASTWithoutMemoryLocs(<wbr>Server, FooCpp);<br>
   ASSERT_EQ(ParseFuture.wait_<wbr>for(DefaultFutureTimeout),<br>
             std::future_status::ready);<br>
   EXPECT_FALSE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
<br>
-  ParseFuture = Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents);<br>
+  ParseFuture = Server.addDocument(FooCpp, SourceContents);<br>
   auto DumpParse2 = dumpASTWithoutMemoryLocs(<wbr>Server, FooCpp);<br>
   ASSERT_EQ(ParseFuture.wait_<wbr>for(DefaultFutureTimeout),<br>
             std::future_status::ready);<br>
@@ -256,23 +254,23 @@ int b = a;<br>
   FS.ExpectedFile = FooCpp;<br>
<br>
   // To sync reparses before checking for errors.<br>
-  std::future<Context> ParseFuture;<br>
+  std::future<void> ParseFuture;<br>
<br>
-  ParseFuture = Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents);<br>
+  ParseFuture = Server.addDocument(FooCpp, SourceContents);<br>
   auto DumpParse1 = dumpASTWithoutMemoryLocs(<wbr>Server, FooCpp);<br>
   ASSERT_EQ(ParseFuture.wait_<wbr>for(DefaultFutureTimeout),<br>
             std::future_status::ready);<br>
   EXPECT_FALSE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
<br>
   FS.Files[FooH] = "";<br>
-  ParseFuture = Server.forceReparse(Context::<wbr>empty(), FooCpp);<br>
+  ParseFuture = Server.forceReparse(FooCpp);<br>
   auto DumpParseDifferent = dumpASTWithoutMemoryLocs(<wbr>Server, FooCpp);<br>
   ASSERT_EQ(ParseFuture.wait_<wbr>for(DefaultFutureTimeout),<br>
             std::future_status::ready);<br>
   EXPECT_TRUE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
<br>
   FS.Files[FooH] = "int a;";<br>
-  ParseFuture = Server.forceReparse(Context::<wbr>empty(), FooCpp);<br>
+  ParseFuture = Server.forceReparse(FooCpp);<br>
   auto DumpParse2 = dumpASTWithoutMemoryLocs(<wbr>Server, FooCpp);<br>
   EXPECT_EQ(ParseFuture.wait_<wbr>for(DefaultFutureTimeout),<br>
             std::future_status::ready);<br>
@@ -302,22 +300,16 @@ TEST_F(ClangdVFSTest, CheckVersions) {<br>
   // No need to sync reparses, because requests are processed on the calling<br>
   // thread.<br>
   FS.Tag = "123";<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents);<br>
-  EXPECT_EQ(<br>
-      Server.codeComplete(Context::<wbr>empty(), FooCpp, Position{0, 0}, CCOpts)<br>
-          .get()<br>
-          .second.Tag,<br>
-      FS.Tag);<br>
+  Server.addDocument(FooCpp, SourceContents);<br>
+  EXPECT_EQ(Server.codeComplete(<wbr>FooCpp, Position{0, 0}, CCOpts).get().Tag,<br>
+            FS.Tag);<br>
   EXPECT_EQ(DiagConsumer.<wbr>lastVFSTag(), FS.Tag);<br>
<br>
   FS.Tag = "321";<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents);<br>
+  Server.addDocument(FooCpp, SourceContents);<br>
   EXPECT_EQ(DiagConsumer.<wbr>lastVFSTag(), FS.Tag);<br>
-  EXPECT_EQ(<br>
-      Server.codeComplete(Context::<wbr>empty(), FooCpp, Position{0, 0}, CCOpts)<br>
-          .get()<br>
-          .second.Tag,<br>
-      FS.Tag);<br>
+  EXPECT_EQ(Server.codeComplete(<wbr>FooCpp, Position{0, 0}, CCOpts).get().Tag,<br>
+            FS.Tag);<br>
 }<br>
<br>
 // Only enable this test on Unix<br>
@@ -365,14 +357,14 @@ mock_string x;<br>
<br>
   // No need to sync reparses, because requests are processed on the calling<br>
   // thread.<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents);<br>
+  Server.addDocument(FooCpp, SourceContents);<br>
   EXPECT_FALSE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
<br>
   const auto SourceContentsWithError = R"cpp(<br>
 #include <string><br>
 std::string x;<br>
 )cpp";<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContentsWithError);<br>
+  Server.addDocument(FooCpp, SourceContentsWithError);<br>
   EXPECT_TRUE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
 }<br>
 #endif // LLVM_ON_UNIX<br>
@@ -402,26 +394,26 @@ struct bar { T x; };<br>
<br>
   // First parse files in C mode and check they produce errors.<br>
   CDB.ExtraClangFlags = {"-xc"};<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents1);<br>
+  Server.addDocument(FooCpp, SourceContents1);<br>
   EXPECT_TRUE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents2);<br>
+  Server.addDocument(FooCpp, SourceContents2);<br>
   EXPECT_TRUE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
<br>
   // Now switch to C++ mode.<br>
   CDB.ExtraClangFlags = {"-xc++"};<br>
   // Currently, addDocument never checks if CompileCommand has changed, so we<br>
   // expect to see the errors.<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents1);<br>
+  Server.addDocument(FooCpp, SourceContents1);<br>
   EXPECT_TRUE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents2);<br>
+  Server.addDocument(FooCpp, SourceContents2);<br>
   EXPECT_TRUE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
   // But forceReparse should reparse the file with proper flags.<br>
-  Server.forceReparse(Context::<wbr>empty(), FooCpp);<br>
+  Server.forceReparse(FooCpp);<br>
   EXPECT_FALSE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
   // Subsequent addDocument calls should finish without errors too.<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents1);<br>
+  Server.addDocument(FooCpp, SourceContents1);<br>
   EXPECT_FALSE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents2);<br>
+  Server.addDocument(FooCpp, SourceContents2);<br>
   EXPECT_FALSE(DiagConsumer.<wbr>hadErrorInLastDiags());<br>
 }<br>
<br>
@@ -448,16 +440,16 @@ struct Something {<br>
<br>
   EXPECT_THAT(Server.<wbr>getUsedBytesPerFile(), IsEmpty());<br>
<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContents);<br>
-  Server.addDocument(Context::<wbr>empty(), BarCpp, SourceContents);<br>
+  Server.addDocument(FooCpp, SourceContents);<br>
+  Server.addDocument(BarCpp, SourceContents);<br>
<br>
   EXPECT_THAT(Server.<wbr>getUsedBytesPerFile(),<br>
               UnorderedElementsAre(Pair(<wbr>FooCpp, Gt(0u)), Pair(BarCpp, Gt(0u))));<br>
<br>
-  Server.removeDocument(Context:<wbr>:empty(), FooCpp);<br>
+  Server.removeDocument(FooCpp);<br>
   EXPECT_THAT(Server.<wbr>getUsedBytesPerFile(), ElementsAre(Pair(BarCpp, Gt(0u))));<br>
<br>
-  Server.removeDocument(Context:<wbr>:empty(), BarCpp);<br>
+  Server.removeDocument(BarCpp);<br>
   EXPECT_THAT(Server.<wbr>getUsedBytesPerFile(), IsEmpty());<br>
 }<br>
<br>
@@ -515,7 +507,7 @@ int d;<br>
     TestDiagConsumer() : Stats(FilesCount, FileStat()) {}<br>
<br>
     void onDiagnosticsReady(<br>
-        const Context &Ctx, PathRef File,<br>
+        PathRef File,<br>
         Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) override {<br>
       StringRef FileIndexStr = llvm::sys::path::stem(File);<br>
       ASSERT_TRUE(FileIndexStr.<wbr>consume_front("Foo"));<br>
@@ -547,7 +539,7 @@ int d;<br>
     unsigned RequestsWithErrors = 0;<br>
     bool LastContentsHadErrors = false;<br>
     bool FileIsRemoved = true;<br>
-    std::future<Context> LastRequestFuture;<br>
+    std::future<void> LastRequestFuture;<br>
   };<br>
<br>
   std::vector<RequestStats> ReqStats;<br>
@@ -574,7 +566,7 @@ int d;<br>
<br>
     // Some helpers.<br>
     auto UpdateStatsOnAddDocument = [&](unsigned FileIndex, bool HadErrors,<br>
-                                        std::future<Context> Future) {<br>
+                                        std::future<void> Future) {<br>
       auto &Stats = ReqStats[FileIndex];<br>
<br>
       if (HadErrors)<br>
@@ -587,7 +579,7 @@ int d;<br>
     };<br>
<br>
     auto UpdateStatsOnRemoveDocument = [&](unsigned FileIndex,<br>
-                                           std::future<Context> Future) {<br>
+                                           std::future<void> Future) {<br>
       auto &Stats = ReqStats[FileIndex];<br>
<br>
       Stats.FileIsRemoved = true;<br>
@@ -595,7 +587,7 @@ int d;<br>
     };<br>
<br>
     auto UpdateStatsOnForceReparse = [&](unsigned FileIndex,<br>
-                                         std::future<Context> Future) {<br>
+                                         std::future<void> Future) {<br>
       auto &Stats = ReqStats[FileIndex];<br>
<br>
       Stats.LastRequestFuture = std::move(Future);<br>
@@ -607,10 +599,9 @@ int d;<br>
<br>
     auto AddDocument = [&](unsigned FileIndex) {<br>
       bool ShouldHaveErrors = ShouldHaveErrorsDist(RandGen);<br>
-      auto Future =<br>
-          Server.addDocument(Context::<wbr>empty(), FilePaths[FileIndex],<br>
-                             ShouldHaveErrors ? SourceContentsWithErrors<br>
-                                              : SourceContentsWithoutErrors);<br>
+      auto Future = Server.addDocument(<br>
+          FilePaths[FileIndex], ShouldHaveErrors ? SourceContentsWithErrors<br>
+                                                 : SourceContentsWithoutErrors);<br>
       UpdateStatsOnAddDocument(<wbr>FileIndex, ShouldHaveErrors, std::move(Future));<br>
     };<br>
<br>
@@ -626,7 +617,7 @@ int d;<br>
       if (ReqStats[FileIndex].<wbr>FileIsRemoved)<br>
         AddDocument(FileIndex);<br>
<br>
-      auto Future = Server.forceReparse(Context::<wbr>empty(), FilePaths[FileIndex]);<br>
+      auto Future = Server.forceReparse(FilePaths[<wbr>FileIndex]);<br>
       UpdateStatsOnForceReparse(<wbr>FileIndex, std::move(Future));<br>
     };<br>
<br>
@@ -636,8 +627,7 @@ int d;<br>
       if (ReqStats[FileIndex].<wbr>FileIsRemoved)<br>
         AddDocument(FileIndex);<br>
<br>
-      auto Future =<br>
-          Server.removeDocument(Context:<wbr>:empty(), FilePaths[FileIndex]);<br>
+      auto Future = Server.removeDocument(<wbr>FilePaths[FileIndex]);<br>
       UpdateStatsOnRemoveDocument(<wbr>FileIndex, std::move(Future));<br>
     };<br>
<br>
@@ -655,7 +645,7 @@ int d;<br>
       // cancelled by any subsequent AddDocument/RemoveDocument request to the<br>
       // same file.<br>
       Server<br>
-          .codeComplete(Context::empty()<wbr>, FilePaths[FileIndex], Pos,<br>
+          .codeComplete(FilePaths[<wbr>FileIndex], Pos,<br>
                         clangd::CodeCompleteOptions())<br>
           .wait();<br>
     };<br>
@@ -667,8 +657,7 @@ int d;<br>
         AddDocument(FileIndex);<br>
<br>
       Position Pos{LineDist(RandGen), ColumnDist(RandGen)};<br>
-      ASSERT_TRUE(!!Server.<wbr>findDefinitions(Context::<wbr>empty(),<br>
-                                           FilePaths[FileIndex], Pos));<br>
+      ASSERT_TRUE(!!Server.<wbr>findDefinitions(FilePaths[<wbr>FileIndex], Pos));<br>
     };<br>
<br>
     std::vector<std::function<<wbr>void()>> AsyncRequests = {<br>
@@ -803,7 +792,7 @@ TEST_F(ClangdThreadingTest, NoConcurrent<br>
         : StartSecondReparse(std::move(<wbr>StartSecondReparse)) {}<br>
<br>
     void onDiagnosticsReady(<br>
-        const Context &Ctx, PathRef File,<br>
+        PathRef File,<br>
         Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) override {<br>
<br>
       std::unique_lock<std::mutex> Lock(Mutex, std::try_to_lock_t());<br>
@@ -851,11 +840,10 @@ int d;<br>
   MockCompilationDatabase CDB;<br>
   ClangdServer Server(CDB, DiagConsumer, FS, 4,<br>
                       /*StorePreamblesInMemory=*/<wbr>true);<br>
-  Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContentsWithErrors);<br>
+  Server.addDocument(FooCpp, SourceContentsWithErrors);<br>
   StartSecondReparse.wait();<br>
<br>
-  auto Future =<br>
-      Server.addDocument(Context::<wbr>empty(), FooCpp, SourceContentsWithoutErrors);<br>
+  auto Future = Server.addDocument(FooCpp, SourceContentsWithoutErrors);<br>
   Future.wait();<br>
 }<br>
<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>ClangdUnitTests.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/ClangdUnitTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>ClangdUnitTests.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>ClangdUnitTests.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>ClangdUnitTests.cpp Wed Jan 31 05:40:48 2018<br>
@@ -43,9 +43,9 @@ ParsedAST build(StringRef Code, std::vec<br>
   Cmd.insert(Cmd.begin() + 1, Flags.begin(), Flags.end());<br>
   auto CI = createInvocationFromCommandLin<wbr>e(Cmd);<br>
   auto Buf = MemoryBuffer::getMemBuffer(<wbr>Code);<br>
-  auto AST = ParsedAST::Build(<br>
-      Context::empty(), std::move(CI), nullptr, std::move(Buf),<br>
-      std::make_shared<<wbr>PCHContainerOperations>(), vfs::getRealFileSystem());<br>
+  auto AST = ParsedAST::Build(std::move(CI)<wbr>, nullptr, std::move(Buf),<br>
+                              std::make_shared<<wbr>PCHContainerOperations>(),<br>
+                              vfs::getRealFileSystem());<br>
   assert(AST.hasValue());<br>
   return std::move(*AST);<br>
 }<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>CodeCompleteTests.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/CodeCompleteTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>CodeCompleteTests.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>CodeCompleteTests.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>CodeCompleteTests.cpp Wed Jan 31 05:40:48 2018<br>
@@ -11,7 +11,6 @@<br>
 #include "ClangdServer.h"<br>
 #include "CodeComplete.h"<br>
 #include "Compiler.h"<br>
-#include "Context.h"<br>
 #include "Matchers.h"<br>
 #include "Protocol.h"<br>
 #include "SourceCode.h"<br>
@@ -61,10 +60,8 @@ using ::testing::<wbr>UnorderedElementsAre;<br>
 using ::testing::Field;<br>
<br>
 class IgnoreDiagnostics : public DiagnosticsConsumer {<br>
-  void<br>
-  onDiagnosticsReady(const Context &Ctx, PathRef File,<br>
-                     Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) override {<br>
-  }<br>
+  void onDiagnosticsReady(<br>
+      PathRef File, Tagged<std::vector<<wbr>DiagWithFixIts>> Diagnostics) override {}<br>
 };<br>
<br>
 // GMock helpers for matching completion items.<br>
@@ -123,11 +120,9 @@ CompletionList completions(StringRef Tex<br>
                       /*StorePreamblesInMemory=*/<wbr>true);<br>
   auto File = getVirtualTestFilePath("foo.<wbr>cpp");<br>
   Annotations Test(Text);<br>
-  Server.addDocument(Context::<wbr>empty(), File, Test.code()).wait();<br>
+  Server.addDocument(File, Test.code()).wait();<br>
   auto CompletionList =<br>
-      Server.codeComplete(Context::<wbr>empty(), File, Test.point(), Opts)<br>
-          .get()<br>
-          .second.Value;<br>
+      Server.codeComplete(File, Test.point(), Opts).get().Value;<br>
   // Sanity-check that filterText is valid.<br>
   EXPECT_THAT(CompletionList.<wbr>items, Each(NameContainsFilter()));<br>
   return CompletionList;<br>
@@ -349,15 +344,15 @@ TEST(CompletionTest, CheckContentsOverri<br>
   ClangdServer Server(CDB, DiagConsumer, FS, getDefaultAsyncThreadsCount(),<br>
                       /*StorePreamblesInMemory=*/<wbr>true);<br>
   auto File = getVirtualTestFilePath("foo.<wbr>cpp");<br>
-  Server.addDocument(Context::<wbr>empty(), File, "ignored text!");<br>
+  Server.addDocument(File, "ignored text!");<br>
<br>
   Annotations Example("int cbc; int b = ^;");<br>
-  auto Results = Server<br>
-                     .codeComplete(Context::empty()<wbr>, File, Example.point(),<br>
-                                   clangd::CodeCompleteOptions(),<br>
-                                   StringRef(Example.code()))<br>
-                     .get()<br>
-                     .second.Value;<br>
+  auto Results =<br>
+      Server<br>
+          .codeComplete(File, Example.point(), clangd::CodeCompleteOptions(),<br>
+                        StringRef(Example.code()))<br>
+          .get()<br>
+          .Value;<br>
   EXPECT_THAT(Results.items, Contains(Named("cbc")));<br>
 }<br>
<br>
@@ -558,28 +553,20 @@ TEST(CompletionTest, IndexSuppressesPrea<br>
       void f() { ns::^; }<br>
       void f() { ns::preamble().$2^; }<br>
   )cpp");<br>
-  Server.addDocument(Context::<wbr>empty(), File, Test.code()).wait();<br>
+  Server.addDocument(File, Test.code()).wait();<br>
   clangd::CodeCompleteOptions Opts = {};<br>
<br>
-  auto WithoutIndex =<br>
-      Server.codeComplete(Context::<wbr>empty(), File, Test.point(), Opts)<br>
-          .get()<br>
-          .second.Value;<br>
+  auto WithoutIndex = Server.codeComplete(File, Test.point(), Opts).get().Value;<br>
   EXPECT_THAT(WithoutIndex.<wbr>items,<br>
               UnorderedElementsAre(Named("<wbr>local"), Named("preamble")));<br>
<br>
   auto I = memIndex({var("ns::index")});<br>
   Opts.Index = I.get();<br>
-  auto WithIndex =<br>
-      Server.codeComplete(Context::<wbr>empty(), File, Test.point(), Opts)<br>
-          .get()<br>
-          .second.Value;<br>
+  auto WithIndex = Server.codeComplete(File, Test.point(), Opts).get().Value;<br>
   EXPECT_THAT(WithIndex.items,<br>
               UnorderedElementsAre(Named("<wbr>local"), Named("index")));<br>
   auto ClassFromPreamble =<br>
-      Server.codeComplete(Context::<wbr>empty(), File, Test.point("2"), Opts)<br>
-          .get()<br>
-          .second.Value;<br>
+      Server.codeComplete(File, Test.point("2"), Opts).get().Value;<br>
   EXPECT_THAT(ClassFromPreamble.<wbr>items, Contains(Named("member")));<br>
 }<br>
<br>
@@ -592,7 +579,7 @@ TEST(CompletionTest, DynamicIndexMultiFi<br>
                       /*BuildDynamicSymbolIndex=*/<wbr>true);<br>
<br>
   Server<br>
-      .addDocument(Context::empty(), getVirtualTestFilePath("foo.<wbr>cpp"), R"cpp(<br>
+      .addDocument(<wbr>getVirtualTestFilePath("foo.<wbr>cpp"), R"cpp(<br>
       namespace ns { class XYZ {}; void foo(int x) {} }<br>
   )cpp")<br>
       .wait();<br>
@@ -606,11 +593,9 @@ TEST(CompletionTest, DynamicIndexMultiFi<br>
       }<br>
       void f() { ns::^ }<br>
   )cpp");<br>
-  Server.addDocument(Context::<wbr>empty(), File, Test.code()).wait();<br>
+  Server.addDocument(File, Test.code()).wait();<br>
<br>
-  auto Results = Server.codeComplete(Context::<wbr>empty(), File, Test.point(), {})<br>
-                     .get()<br>
-                     .second.Value;<br>
+  auto Results = Server.codeComplete(File, Test.point(), {}).get().Value;<br>
   // "XYZ" and "foo" are not included in the file being completed but are still<br>
   // visible through the index.<br>
   EXPECT_THAT(Results.items, Has("XYZ", CompletionItemKind::Class));<br>
@@ -637,8 +622,8 @@ SignatureHelp signatures(StringRef Text)<br>
                       /*StorePreamblesInMemory=*/<wbr>true);<br>
   auto File = getVirtualTestFilePath("foo.<wbr>cpp");<br>
   Annotations Test(Text);<br>
-  Server.addDocument(Context::<wbr>empty(), File, Test.code());<br>
-  auto R = Server.signatureHelp(Context::<wbr>empty(), File, Test.point());<br>
+  Server.addDocument(File, Test.code());<br>
+  auto R = Server.signatureHelp(File, Test.point());<br>
   assert(R);<br>
   return R.get().Value;<br>
 }<br>
@@ -707,7 +692,7 @@ TEST(SignatureHelpTest, ActiveArg) {<br>
 class IndexRequestCollector : public SymbolIndex {<br>
 public:<br>
   bool<br>
-  fuzzyFind(const Context &Ctx, const FuzzyFindRequest &Req,<br>
+  fuzzyFind(const FuzzyFindRequest &Req,<br>
             llvm::function_ref<void(const Symbol &)> Callback) const override {<br>
     Requests.push_back(Req);<br>
     return false;<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>FileIndexTests.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/FileIndexTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>FileIndexTests.cpp?rev=323872&<wbr>r1=323871&r2=323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>FileIndexTests.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>FileIndexTests.cpp Wed Jan 31 05:40:48 2018<br>
@@ -76,8 +76,7 @@ TEST(FileSymbolsTest, SnapshotAliveAfter<br>
 std::vector<std::string> match(const SymbolIndex &I,<br>
                                const FuzzyFindRequest &Req) {<br>
   std::vector<std::string> Matches;<br>
-  auto Ctx = Context::empty();<br>
-  I.fuzzyFind(Ctx, Req, [&](const Symbol &Sym) {<br>
+  I.fuzzyFind(Req, [&](const Symbol &Sym) {<br>
     Matches.push_back((Sym.Scope + Sym.Name).str());<br>
   });<br>
   return Matches;<br>
@@ -85,7 +84,6 @@ std::vector<std::string> match(const Sym<br>
<br>
 /// Create an ParsedAST for \p Code. Returns None if \p Code is empty.<br>
 llvm::Optional<ParsedAST> build(std::string Path, llvm::StringRef Code) {<br>
-  Context Ctx = Context::empty();<br>
   if (Code.empty())<br>
     return llvm::None;<br>
   const char *Args[] = {"clang", "-xc++", Path.c_str()};<br>
@@ -93,7 +91,7 @@ llvm::Optional<ParsedAST> build(std::str<br>
   auto CI = createInvocationFromCommandLin<wbr>e(Args);<br>
<br>
   auto Buf = llvm::MemoryBuffer::<wbr>getMemBuffer(Code);<br>
-  auto AST = ParsedAST::Build(Ctx, std::move(CI), nullptr, std::move(Buf),<br>
+  auto AST = ParsedAST::Build(std::move(CI)<wbr>, nullptr, std::move(Buf),<br>
                               std::make_shared<<wbr>PCHContainerOperations>(),<br>
                               vfs::getRealFileSystem());<br>
   assert(AST.hasValue());<br>
@@ -102,9 +100,8 @@ llvm::Optional<ParsedAST> build(std::str<br>
<br>
 TEST(FileIndexTest, IndexAST) {<br>
   FileIndex M;<br>
-  auto Ctx = Context::empty();<br>
   M.update(<br>
-      Ctx, "f1",<br>
+      "f1",<br>
       build("f1", "namespace ns { void f() {} class X {}; }").getPointer());<br>
<br>
   FuzzyFindRequest Req;<br>
@@ -115,9 +112,8 @@ TEST(FileIndexTest, IndexAST) {<br>
<br>
 TEST(FileIndexTest, NoLocal) {<br>
   FileIndex M;<br>
-  auto Ctx = Context::empty();<br>
   M.update(<br>
-      Ctx, "f1",<br>
+      "f1",<br>
       build("f1", "namespace ns { void f() { int local = 0; } class X {}; }")<br>
           .getPointer());<br>
<br>
@@ -128,12 +124,11 @@ TEST(FileIndexTest, NoLocal) {<br>
<br>
 TEST(FileIndexTest, IndexMultiASTAndDeduplicate) {<br>
   FileIndex M;<br>
-  auto Ctx = Context::empty();<br>
   M.update(<br>
-      Ctx, "f1",<br>
+      "f1",<br>
       build("f1", "namespace ns { void f() {} class X {}; }").getPointer());<br>
   M.update(<br>
-      Ctx, "f2",<br>
+      "f2",<br>
       build("f2", "namespace ns { void ff() {} class X {}; }").getPointer());<br>
<br>
   FuzzyFindRequest Req;<br>
@@ -144,9 +139,8 @@ TEST(FileIndexTest, IndexMultiASTAndDedu<br>
<br>
 TEST(FileIndexTest, RemoveAST) {<br>
   FileIndex M;<br>
-  auto Ctx = Context::empty();<br>
   M.update(<br>
-      Ctx, "f1",<br>
+      "f1",<br>
       build("f1", "namespace ns { void f() {} class X {}; }").getPointer());<br>
<br>
   FuzzyFindRequest Req;<br>
@@ -154,21 +148,19 @@ TEST(FileIndexTest, RemoveAST) {<br>
   Req.Scopes = {"ns::"};<br>
   EXPECT_THAT(match(M, Req), UnorderedElementsAre("ns::f", "ns::X"));<br>
<br>
-  M.update(Ctx, "f1", nullptr);<br>
+  M.update("f1", nullptr);<br>
   EXPECT_THAT(match(M, Req), UnorderedElementsAre());<br>
 }<br>
<br>
 TEST(FileIndexTest, RemoveNonExisting) {<br>
   FileIndex M;<br>
-  auto Ctx = Context::empty();<br>
-  M.update(Ctx, "no", nullptr);<br>
+  M.update("no", nullptr);<br>
   EXPECT_THAT(match(M, FuzzyFindRequest()), UnorderedElementsAre());<br>
 }<br>
<br>
 TEST(FileIndexTest, IgnoreClassMembers) {<br>
   FileIndex M;<br>
-  auto Ctx = Context::empty();<br>
-  M.update(Ctx, "f1",<br>
+  M.update("f1",<br>
            build("f1", "class X { static int m1; int m2; static void f(); };")<br>
                .getPointer());<br>
<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/IndexTests.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>IndexTests.cpp?rev=323872&r1=<wbr>323871&r2=323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/IndexTests.<wbr>cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/IndexTests.<wbr>cpp Wed Jan 31 05:40:48 2018<br>
@@ -92,8 +92,7 @@ generateNumSymbols(int Begin, int End,<br>
 std::vector<std::string> match(const SymbolIndex &I,<br>
                                const FuzzyFindRequest &Req) {<br>
   std::vector<std::string> Matches;<br>
-  auto Ctx = Context::empty();<br>
-  I.fuzzyFind(Ctx, Req, [&](const Symbol &Sym) {<br>
+  I.fuzzyFind(Req, [&](const Symbol &Sym) {<br>
     Matches.push_back(<br>
         (Sym.Scope + (Sym.Scope.empty() ? "" : "::") + Sym.Name).str());<br>
   });<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>TUSchedulerTests.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TUSchedulerTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>TUSchedulerTests.cpp?rev=<wbr>323872&r1=323871&r2=323872&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>TUSchedulerTests.cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/<wbr>TUSchedulerTests.cpp Wed Jan 31 05:40:48 2018<br>
@@ -7,6 +7,7 @@<br>
 //<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
+#include "Context.h"<br>
 #include "TUScheduler.h"<br>
 #include "TestFS.h"<br>
 #include "gmock/gmock.h"<br>
@@ -20,7 +21,7 @@ namespace clangd {<br>
 using ::testing::Pair;<br>
 using ::testing::Pointee;<br>
<br>
-void ignoreUpdate(Context, llvm::Optional<std::vector<<wbr>DiagWithFixIts>>) {}<br>
+void ignoreUpdate(llvm::Optional<<wbr>std::vector<DiagWithFixIts>>) {}<br>
 void ignoreError(llvm::Error Err) {<br>
   handleAllErrors(std::move(Err)<wbr>, [](const llvm::ErrorInfoBase &) {});<br>
 }<br>
@@ -52,7 +53,7 @@ TEST_F(TUSchedulerTests, MissingFiles) {<br>
   auto Missing = getVirtualTestFilePath("<wbr>missing.cpp");<br>
   changeFile(Missing, "");<br>
<br>
-  S.update(Context::empty(), Added, getInputs(Added, ""), ignoreUpdate);<br>
+  S.update(Added, getInputs(Added, ""), ignoreUpdate);<br>
<br>
   // Assert each operation for missing file is an error (even if it's available<br>
   // in VFS).<br>
@@ -122,46 +123,61 @@ TEST_F(TUSchedulerTests, ManyUpdates) {<br>
     llvm::StringRef AllContents[] = {Contents1, Contents2, Contents3};<br>
     const int AllContentsSize = 3;<br>
<br>
+    // Scheduler may run tasks asynchronously, but should propagate the context.<br>
+    // We stash a nonce in the context, and verify it in the task.<br>
+    static Key<int> NonceKey;<br>
+    int Nonce = 0;<br>
+<br>
     for (int FileI = 0; FileI < FilesCount; ++FileI) {<br>
       for (int UpdateI = 0; UpdateI < UpdatesPerFile; ++UpdateI) {<br>
         auto Contents = AllContents[(FileI + UpdateI) % AllContentsSize];<br>
<br>
         auto File = Files[FileI];<br>
         auto Inputs = getInputs(File, Contents.str());<br>
-        static Key<std::pair<int, int>> FileAndUpdateKey;<br>
-        auto Ctx = Context::empty().derive(<wbr>FileAndUpdateKey,<br>
-                                           std::make_pair(FileI, UpdateI));<br>
-        S.update(std::move(Ctx), File, Inputs,<br>
-                 [FileI, UpdateI, &Mut, &TotalUpdates](<br>
-                     Context Ctx,<br>
-                     llvm::Optional<std::vector<<wbr>DiagWithFixIts>> Diags) {<br>
-                   EXPECT_THAT(Ctx.get(<wbr>FileAndUpdateKey),<br>
-                               Pointee(Pair(FileI, UpdateI)));<br>
-<br>
-                   std::lock_guard<std::mutex> Lock(Mut);<br>
-                   ++TotalUpdates;<br>
-                 });<br>
-<br>
-        S.runWithAST(File, [Inputs, &Mut,<br>
-                            &TotalASTReads](llvm::<wbr>Expected<InputsAndAST> AST) {<br>
-          ASSERT_TRUE((bool)AST);<br>
-          EXPECT_EQ(AST->Inputs.FS, Inputs.FS);<br>
-          EXPECT_EQ(AST->Inputs.<wbr>Contents, Inputs.Contents);<br>
-<br>
-          std::lock_guard<std::mutex> Lock(Mut);<br>
-          ++TotalASTReads;<br>
-        });<br>
-<br>
-        S.runWithPreamble(<br>
-            File, [Inputs, &Mut, &TotalPreambleReads](<br>
-                      llvm::Expected<<wbr>InputsAndPreamble> Preamble) {<br>
-              ASSERT_TRUE((bool)Preamble);<br>
-              EXPECT_EQ(Preamble->Inputs.FS, Inputs.FS);<br>
-              EXPECT_EQ(Preamble->Inputs.<wbr>Contents, Inputs.Contents);<br>
-<br>
-              std::lock_guard<std::mutex> Lock(Mut);<br>
-              ++TotalPreambleReads;<br>
-            });<br>
+<br>
+        {<br>
+          WithContextValue WithNonce(NonceKey, ++Nonce);<br>
+          S.update(File, Inputs,<br>
+                   [Nonce, &Mut, &TotalUpdates](<br>
+                       llvm::Optional<std::vector<<wbr>DiagWithFixIts>> Diags) {<br>
+                     EXPECT_THAT(Context::current()<wbr>.get(NonceKey),<br>
+                                 Pointee(Nonce));<br>
+<br>
+                     std::lock_guard<std::mutex> Lock(Mut);<br>
+                     ++TotalUpdates;<br>
+                   });<br>
+        }<br>
+<br>
+        {<br>
+          WithContextValue WithNonce(NonceKey, ++Nonce);<br>
+          S.runWithAST(File, [Inputs, Nonce, &Mut, &TotalASTReads](<br>
+                                 llvm::Expected<InputsAndAST> AST) {<br>
+            EXPECT_THAT(Context::current()<wbr>.get(NonceKey), Pointee(Nonce));<br>
+<br>
+            ASSERT_TRUE((bool)AST);<br>
+            EXPECT_EQ(AST->Inputs.FS, Inputs.FS);<br>
+            EXPECT_EQ(AST->Inputs.<wbr>Contents, Inputs.Contents);<br>
+<br>
+            std::lock_guard<std::mutex> Lock(Mut);<br>
+            ++TotalASTReads;<br>
+          });<br>
+        }<br>
+<br>
+        {<br>
+          WithContextValue WithNonce(NonceKey, ++Nonce);<br>
+          S.runWithPreamble(<br>
+              File, [Inputs, Nonce, &Mut, &TotalPreambleReads](<br>
+                        llvm::Expected<<wbr>InputsAndPreamble> Preamble) {<br>
+                EXPECT_THAT(Context::current()<wbr>.get(NonceKey), Pointee(Nonce));<br>
+<br>
+                ASSERT_TRUE((bool)Preamble);<br>
+                EXPECT_EQ(Preamble->Inputs.FS, Inputs.FS);<br>
+                EXPECT_EQ(Preamble->Inputs.<wbr>Contents, Inputs.Contents);<br>
+<br>
+                std::lock_guard<std::mutex> Lock(Mut);<br>
+                ++TotalPreambleReads;<br>
+              });<br>
+        }<br>
       }<br>
     }<br>
   } // TUScheduler destructor waits for all operations to finish.<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/TraceTests.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/TraceTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>TraceTests.cpp?rev=323872&r1=<wbr>323871&r2=323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/TraceTests.<wbr>cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/TraceTests.<wbr>cpp Wed Jan 31 05:40:48 2018<br>
@@ -7,7 +7,6 @@<br>
 //<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
-#include "Context.h"<br>
 #include "Trace.h"<br>
<br>
 #include "llvm/ADT/DenseMap.h"<br>
@@ -78,8 +77,8 @@ TEST(TraceTest, SmokeTest) {<br>
     auto JSONTracer = trace::createJSONTracer(OS);<br>
     trace::Session Session(*JSONTracer);<br>
     {<br>
-      trace::Span Tracer(Context::empty(), "A");<br>
-      trace::log(Tracer.Ctx, "B");<br>
+      trace::Span Tracer("A");<br>
+      trace::log("B");<br>
     }<br>
   }<br>
<br>
<br>
Modified: clang-tools-extra/trunk/<wbr>unittests/clangd/XRefsTests.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/XRefsTests.cpp?rev=323872&r1=323871&r2=323872&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-extra/<wbr>trunk/unittests/clangd/<wbr>XRefsTests.cpp?rev=323872&r1=<wbr>323871&r2=323872&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- clang-tools-extra/trunk/<wbr>unittests/clangd/XRefsTests.<wbr>cpp (original)<br>
+++ clang-tools-extra/trunk/<wbr>unittests/clangd/XRefsTests.<wbr>cpp Wed Jan 31 05:40:48 2018<br>
@@ -43,9 +43,9 @@ ParsedAST build(StringRef Code) {<br>
   auto CI =<br>
       createInvocationFromCommandLin<wbr>e({"clang", "-xc++", TestFile.c_str()});<br>
   auto Buf = MemoryBuffer::getMemBuffer(<wbr>Code);<br>
-  auto AST = ParsedAST::Build(<br>
-      Context::empty(), std::move(CI), nullptr, std::move(Buf),<br>
-      std::make_shared<<wbr>PCHContainerOperations>(), vfs::getRealFileSystem());<br>
+  auto AST = ParsedAST::Build(std::move(CI)<wbr>, nullptr, std::move(Buf),<br>
+                              std::make_shared<<wbr>PCHContainerOperations>(),<br>
+                              vfs::getRealFileSystem());<br>
   assert(AST.hasValue());<br>
   return std::move(*AST);<br>
 }<br>
@@ -101,8 +101,7 @@ TEST(HighlightsTest, All) {<br>
   for (const char *Test : Tests) {<br>
     Annotations T(Test);<br>
     auto AST = build(T.code());<br>
-    EXPECT_THAT(<wbr>findDocumentHighlights(<wbr>Context::empty(), AST, T.point()),<br>
-                HighlightsFrom(T))<br>
+    EXPECT_THAT(<wbr>findDocumentHighlights(AST, T.point()), HighlightsFrom(T))<br>
         << Test;<br>
   }<br>
 }<br>
@@ -222,7 +221,7 @@ TEST(GoToDefinition, All) {<br>
   for (const char *Test : Tests) {<br>
     Annotations T(Test);<br>
     auto AST = build(T.code());<br>
-    EXPECT_THAT(findDefinitions(<wbr>Context::empty(), AST, T.point()),<br>
+    EXPECT_THAT(findDefinitions(<wbr>AST, T.point()),<br>
                 ElementsAre(RangeIs(T.range())<wbr>))<br>
         << Test;<br>
   }<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>