llvm-project/lldb/tools
Raphael Isemann 74a51753a6 [lldb] Make order of completions for expressions deterministic and sorted by Clang's priority values.
Summary:

It turns out that the order in which we provide completions for expressions is
nondeterministic. This leads to confusing user experience and also breaks the
reproducer tests (as two LLDB tests can go out of sync due to the
non-determinism in the completion lists)

The reason for the non-determinism is that the CompletionConsumer informs us
about decls in the order in which it finds declarations in the lookup store of
the DeclContexts it visits (mainly this snippet in SemaLookup.cpp):

``` lang=c++
    // Enumerate all of the results in this context.
    for (DeclContextLookupResult R :
         Load ? Ctx->lookups()
              : Ctx->noload_lookups(/*PreserveInternalState=*/false)) {
       [...]
```

This storage of the lookup is sorted by pointer values (see the hash of
`DeclarationName`) and can therefore be non-deterministic. The LLDB code
completion consumer that receives these calls originally expected that the order
of declarations is defined by Clang, but it seems the API expects the client to
provide an order to the completions.

This patch fixes the issue as follows:

* We sort the completions we get from Clang alphabetically and also by the
priority value we get from Clang (with priority value sorting having precedence
over the alphabetical sorting)

* We make all the functions/variables that touch a completion before the sorting
const-qualified. The idea is that this should prevent that we never have
observable side-effect from touching these declarations in a non-deterministic
order (e.g., we don't try to complete the type by accident).

This way we behave like the other parts of Clang which also sort the results by
some deterministic value (usually the name or something computed from a name,
e.g., edit distance to a given string).

We most likely also need to fix the Clang code to make the loop I listed above
deterministic to prevent these issues in the future (tracked in rdar://63442513
). This wouldn't replace the functionality provided in this patch though as we
would still need the priority and overall alphabetical sorting.

Note: I had to increase the lldb-vscode completion limit to 100 as the tests
look for strings that aren't in the first 50 results anymore due to variable
names starting with letters like 'v' (which are now always shown much further
down in the list due to the alphabetical sorting).

Fixes rdar://63200995

Reviewers: JDevlieghere, clayborg

Reviewed By: JDevlieghere

Subscribers: mgrang, abidh

Differential Revision: https://reviews.llvm.org/D80292
2020-05-27 19:22:01 +02:00
..
argdumper [JSON] Use LLVM's library for argdumper 2019-10-01 17:41:55 +00:00
compact-unwind Add arm64_32 support to lldb, an ILP32 codegen 2019-10-16 19:14:49 +00:00
darwin-debug Embed a zero-length /dev/null in darwin-debug for the special section. 2020-01-22 15:50:33 -08:00
darwin-threads the thread id is easier to read in base16. 2018-03-06 23:33:02 +00:00
debugserver Quote error string from qLaunchSuccess 2020-05-11 20:05:57 -07:00
driver [lldb/Driver] Print snippet before exiting with unknown argument. 2020-05-20 12:35:02 -07:00
intel-features [intel-mpx] Delete an unnecessary license header 2020-04-03 17:27:37 -07:00
lldb-instr [lldb/Reproducers] Change the way we instrument void* arguments 2020-02-04 19:05:13 -08:00
lldb-perf/darwin/sketch Remove lldb-perf 2019-07-08 21:38:34 +00:00
lldb-server [lldb] Change Communication::SetConnection to take a unique_ptr 2020-04-02 14:42:25 +02:00
lldb-test [lldb/CMake] Use INSTALL_RPATH for tools and BUILD_RPATH for unittests. 2020-04-30 13:20:06 -07:00
lldb-vscode [lldb] Make order of completions for expressions deterministic and sorted by Clang's priority values. 2020-05-27 19:22:01 +02:00
CMakeLists.txt [CMake] Copy over the system debugserver when using LLDB_USE_SYSTEM_DEBUGSERVER 2019-09-24 22:39:04 +00:00