<div dir="ltr">Thanks! After thinking about it further, I can't see a simple combination of flags to set that won't break other platforms.<div>So I've disabled the tests on PS4 for now, and will fix this properly once I get some sleep.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 15, 2017 at 9:49 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_7432862089235113006WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">You could build a PS4-target compiler yourself, actually, at least adequate for running lit tests. (Sorry it's not enough to build actual PS4 code!)  In a new
 build directory, run cmake with `-DLLVM_DEFAULT_TRIPLE=x86_64-<wbr>scei-ps4` and then it should all Just Work.  That's all the upstream PS4 bots are doing.<u></u><u></u></span></p>
<p class="MsoNormal"><a name="m_7432862089235113006__MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">--paulr<u></u><u></u></span></a></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></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 12:42 PM<br>
<b>To:</b> Robinson, Paul<br>
<b>Cc:</b> Galina Kistanova; cfe-commits (<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>)</span></p><div><div class="h5"><br>
<b>Subject:</b> Re: [clang-tools-extra] r318287 - [clangd] Support returning a limited number of completion results.<u></u><u></u></div></div><p></p>
</div>
</div><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<div>
<p class="MsoNormal">On Wed, Nov 15, 2017 at 8:46 PM, Sam McCall <<a href="mailto:sam.mccall@gmail.com" target="_blank">sam.mccall@gmail.com</a>> wrote:<u></u><u></u></p>
<div>
<p class="MsoNormal">That sounds great - I think using the same default std as clang is what we want.<u></u><u></u></p>
<div>
<p class="MsoNormal">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.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">For now r318327 explicitly sets the target triple to -pc-, which should get us back to uniform behavior across platforms.<u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal">Well, this didn't fix it. Lacking a machine to test on, I'll try to disable the tests on PS4 until this can be fixed in some other way.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal">This is obviously a hack and makes for a rocky -std transition, I'll look into this.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">(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)<u></u><u></u></p>
</div>
</div>
<div>
<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Wed, Nov 15, 2017 at 8:13 PM, Robinson, Paul <<a href="mailto:paul.robinson@sony.com" target="_blank">paul.robinson@sony.com</a>> wrote:<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Thanks for looking into it.</span><u></u><u></u></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.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">--paulr</span><u></u><u></u></p>
<p class="MsoNormal"><a name="m_7432862089235113006_m_2658568305513533698_m_4640626826386712"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> </span></a><u></u><u></u></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.</span><u></u><u></u></p>
</div>
</div>
<div>
<div>
<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>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div></div></div>
</div>
</div>

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