<div dir="ltr">That sounds great - I think using the same default std as clang is what we want.<div>Unfortunately, passing --std=c++11 isn't ideal - we want to keep using the existing logic to derive the std from the language of the input file.</div><div>For now r318327 explicitly sets the target triple to -pc-, which should get us back to uniform behavior across platforms.</div><div>This is obviously a hack and makes for a rocky -std transition, I'll look into this.<br></div><div><br></div><div>(All this defaulting only happens if the user hasn't set up a compilation database to tell clangd how to build their project - unfortunately the tests do this)</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 15, 2017 at 8:13 PM, Robinson, Paul <span dir="ltr"><<a href="mailto:paul.robinson@sony.com" target="_blank">paul.robinson@sony.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-US" link="blue" vlink="purple">
<div class="m_4640626826386712023WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Thanks for looking into it.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I should point out that Clang is planning to update the default â€“std for everyone, hopefully before 6.0 branches, and it might be best to be ready for that
 rather than sticking with C++98.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">--paulr<u></u><u></u></span></p>
<p class="MsoNormal"><a name="m_4640626826386712023__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></a></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> Sam McCall [mailto:<a href="mailto:sam.mccall@gmail.com" target="_blank">sam.mccall@gmail.com</a>]
<br>
<b>Sent:</b> Wednesday, November 15, 2017 11:09 AM<br>
<b>To:</b> Robinson, Paul; Galina Kistanova<br>
<b>Cc:</b> cfe-commits (<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>)<br>
<b>Subject:</b> Re: [clang-tools-extra] r318287 - [clangd] Support returning a limited number of completion results.<u></u><u></u></span></p>
</div>
</div><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">Sorry about these - I've finally understood what's going on.<u></u><u></u></p>
<div>
<p class="MsoNormal">It looks like the PS4 has a different default --std, which probably doesn't make sense for clangd. I'll override it.<u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Wed, Nov 15, 2017 at 7:49 PM, Robinson, Paul <<a href="mailto:paul.robinson@sony.com" target="_blank">paul.robinson@sony.com</a>> wrote:<u></u><u></u></p>
<p class="MsoNormal">Hi Sam,<br>
It looks like llvm-clang-lld-x86_64-scei-<wbr>ps4-windows10pro-fast has been<br>
failing a couple of clangd tests ever since this went in.<br>
<br>
<a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/13517" target="_blank">http://lab.llvm.org:8011/<wbr>builders/llvm-clang-lld-x86_<wbr>64-scei-ps4-windows10pro-fast/<wbr>builds/13517</a><br>
<br>
Please fix or revert ASAP when bots go red.  Failures like this interfere<br>
with our CI process.<br>
<br>
Thanks,<br>
--paulr<br>
PS4 code owner<br>
<br>
<br>
> -----Original Message-----<br>
> From: cfe-commits [mailto:<a href="mailto:cfe-commits-bounces@lists.llvm.org" target="_blank">cfe-commits-bounces@<wbr>lists.llvm.org</a>] On Behalf Of<br>
> Sam McCall via cfe-commits<br>
> Sent: Wednesday, November 15, 2017 1:16 AM<br>
> To: <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
> Subject: [clang-tools-extra] r318287 - [clangd] Support returning a<br>
> limited number of completion results.<br>
><br>
> Author: sammccall<br>
> Date: Wed Nov 15 01:16:29 2017<br>
> New Revision: 318287<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=318287&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project?rev=318287&view=rev</a><br>
> Log:<br>
> [clangd] Support returning a limited number of completion results.<br>
><br>
> Summary:<br>
> All results are scored, we only process CodeCompletionStrings for the<br>
> winners.<br>
> We now return CompletionList rather than CompletionItem[] (both are<br>
> valid).<br>
> sortText is now based on CodeCompletionResult::<wbr>orderedName (mostly the<br>
> same).<br>
><br>
> This is the first clangd-only completion option, so plumbing changed.<br>
> It requires a small clangd patch (exposing<br>
> CodeCompletionResult::<wbr>orderedName).<br>
><br>
> (This can't usefully be enabled yet: we don't support server-side<br>
> filtering)<br>
><br>
> Reviewers: ilya-biryukov<br>
><br>
> Subscribers: cfe-commits<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D39852" target="_blank">
https://reviews.llvm.org/<wbr>D39852</a><br>
><br>
> Modified:<br>
>  Â  Â clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.cpp<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/Protocol.cpp<br>
>  Â  Â clang-tools-extra/trunk/<wbr>clangd/Protocol.h<br>
>  Â  Â clang-tools-extra/trunk/test/<wbr>clangd/authority-less-uri.test<br>
>  Â  Â clang-tools-extra/trunk/test/<wbr>clangd/completion-items-kinds.<wbr>test<br>
>  Â  Â clang-tools-extra/trunk/test/<wbr>clangd/completion-priorities.<wbr>test<br>
>  Â  Â clang-tools-extra/trunk/test/<wbr>clangd/completion-qualifiers.<wbr>test<br>
>  Â  Â clang-tools-extra/trunk/test/<wbr>clangd/completion-snippet.test<br>
>  Â  Â clang-tools-extra/trunk/test/<wbr>clangd/completion.test<br>
>  Â  Â clang-tools-extra/trunk/test/<wbr>clangd/protocol.test<br>
>  Â  Â clang-tools-extra/trunk/<wbr>unittests/clangd/ClangdTests.<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-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/<wbr>ClangdLSPServer.cpp?rev=<wbr>318287&r1=318286&r2=318287&<wbr>view<br>
> =diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.cpp (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdLSPServer.cpp Wed Nov 15 01:16:29<br>
> 2017<br>
> @@ -195,15 +195,15 @@ void ClangdLSPServer::onCodeAction(<wbr>Ctx C<br>
>  }<br>
><br>
>  void ClangdLSPServer::onCompletion(<wbr>Ctx C, TextDocumentPositionParams<br>
> &Params) {<br>
> -  auto Items = Server<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â .codeComplete(Params.<wbr>textDocument.uri.file,<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â Position{Params.position.<wbr>line,<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Params.position.character})<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â .get() // FIXME(ibiryukov): This could be made async<br>
> if we<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  // had an API that would allow to attach<br>
> callbacks to<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  // futures returned by ClangdServer.<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â .Value;<br>
> -  C.reply(json::ary(Items));<br>
> +  auto List = Server<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  .codeComplete(<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Params.textDocument.uri.file,<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Position{Params.position.line,<br>
> Params.position.character})<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  .get() // FIXME(ibiryukov): This could be made async if<br>
> we<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â // had an API that would allow to attach<br>
> callbacks to<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â // futures returned by ClangdServer.<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  .Value;<br>
> +  C.reply(List);<br>
>  }<br>
><br>
>  void ClangdLSPServer::<wbr>onSignatureHelp(Ctx C,<br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/<wbr>ClangdServer.cpp?rev=318287&<wbr>r1=318286&r2=318287&view=di<br>
> ff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp Wed Nov 15 01:16:29<br>
> 2017<br>
> @@ -222,11 +222,11 @@ std::future<void> ClangdServer::forceRep<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â std::move(TaggedFS));<br>
>  }<br>
><br>
> -std::future<Tagged<std::<wbr>vector<CompletionItem>>><br>
> +std::future<Tagged<<wbr>CompletionList>><br>
>  ClangdServer::codeComplete(<wbr>PathRef File, Position Pos,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â llvm::Optional<StringRef> OverridenContents,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS) {<br>
> -  using ResultType = Tagged<std::vector<<wbr>CompletionItem>>;<br>
> +  using ResultType = Tagged<CompletionList>;<br>
><br>
>  Â  std::promise<ResultType> ResultPromise;<br>
><br>
> @@ -242,11 +242,10 @@ ClangdServer::codeComplete(<wbr>PathRef File,<br>
>  }<br>
><br>
>  void ClangdServer::codeComplete(<br>
> -  Â  UniqueFunction<void(Tagged<<wbr>std::vector<CompletionItem>>)> Callback,<br>
> -  Â  PathRef File, Position Pos, llvm::Optional<StringRef><br>
> OverridenContents,<br>
> +  Â  UniqueFunction<void(Tagged<<wbr>CompletionList>)> Callback, PathRef File,<br>
> +  Â  Position Pos, llvm::Optional<StringRef> OverridenContents,<br>
>  Â  Â  IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS) {<br>
> -  using CallbackType =<br>
> -  Â  Â  UniqueFunction<void(Tagged<<wbr>std::vector<CompletionItem>>)><wbr>;<br>
> +  using CallbackType = UniqueFunction<void(Tagged<<wbr>CompletionList>)>;<br>
><br>
>  Â  std::string Contents;<br>
>  Â  if (OverridenContents) {<br>
> @@ -283,7 +282,7 @@ void ClangdServer::codeComplete(<br>
>  Â  Â  Â  Â  // FIXME(ibiryukov): even if Preamble is non-null, we may want to<br>
> check<br>
>  Â  Â  Â  Â  // both the old and the new version in case only one of them<br>
> matches.<br>
><br>
> -  Â  Â  Â  std::vector<CompletionItem> Result = clangd::codeComplete(<br>
> +  Â  Â  Â  CompletionList Result = clangd::codeComplete(<br>
>  Â  Â  Â  Â  Â  Â  File, Resources->getCompileCommand()<wbr>,<br>
>  Â  Â  Â  Â  Â  Â  Preamble ? &Preamble->Preamble : nullptr, Contents, Pos,<br>
>  Â  Â  Â  Â  Â  Â  TaggedFS.Value, PCHs, CodeCompleteOpts, Logger);<br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdServer.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/<wbr>ClangdServer.h?rev=318287&r1=<wbr>318286&r2=318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdServer.h (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdServer.h Wed Nov 15 01:16:29 2017<br>
> @@ -251,18 +251,17 @@ public:<br>
>  Â  /// This method should only be called for currently tracked files.<br>
> However, it<br>
>  Â  /// is safe to call removeDocument for \p File after this method<br>
> returns, even<br>
>  Â  /// while returned future is not yet ready.<br>
> -  std::future<Tagged<std::<wbr>vector<CompletionItem>>><br>
> +  std::future<Tagged<<wbr>CompletionList>><br>
>  Â  codeComplete(PathRef File, Position Pos,<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<br>
> thread<br>
>  Â  /// when codeComplete results become available.<br>
> -  void codeComplete(<br>
> -  Â  Â  UniqueFunction<void(Tagged<<wbr>std::vector<CompletionItem>>)> Callback,<br>
> -  Â  Â  PathRef File, Position Pos,<br>
> -  Â  Â  llvm::Optional<StringRef> OverridenContents = llvm::None,<br>
> -  Â  Â  IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS = nullptr);<br>
> +  void codeComplete(UniqueFunction<<wbr>void(Tagged<CompletionList>)><br>
> Callback,<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  PathRef File, Position Pos,<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  llvm::Optional<StringRef> OverridenContents =<br>
> llvm::None,<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  IntrusiveRefCntPtr<vfs::<wbr>FileSystem> *UsedFS =<br>
> nullptr);<br>
><br>
>  Â  /// Provide signature help for \p File at \p Pos. If \p<br>
> OverridenContents is<br>
>  Â  /// not None, they will used only for signature help, i.e. no<br>
> diagnostics<br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/ClangdUnit.<wbr>cpp?rev=318287&r1=318286&r2=<wbr>318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp Wed Nov 15 01:16:29 2017<br>
> @@ -368,28 +368,90 @@ std::string getDocumentation(const CodeC<br>
>  Â  return Result;<br>
>  }<br>
><br>
> +/// A scored code completion result.<br>
> +/// It may be promoted to a CompletionItem if it's among the top-ranked<br>
> results.<br>
> +struct CompletionCandidate {<br>
> +  CompletionCandidate(<wbr>CodeCompletionResult &Result)<br>
> +  Â  Â  : Result(&Result), Score(score(Result)) {}<br>
> +<br>
> +  CodeCompletionResult *Result;<br>
> +  // Higher score is worse. FIXME: use a more natural scale!<br>
> +  int Score;<br>
> +<br>
> +  // Comparison reflects rank: better candidates are smaller.<br>
> +  bool operator<(const CompletionCandidate &C) const {<br>
> +  Â  if (Score != C.Score)<br>
> +  Â  Â  return Score < C.Score;<br>
> +  Â  return *Result < *C.Result;<br>
> +  }<br>
> +<br>
> +  std::string sortText() const {<br>
> +  Â  // Fill in the sortText of the CompletionItem.<br>
> +  Â  assert(Score <= 999999 && "Expecting score to have at most 6-<br>
> digits");<br>
> +  Â  std::string S, NameStorage;<br>
> +  Â  StringRef Name = Result->getOrderedName(<wbr>NameStorage);<br>
> +  Â  llvm::raw_string_ostream(S)<br>
> +  Â  Â  Â  << llvm::format("%06d%.*s", Score, Name.size(), Name.data());<br>
> +  Â  return S;<br>
> +  }<br>
> +<br>
> +private:<br>
> +  static int score(const CodeCompletionResult &Result) {<br>
> +  Â  int Score = Result.Priority;<br>
> +  Â  // Fill in the sortText of the CompletionItem.<br>
> +  Â  assert(Score <= 99999 && "Expecting code completion result "<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â "priority to have at most 5-digits");<br>
> +<br>
> +  Â  const int Penalty = 100000;<br>
> +  Â  switch (static_cast<<wbr>CXAvailabilityKind>(Result.<wbr>Availability)) {<br>
> +  Â  case CXAvailability_Available:<br>
> +  Â  Â  // No penalty.<br>
> +  Â  Â  break;<br>
> +  Â  case CXAvailability_Deprecated:<br>
> +  Â  Â  Score += Penalty;<br>
> +  Â  Â  break;<br>
> +  Â  case CXAvailability_NotAccessible:<br>
> +  Â  Â  Score += 2 * Penalty;<br>
> +  Â  Â  break;<br>
> +  Â  case CXAvailability_NotAvailable:<br>
> +  Â  Â  Score += 3 * Penalty;<br>
> +  Â  Â  break;<br>
> +  Â  }<br>
> +  Â  return Score;<br>
> +  }<br>
> +};<br>
> +<br>
>  class CompletionItemsCollector : public CodeCompleteConsumer {<br>
>  public:<br>
> -  CompletionItemsCollector(const clang::CodeCompleteOptions<br>
> &CodeCompleteOpts,<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â std::vector<CompletionItem> &Items)<br>
> -  Â  Â  : CodeCompleteConsumer(<wbr>CodeCompleteOpts, /*OutputIsBinary=*/false),<br>
> -  Â  Â  Â  Items(Items),<br>
> +  CompletionItemsCollector(const clangd::CodeCompleteOptions<br>
> &CodeCompleteOpts,<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â CompletionList &Items)<br>
> +  Â  Â  : CodeCompleteConsumer(<wbr>CodeCompleteOpts.<wbr>getClangCompleteOpts(),<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â /*OutputIsBinary=*/false),<br>
> +  Â  Â  Â  ClangdOpts(CodeCompleteOpts), Items(Items),<br>
><br>
> Allocator(std::make_shared<<wbr>clang::<wbr>GlobalCodeCompletionAllocator><wbr>()),<br>
>  Â  Â  Â  Â  CCTUInfo(Allocator) {}<br>
><br>
>  Â  void ProcessCodeCompleteResults(<wbr>Sema &S, CodeCompletionContext Context,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  CodeCompletionResult *Results,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  unsigned NumResults) override final {<br>
> -  Â  Items.reserve(NumResults);<br>
> +  Â  std::priority_queue<<wbr>CompletionCandidate> Candidates;<br>
>  Â  Â  for (unsigned I = 0; I < NumResults; ++I) {<br>
> -  Â  Â  auto &Result = Results[I];<br>
> -  Â  Â  const auto *CCS = Result.<wbr>CreateCodeCompletionString(<br>
> +  Â  Â  Candidates.emplace(Results[I])<wbr>;<br>
> +  Â  Â  if (ClangdOpts.Limit && Candidates.size() > ClangdOpts.Limit) {<br>
> +  Â  Â  Â  Candidates.pop();<br>
> +  Â  Â  Â  Items.isIncomplete = true;<br>
> +  Â  Â  }<br>
> +  Â  }<br>
> +  Â  while (!Candidates.empty()) {<br>
> +  Â  Â  auto &Candidate = Candidates.top();<br>
> +  Â  Â  const auto *CCS = Candidate.Result-><wbr>CreateCodeCompletionString(<br>
>  Â  Â  Â  Â  Â  S, Context, *Allocator, CCTUInfo,<br>
>  Â  Â  Â  Â  Â  CodeCompleteOpts.<wbr>IncludeBriefComments);<br>
>  Â  Â  Â  assert(CCS && "Expected the CodeCompletionString to be non-null");<br>
> -  Â  Â  Items.push_back(<wbr>ProcessCodeCompleteResult(<wbr>Result, *CCS));<br>
> +  Â  Â  Items.items.push_back(<wbr>ProcessCodeCompleteResult(<wbr>Candidate, *CCS));<br>
> +  Â  Â  Candidates.pop();<br>
>  Â  Â  }<br>
> -  Â  std::sort(Items.begin(), Items.end());<br>
> +  Â  std::reverse(Items.items.<wbr>begin(), Items.items.end());<br>
>  Â  }<br>
><br>
>  Â  GlobalCodeCompletionAllocator &getAllocator() override { return<br>
> *Allocator; }<br>
> @@ -398,7 +460,7 @@ public:<br>
><br>
>  private:<br>
>  Â  CompletionItem<br>
> -  ProcessCodeCompleteResult(<wbr>const CodeCompletionResult &Result,<br>
> +  ProcessCodeCompleteResult(<wbr>const CompletionCandidate &Candidate,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  const CodeCompletionString &CCS) const {<br>
><br>
>  Â  Â  // Adjust this to InsertTextFormat::Snippet iff we encounter a<br>
> @@ -407,15 +469,14 @@ private:<br>
>  Â  Â  Item.insertTextFormat = InsertTextFormat::PlainText;<br>
><br>
>  Â  Â  Item.documentation = getDocumentation(CCS);<br>
> +  Â  Item.sortText = Candidate.sortText();<br>
><br>
>  Â  Â  // Fill in the label, detail, insertText and filterText fields of the<br>
>  Â  Â  // CompletionItem.<br>
>  Â  Â  ProcessChunks(CCS, Item);<br>
><br>
>  Â  Â  // Fill in the kind field of the CompletionItem.<br>
> -  Â  Item.kind = getKind(Result.Kind, Result.CursorKind);<br>
> -<br>
> -  Â  FillSortText(CCS, Item);<br>
> +  Â  Item.kind = getKind(Candidate.Result-><wbr>Kind, Candidate.Result-<br>
> >CursorKind);<br>
><br>
>  Â  Â  return Item;<br>
>  Â  }<br>
> @@ -423,42 +484,8 @@ private:<br>
>  Â  virtual void ProcessChunks(const CodeCompletionString &CCS,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â CompletionItem &Item) const = 0;<br>
><br>
> -  static int GetSortPriority(const CodeCompletionString &CCS) {<br>
> -  Â  int Score = CCS.getPriority();<br>
> -  Â  // Fill in the sortText of the CompletionItem.<br>
> -  Â  assert(Score <= 99999 && "Expecting code completion result "<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â "priority to have at most 5-digits");<br>
> -<br>
> -  Â  const int Penalty = 100000;<br>
> -  Â  switch (static_cast<<wbr>CXAvailabilityKind>(CCS.<wbr>getAvailability())) {<br>
> -  Â  case CXAvailability_Available:<br>
> -  Â  Â  // No penalty.<br>
> -  Â  Â  break;<br>
> -  Â  case CXAvailability_Deprecated:<br>
> -  Â  Â  Score += Penalty;<br>
> -  Â  Â  break;<br>
> -  Â  case CXAvailability_NotAccessible:<br>
> -  Â  Â  Score += 2 * Penalty;<br>
> -  Â  Â  break;<br>
> -  Â  case CXAvailability_NotAvailable:<br>
> -  Â  Â  Score += 3 * Penalty;<br>
> -  Â  Â  break;<br>
> -  Â  }<br>
> -<br>
> -  Â  return Score;<br>
> -  }<br>
> -<br>
> -  static void FillSortText(const CodeCompletionString &CCS,<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â CompletionItem &Item) {<br>
> -  Â  int Priority = GetSortPriority(CCS);<br>
> -  Â  // Fill in the sortText of the CompletionItem.<br>
> -  Â  assert(Priority <= 999999 &&<br>
> -  Â  Â  Â  Â  Â "Expecting sort priority to have at most 6-digits");<br>
> -  Â  llvm::raw_string_ostream(Item.<wbr>sortText)<br>
> -  Â  Â  Â  << llvm::format("%06d%s", Priority, Item.filterText.c_str());<br>
> -  }<br>
> -<br>
> -  std::vector<CompletionItem> &Items;<br>
> +  clangd::CodeCompleteOptions ClangdOpts;<br>
> +  CompletionList &Items;<br>
>  Â  std::shared_ptr<clang::<wbr>GlobalCodeCompletionAllocator> Allocator;<br>
>  Â  CodeCompletionTUInfo CCTUInfo;<br>
><br>
> @@ -474,8 +501,8 @@ class PlainTextCompletionItemsCollec<wbr>tor<br>
><br>
>  public:<br>
>  Â  PlainTextCompletionItemsCollec<wbr>tor(<br>
> -  Â  Â  const clang::CodeCompleteOptions &CodeCompleteOpts,<br>
> -  Â  Â  std::vector<CompletionItem> &Items)<br>
> +  Â  Â  const clangd::CodeCompleteOptions &CodeCompleteOpts,<br>
> +  Â  Â  CompletionList &Items)<br>
>  Â  Â  Â  : CompletionItemsCollector(<wbr>CodeCompleteOpts, Items) {}<br>
><br>
>  private:<br>
> @@ -511,8 +538,8 @@ class SnippetCompletionItemsCollecto<wbr>r fi<br>
><br>
>  public:<br>
>  Â  SnippetCompletionItemsCollecto<wbr>r(<br>
> -  Â  Â  const clang::CodeCompleteOptions &CodeCompleteOpts,<br>
> -  Â  Â  std::vector<CompletionItem> &Items)<br>
> +  Â  Â  const clangd::CodeCompleteOptions &CodeCompleteOpts,<br>
> +  Â  Â  CompletionList &Items)<br>
>  Â  Â  Â  : CompletionItemsCollector(<wbr>CodeCompleteOpts, Items) {}<br>
><br>
>  private:<br>
> @@ -795,7 +822,8 @@ clangd::CodeCompleteOptions::<wbr>CodeComplet<br>
>  Â  Â  Â  IncludeMacros(IncludeMacros), IncludeGlobals(IncludeGlobals)<wbr>,<br>
>  Â  Â  Â  IncludeBriefComments(<wbr>IncludeBriefComments) {}<br>
><br>
> -clang::CodeCompleteOptions<br>
> clangd::CodeCompleteOptions::<wbr>getClangCompleteOpts() {<br>
> +clang::CodeCompleteOptions<br>
> +clangd::CodeCompleteOptions::<wbr>getClangCompleteOpts() const {<br>
>  Â  clang::CodeCompleteOptions Result;<br>
>  Â  Result.IncludeCodePatterns = EnableSnippets && IncludeCodePatterns;<br>
>  Â  Result.IncludeMacros = IncludeMacros;<br>
> @@ -805,25 +833,24 @@ clang::CodeCompleteOptions clangd::CodeC<br>
>  Â  return Result;<br>
>  }<br>
><br>
> -std::vector<CompletionItem><br>
> +CompletionList<br>
>  clangd::codeComplete(PathRef FileName, const tooling::CompileCommand<br>
> &Command,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â PrecompiledPreamble const *Preamble, StringRef<br>
> Contents,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â Position Pos, IntrusiveRefCntPtr<vfs::<wbr>FileSystem><br>
> VFS,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â std::shared_ptr<<wbr>PCHContainerOperations> PCHs,<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â clangd::CodeCompleteOptions Opts, clangd::Logger<br>
> &Logger) {<br>
> -  std::vector<CompletionItem> Results;<br>
> +  CompletionList Results;<br>
>  Â  std::unique_ptr<<wbr>CodeCompleteConsumer> Consumer;<br>
> -  clang::CodeCompleteOptions ClangCompleteOpts =<br>
> Opts.getClangCompleteOpts();<br>
>  Â  if (Opts.EnableSnippets) {<br>
> -  Â  Consumer = llvm::make_unique<<wbr>SnippetCompletionItemsCollecto<wbr>r>(<br>
> -  Â  Â  Â  ClangCompleteOpts, Results);<br>
> +  Â  Consumer =<br>
> +  Â  Â  Â  llvm::make_unique<<wbr>SnippetCompletionItemsCollecto<wbr>r>(Opts,<br>
> Results);<br>
>  Â  } else {<br>
> -  Â  Consumer = llvm::make_unique<<wbr>PlainTextCompletionItemsCollec<wbr>tor>(<br>
> -  Â  Â  Â  ClangCompleteOpts, Results);<br>
> +  Â  Consumer =<br>
> +  Â  Â  Â  llvm::make_unique<<wbr>PlainTextCompletionItemsCollec<wbr>tor>(Opts,<br>
> Results);<br>
>  Â  }<br>
> -  invokeCodeComplete(std::move(<wbr>Consumer), ClangCompleteOpts, FileName,<br>
> Command,<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â Preamble, Contents, Pos, std::move(VFS),<br>
> std::move(PCHs),<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â Logger);<br>
> +  invokeCodeComplete(std::move(<wbr>Consumer), Opts.getClangCompleteOpts(),<br>
> FileName,<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â Command, Preamble, Contents, Pos, std::move(VFS),<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â std::move(PCHs), Logger);<br>
>  Â  return Results;<br>
>  }<br>
><br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/ClangdUnit.<wbr>h?rev=318287&r1=318286&r2=<wbr>318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h Wed Nov 15 01:16:29 2017<br>
> @@ -263,7 +263,7 @@ struct CodeCompleteOptions {<br>
>  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  bool IncludeBriefComments);<br>
><br>
>  Â  /// Returns options that can be passed to clang's completion engine.<br>
> -  clang::CodeCompleteOptions getClangCompleteOpts();<br>
> +  clang::CodeCompleteOptions getClangCompleteOpts() const;<br>
><br>
>  Â  /// When true, completion items will contain expandable code snippets<br>
> in<br>
>  Â  /// completion (e.g.  `return ${1:expression}` or `foo(${1:int a},<br>
> ${2:int<br>
> @@ -285,10 +285,14 @@ struct CodeCompleteOptions {<br>
>  Â  /// FIXME(ibiryukov): it looks like turning this option on<br>
> significantly slows<br>
>  Â  /// down completion, investigate if it can be made faster.<br>
>  Â  bool IncludeBriefComments = true;<br>
> +<br>
> +  /// Limit the number of results returned (0 means no limit).<br>
> +  /// If more results are available, we set CompletionList.isIncomplete.<br>
> +  size_t Limit = 0;<br>
>  };<br>
><br>
>  /// Get code completions at a specified \p Pos in \p FileName.<br>
> -std::vector<CompletionItem><br>
> +CompletionList<br>
>  codeComplete(PathRef FileName, const tooling::CompileCommand &Command,<br>
>  Â  Â  Â  Â  Â  Â  Â PrecompiledPreamble const *Preamble, StringRef Contents,<br>
>  Â  Â  Â  Â  Â  Â  Â Position Pos, IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS,<br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/Protocol.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/Protocol.<wbr>cpp?rev=318287&r1=318286&r2=<wbr>318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>clangd/Protocol.cpp (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/Protocol.cpp Wed Nov 15 01:16:29 2017<br>
> @@ -1043,6 +1043,13 @@ bool clangd::operator<(const CompletionI<br>
>  Â  Â  Â  Â  Â (R.sortText.empty() ? R.label : R.sortText);<br>
>  }<br>
><br>
> +json::Expr CompletionList::unparse(const CompletionList &L) {<br>
> +  return json::obj{<br>
> +  Â  Â  {"isIncomplete", L.isIncomplete},<br>
> +  Â  Â  {"items", json::ary(L.items)},<br>
> +  };<br>
> +}<br>
> +<br>
>  json::Expr ParameterInformation::unparse(<wbr>const ParameterInformation &PI)<br>
> {<br>
>  Â  assert(!PI.label.empty() && "parameter information label is required");<br>
>  Â  json::obj Result{{"label", PI.label}};<br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/Protocol.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/Protocol.h?<wbr>rev=318287&r1=318286&r2=<wbr>318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>clangd/Protocol.h (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/Protocol.h Wed Nov 15 01:16:29 2017<br>
> @@ -547,6 +547,18 @@ struct CompletionItem {<br>
><br>
>  bool operator<(const CompletionItem &, const CompletionItem &);<br>
><br>
> +/// Represents a collection of completion items to be presented in the<br>
> editor.<br>
> +struct CompletionList {<br>
> +  /// The list is not complete. Further typing should result in<br>
> recomputing the<br>
> +  /// list.<br>
> +  bool isIncomplete = false;<br>
> +<br>
> +  /// The completion items.<br>
> +  std::vector<CompletionItem> items;<br>
> +<br>
> +  static json::Expr unparse(const CompletionList &);<br>
> +};<br>
> +<br>
>  /// A single parameter of a particular signature.<br>
>  struct ParameterInformation {<br>
><br>
><br>
> Modified: clang-tools-extra/trunk/test/<wbr>clangd/authority-less-uri.test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/test/clangd/<wbr>authority-less-<br>
> uri.test?rev=318287&r1=318286&<wbr>r2=318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/test/<wbr>clangd/authority-less-uri.test (original)<br>
> +++ clang-tools-extra/trunk/test/<wbr>clangd/authority-less-uri.test Wed Nov 15<br>
> 01:16:29 2017<br>
> @@ -17,14 +17,17 @@ Content-Length: 146<br>
>  #<br>
>  #  Â  Â  CHECK:  "id": 1,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -#  Â  Â  CHECK:  Â  Â  "filterText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 7,<br>
> -# CHECK-NEXT:  Â  Â  "label": "fake::",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000075fake"<br>
> -#  Â  Â  CHECK:  ]<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "filterText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 7,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "fake::",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000075fake"<br>
> +#  Â  Â  CHECK:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
>  Content-Length: 172<br>
><br>
><br>
> {"jsonrpc":"2.0","id":2,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"uri":"<a>file:///<wbr>main.cpp</a>","position":{<br>
> "line":3,"character":5}}}<br>
> @@ -32,14 +35,17 @@ Content-Length: 172<br>
>  #<br>
>  #  Â  Â  CHECK:  "id": 2,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -#  Â  Â  CHECK:  Â  Â  "filterText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 7,<br>
> -# CHECK-NEXT:  Â  Â  "label": "fake::",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000075fake"<br>
> -#  Â  Â  CHECK:  ]<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "filterText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 7,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "fake::",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000075fake"<br>
> +#  Â  Â  CHECK:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
>  Content-Length: 44<br>
><br>
>  {"jsonrpc":"2.0","id":3,"<wbr>method":"shutdown"}<br>
><br>
> Modified: clang-tools-extra/trunk/test/<wbr>clangd/completion-items-kinds.<wbr>test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/test/clangd/<wbr>completion-items-<br>
> kinds.test?rev=318287&r1=<wbr>318286&r2=318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/test/<wbr>clangd/completion-items-kinds.<wbr>test<br>
> (original)<br>
> +++ clang-tools-extra/trunk/test/<wbr>clangd/completion-items-kinds.<wbr>test Wed<br>
> Nov 15 01:16:29 2017<br>
> @@ -11,7 +11,7 @@ Content-Length: 148<br>
><br>
><br>
> {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>4,"character":7}}}<br>
>  Content-Length: 58<br>
> -# CHECK: {"id":1,"jsonrpc":"2.0","<wbr>result":[<br>
> +# CHECK: {"id":1,"jsonrpc":"2.0","<wbr>result":{"isIncomplete":false,<wbr>"items":<br>
>  #<br>
>  # Keyword<br>
>  # CHECK-DAG:<br>
> {"filterText":"int","<wbr>insertText":"int","<wbr>insertTextFormat":1,"kind":14,<wbr>"lab<br>
> el":"int","sortText":"<wbr>000050int"}<br>
> @@ -31,6 +31,6 @@ Content-Length: 58<br>
>  # Function<br>
>  # CHECK-DAG:<br>
> {"detail":"int","filterText":"<wbr>function","insertText":"<wbr>function()","insertT<br>
> extFormat":1,"kind":3,"label":<wbr>"function()","sortText":"<wbr>000012function"}<br>
>  #<br>
> -# CHECK-SAME: ]}<br>
> +# CHECK-SAME: ]}}<br>
><br>
>  {"jsonrpc":"2.0","id":3,"<wbr>method":"shutdown","params":<wbr>null}<br>
><br>
> Modified: clang-tools-extra/trunk/test/<wbr>clangd/completion-priorities.<wbr>test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/test/clangd/<wbr>completion-<br>
> priorities.test?rev=318287&r1=<wbr>318286&r2=318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/test/<wbr>clangd/completion-priorities.<wbr>test<br>
> (original)<br>
> +++ clang-tools-extra/trunk/test/<wbr>clangd/completion-priorities.<wbr>test Wed Nov<br>
> 15 01:16:29 2017<br>
> @@ -15,69 +15,74 @@ Content-Length: 151<br>
><br>
> {"jsonrpc":"2.0","id":2,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>12,"character":8}}<br>
> }<br>
>  #  Â  Â  CHECK:  "id": 2,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "void",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "priv",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "priv",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "priv()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000034priv"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "void",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "prot",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "prot",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "prot()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000034prot"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "void",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "pub",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "pub",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "pub()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000034pub"<br>
> -# CHECK-NEXT:  Â  },<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "void",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "priv",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "priv",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "priv()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000034priv"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "void",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "prot",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "prot",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "prot()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000034prot"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "void",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "pub",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "pub",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "pub()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000034pub"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
>  Content-Length: 151<br>
><br>
><br>
> {"jsonrpc":"2.0","id":3,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>17,"character":4}}<br>
> }<br>
>  #  Â  Â  CHECK:  "id": 3,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "void",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "pub",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "pub",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "pub()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000034pub"<br>
> -# CHECK-NEXT:  Â  },<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "void",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "pub",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "pub",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "pub()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000034pub"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
>  # priv() and prot() are at the end of the list<br>
> -# CHECK-NEXT:  Â  {<br>
> -#  Â  Â  CHECK:  Â  Â  "detail": "void",<br>
> -#  Â  Â  CHECK:  Â  Â  "filterText": "priv",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "priv",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "priv()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "200034priv"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "void",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "prot",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "prot",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "prot()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "200034prot"<br>
> -# CHECK-NEXT:  Â  }<br>
> -# CHECK-NEXT:  ]<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "detail": "void",<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "filterText": "priv",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "priv",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "priv()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "200034priv"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "void",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "prot",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "prot",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "prot()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "200034prot"<br>
> +# CHECK-NEXT:  Â  Â  }<br>
> +# CHECK-NEXT:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
>  Content-Length: 58<br>
><br>
>  {"jsonrpc":"2.0","id":4,"<wbr>method":"shutdown","params":<wbr>null}<br>
><br>
> Modified: clang-tools-extra/trunk/test/<wbr>clangd/completion-qualifiers.<wbr>test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/test/clangd/<wbr>completion-<br>
> qualifiers.test?rev=318287&r1=<wbr>318286&r2=318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/test/<wbr>clangd/completion-qualifiers.<wbr>test<br>
> (original)<br>
> +++ clang-tools-extra/trunk/test/<wbr>clangd/completion-qualifiers.<wbr>test Wed Nov<br>
> 15 01:16:29 2017<br>
> @@ -10,37 +10,40 @@ Content-Length: 151<br>
><br>
> {"jsonrpc":"2.0","id":2,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>11,"character":8}}<br>
> }<br>
>  #  Â  Â  CHECK:  "id": 2,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
>  # Eligible const functions are at the top of the list.<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "int",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "bar",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "bar",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "bar() const",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000037bar"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "int",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "foo",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "foo",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "Foo::foo() const",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000037foo"<br>
> -# CHECK-NEXT:  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "int",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "bar",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "bar",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "bar() const",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000037bar"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "int",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "foo",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "foo",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "Foo::foo() const",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000037foo"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
>  # Ineligible non-const function is at the bottom of the list.<br>
> -# CHECK-NEXT:  Â  {<br>
> -#  Â  Â  CHECK:  Â  Â  "detail": "int",<br>
> -#  Â  Â  CHECK:  Â  Â  "filterText": "foo",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "foo",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "foo() const",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "200035foo"<br>
> -# CHECK-NEXT:  Â  }<br>
> -# CHECK-NEXT:  ]<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "detail": "int",<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "filterText": "foo",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "foo",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "foo() const",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "200035foo"<br>
> +# CHECK-NEXT:  Â  Â  }<br>
> +# CHECK-NEXT:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
>  Content-Length: 44<br>
><br>
>  {"jsonrpc":"2.0","id":4,"<wbr>method":"shutdown"}<br>
><br>
> Modified: clang-tools-extra/trunk/test/<wbr>clangd/completion-snippet.test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/test/clangd/<wbr>completion-<br>
> snippet.test?rev=318287&r1=<wbr>318286&r2=318287&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/test/<wbr>clangd/completion-snippet.test (original)<br>
> +++ clang-tools-extra/trunk/test/<wbr>clangd/completion-snippet.test Wed Nov 15<br>
> 01:16:29 2017<br>
> @@ -14,71 +14,74 @@ Content-Length: 148<br>
><br>
> {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>3,"character":5}}}<br>
>  #  Â  Â  CHECK:  "id": 1,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "int",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "a",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "a",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 5,<br>
> -# CHECK-NEXT:  Â  Â  "label": "a",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000035a"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "int",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "bb",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "bb",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 5,<br>
> -# CHECK-NEXT:  Â  Â  "label": "bb",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000035bb"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "int",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "ccc",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "ccc",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 5,<br>
> -# CHECK-NEXT:  Â  Â  "label": "ccc",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000035ccc"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "int",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "f",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "f(${1:int i}, ${2:const float f})",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 2,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "f(int i, const float f) const",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000035f"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "fake::",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 7,<br>
> -# CHECK-NEXT:  Â  Â  "label": "fake::",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000075fake"<br>
> -# CHECK-NEXT:  Â  },<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "fake &",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "operator=",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "operator=(${1:const fake &})",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 2,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "operator=(const fake &)",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000079operator="<br>
> -# CHECK-NEXT:  Â  },<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "int",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "a",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "a",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 5,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "a",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000035a"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "int",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "bb",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "bb",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 5,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "bb",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000035bb"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "int",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "ccc",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "ccc",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 5,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "ccc",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000035ccc"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "int",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "f",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "f(${1:int i}, ${2:const float f})",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "f(int i, const float f) const",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000035f"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "fake::",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 7,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "fake::",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000075fake"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "fake &",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "operator=",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "operator=(${1:const fake &})",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "operator=(const fake &)",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000079operator="<br>
> +# CHECK-NEXT:  Â  Â  },<br>
>  # FIXME: Why do some buildbots show an extra operator==(fake&&) here?<br>
> -#  Â  Â  CHECK:  Â  {<br>
> -#  Â  Â  CHECK:  Â  Â  "detail": "void",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "~fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "~fake()",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 4,<br>
> -# CHECK-NEXT:  Â  Â  "label": "~fake()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000079~fake"<br>
> -# CHECK-NEXT:  Â  }<br>
> -# CHECK-NEXT:  ]<br>
> +#  Â  Â  CHECK:  Â  Â  {<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "detail": "void",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "~fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "~fake()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 4,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "~fake()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000079~fake"<br>
> +# CHECK-NEXT:  Â  Â  }<br>
> +# CHECK-NEXT:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
>  # Update the source file and check for completions again.<br>
>  Content-Length: 226<br>
><br>
> @@ -89,16 +92,18 @@ Content-Length: 148<br>
><br>
> {"jsonrpc":"2.0","id":3,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>3,"character":5}}}<br>
>  #  Â  Â  CHECK:  "id": 3,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -# CHECK-NEXT:  Â  {<br>
> -# CHECK-NEXT:  Â  Â  "detail": "int (*)(int, int)",<br>
> -# CHECK-NEXT:  Â  Â  "filterText": "func",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "func()",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 2,<br>
> -# CHECK-NEXT:  Â  Â  "label": "func()",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000034func"<br>
> -# CHECK-NEXT:  Â  },<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +# CHECK-NEXT:  Â  Â  {<br>
> +# CHECK-NEXT:  Â  Â  Â  "detail": "int (*)(int, int)",<br>
> +# CHECK-NEXT:  Â  Â  Â  "filterText": "func",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "func()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 2,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "func()",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000034func"<br>
> +# CHECK-NEXT:  Â  Â  },<br>
>  Content-Length: 44<br>
><br>
>  {"jsonrpc":"2.0","id":4,"<wbr>method":"shutdown"}<br>
><br>
> Modified: clang-tools-extra/trunk/test/<wbr>clangd/completion.test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/test/clangd/<wbr>completion.test?rev=318287&r1=<wbr>318286&r2=318287&vie<br>
> w=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/test/<wbr>clangd/completion.test (original)<br>
> +++ clang-tools-extra/trunk/test/<wbr>clangd/completion.test Wed Nov 15<br>
> 01:16:29 2017<br>
> @@ -14,7 +14,9 @@ Content-Length: 148<br>
><br>
> {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>3,"character":5}}}<br>
>  #  Â  Â  CHECK:  "id": 1<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
>  # CHECK-NEXT:  Â  {<br>
>  # CHECK-NEXT:  Â  Â  "detail": "int",<br>
>  # CHECK-NEXT:  Â  Â  "filterText": "a",<br>
> @@ -84,7 +86,9 @@ Content-Length: 148<br>
><br>
> {"jsonrpc":"2.0","id":2,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>3,"character":5}}}<br>
>  #  Â  Â  CHECK:  "id": 2<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
>  # CHECK-NEXT:  Â  {<br>
>  # CHECK-NEXT:  Â  Â  "detail": "int",<br>
>  # CHECK-NEXT:  Â  Â  "filterText": "a",<br>
> @@ -158,7 +162,9 @@ Content-Length: 148<br>
><br>
> {"jsonrpc":"2.0","id":3,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"<a>file:///<wbr>main.cpp</a>"},"position":{"line":<wbr>3,"character":5}}}<br>
>  #  Â  Â  CHECK:  Â  "id": 3,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
>  # CHECK-NEXT:  Â  {<br>
>  # CHECK-NEXT:  Â  Â  "detail": "int (*)(int, int)",<br>
>  # CHECK-NEXT:  Â  Â  "filterText": "func",<br>
><br>
> Modified: clang-tools-extra/trunk/test/<wbr>clangd/protocol.test<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/test/clangd/<wbr>protocol.test?rev=318287&r1=<wbr>318286&r2=318287&view=<br>
> diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/test/<wbr>clangd/protocol.test (original)<br>
> +++ clang-tools-extra/trunk/test/<wbr>clangd/protocol.test Wed Nov 15 01:16:29<br>
> 2017<br>
> @@ -31,14 +31,17 @@ Content-Length: 146<br>
>  #<br>
>  #  Â  Â  CHECK:  "id": 1,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -#  Â  Â  CHECK:  Â  Â  "filterText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 7,<br>
> -# CHECK-NEXT:  Â  Â  "label": "fake::",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000075fake"<br>
> -#  Â  Â  CHECK:  ]<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "filterText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 7,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "fake::",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000075fake"<br>
> +#  Â  Â  CHECK:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
><br>
>  X-Test: Testing<br>
>  Content-Type: application/vscode-jsonrpc; charset-utf-8<br>
> @@ -57,14 +60,17 @@ Content-Length: 146<br>
>  #<br>
>  #  Â  Â  CHECK:  "id": 3,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -#  Â  Â  CHECK:  Â  Â  "filterText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 7,<br>
> -# CHECK-NEXT:  Â  Â  "label": "fake::",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000075fake"<br>
> -#  Â  Â  CHECK:  ]<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "filterText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 7,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "fake::",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000075fake"<br>
> +#  Â  Â  CHECK:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
>  # STDERR: Warning: Duplicate Content-Length header received. The previous<br>
> value for this message (10) was ignored.<br>
><br>
>  Content-Type: application/vscode-jsonrpc; charset-utf-8<br>
> @@ -83,14 +89,17 @@ Content-Length: 146<br>
>  #<br>
>  #  Â  Â  CHECK:  "id": 5,<br>
>  # CHECK-NEXT:  "jsonrpc": "2.0",<br>
> -# CHECK-NEXT:  "result": [<br>
> -#  Â  Â  CHECK:  Â  Â  "filterText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertText": "fake",<br>
> -# CHECK-NEXT:  Â  Â  "insertTextFormat": 1,<br>
> -# CHECK-NEXT:  Â  Â  "kind": 7,<br>
> -# CHECK-NEXT:  Â  Â  "label": "fake::",<br>
> -# CHECK-NEXT:  Â  Â  "sortText": "000075fake"<br>
> -#  Â  Â  CHECK:  ]<br>
> +# CHECK-NEXT:  "result": {<br>
> +# CHECK-NEXT:  Â  "isIncomplete": false,<br>
> +# CHECK-NEXT:  Â  "items": [<br>
> +#  Â  Â  CHECK:  Â  Â  Â  "filterText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertText": "fake",<br>
> +# CHECK-NEXT:  Â  Â  Â  "insertTextFormat": 1,<br>
> +# CHECK-NEXT:  Â  Â  Â  "kind": 7,<br>
> +# CHECK-NEXT:  Â  Â  Â  "label": "fake::",<br>
> +# CHECK-NEXT:  Â  Â  Â  "sortText": "000075fake"<br>
> +#  Â  Â  CHECK:  Â  ]<br>
> +# CHECK-NEXT:  }<br>
>  Content-Length: 1024<br>
><br>
><br>
> {"jsonrpc":"2.0","id":5,"<wbr>method":"textDocument/<wbr>completion","params":{"text<br>
> Document":{"uri":"file:/main.<wbr>cpp"},"position":{"line":3,"<wbr>character":5}}}<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-" target="_blank">
http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/unittests/clangd/<wbr>ClangdTests.cpp?rev=318287&r1=<wbr>318286&r2=31828<br>
> 7&view=diff<br>
> ==============================<wbr>==============================<wbr>==============<br>
> ====<br>
> --- clang-tools-extra/trunk/<wbr>unittests/clangd/ClangdTests.<wbr>cpp (original)<br>
> +++ clang-tools-extra/trunk/<wbr>unittests/clangd/ClangdTests.<wbr>cpp Wed Nov 15<br>
> 01:16:29 2017<br>
> @@ -619,16 +619,15 @@ struct bar { T x; };<br>
>  class ClangdCompletionTest : public ClangdVFSTest {<br>
>  protected:<br>
>  Â  template <class Predicate><br>
> -  bool ContainsItemPred(std::vector<<wbr>CompletionItem> const &Items,<br>
> -  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Predicate Pred) {<br>
> -  Â  for (const auto &Item : Items) {<br>
> +  bool ContainsItemPred(<wbr>CompletionList const &Items, Predicate Pred) {<br>
> +  Â  for (const auto &Item : Items.items) {<br>
>  Â  Â  Â  if (Pred(Item))<br>
>  Â  Â  Â  Â  return true;<br>
>  Â  Â  }<br>
>  Â  Â  return false;<br>
>  Â  }<br>
><br>
> -  bool ContainsItem(std::vector<<wbr>CompletionItem> const &Items, StringRef<br>
> Name) {<br>
> +  bool ContainsItem(CompletionList const &Items, StringRef Name) {<br>
>  Â  Â  return ContainsItemPred(Items, [Name](clangd::CompletionItem Item) {<br>
>  Â  Â  Â  return Item.insertText == Name;<br>
>  Â  Â  });<br>
> @@ -694,6 +693,44 @@ int b =  Â ;<br>
>  Â  }<br>
>  }<br>
><br>
> +TEST_F(ClangdCompletionTest, Limit) {<br>
> +  MockFSProvider FS;<br>
> +  MockCompilationDatabase CDB(/*AddFreestandingFlag=*/<wbr>true);<br>
> +  CDB.ExtraClangFlags.push_back(<wbr>"-xc++");<br>
> +  ErrorCheckingDiagConsumer DiagConsumer;<br>
> +  clangd::CodeCompleteOptions Opts;<br>
> +  Opts.Limit = 2;<br>
> +  ClangdServer Server(CDB, DiagConsumer, FS,<br>
> getDefaultAsyncThreadsCount(),<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Opts, EmptyLogger::getInstance());<br>
> +<br>
> +  auto FooCpp = getVirtualTestFilePath("foo.<wbr>cpp");<br>
> +  FS.Files[FooCpp] = "";<br>
> +  FS.ExpectedFile = FooCpp;<br>
> +  StringWithPos Completion = parseTextMarker(R"cpp(<br>
> +struct ClassWithMembers {<br>
> +  int AAA();<br>
> +  int BBB();<br>
> +  int CCC();<br>
> +}<br>
> +int main() { ClassWithMembers().{complete} }<br>
> +  Â  Â  )cpp",<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â "complete");<br>
> +  Server.addDocument(FooCpp, Completion.Text);<br>
> +<br>
> +  /// For after-dot completion we must always get consistent results.<br>
> +  auto Results = Server<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â .codeComplete(FooCpp, Completion.MarkerPos,<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â StringRef(Completion.Text))<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â .get()<br>
> +  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â .Value;<br>
> +<br>
> +  EXPECT_TRUE(Results.<wbr>isIncomplete);<br>
> +  EXPECT_EQ(Opts.Limit, Results.items.size());<br>
> +  EXPECT_TRUE(ContainsItem(<wbr>Results, "AAA"));<br>
> +  EXPECT_TRUE(ContainsItem(<wbr>Results, "BBB"));<br>
> +  EXPECT_FALSE(ContainsItem(<wbr>Results, "CCC"));<br>
> +}<br>
> +<br>
>  TEST_F(ClangdCompletionTest, CompletionOptions) {<br>
>  Â  MockFSProvider FS;<br>
>  Â  ErrorCheckingDiagConsumer DiagConsumer;<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" target="_blank">
http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div></div></div>
</div>
</div>

</blockquote></div><br></div>