RFC: expected types in clangd completions

Hi clangd-dev,

I have just posted a design doc about adding the expected types to the C++ completions:
https://docs.google.com/document/d/1_BSeTIr2aLA6wKKCRCajSI0AdnjhvgK4BXXJQX-Dsro/edit#

It serves two purposes:

  • List possible improvements to code completion that can be gained by using more semantic information available in Clang.
  • Discuss the design of type-based ranking in presence of the index, i.e. when some completions are not from Sema.

The first half of the document attempts to enumerate interesting cases where completions can be improved by using type information. It would be great to get ideas from anyone interested in improvements to ClangD completions in general, the ‘Anticipated Improvements’ is there to collect a raw list of nice-to-have cases, feel free to contribue!

The second half is targeted at a narrower audience, specifically anyone who’s interested in support of type-based ranking with index enabled in ClangD. If you’re interested, please take a look.

Feedback and suggestions are very welcome!

Thanks for putting this together!

I have one question:

In the example where an ‘std::make_unique’ completion was added based on function argument type, how would Clang know that std::unique_ptr is constructed using std::make_unique? Would that be hardcoded into Clang, or would there be some way to annotate the type in the header (e.g. using an attribute) so that Clang can deduce this (e.g. for supporting llvm::make_unique, etc.).

Thanks,
Alex

We planned to start with hard-coding the most common cases. This is obviously hard to generalize, but should work nicely for the common things (mostly STL, maybe other libs if we’re good at detecting those, but I’m not sure).
Annotating the type in the header would be perfect for the tools, but I wonder if people are willing to change the code for the sole purpose of improved tooling (you could argue this also serves documentation purposes). There will always be code that cannot be annotated, because users don’t own it.

Alternative approaches that come to mind:

  • Detecting constructor functions during indexing. (By looking at the function bodies or the most common functions used to “create” variables of some type).
    Pros: does not require any actions from the user.

Cons: requires preprocessing of the code base to work, might be hard to make it work with index-while-build.

  • Having external annotations (in addition to in-code annotations?), something that could give the tools enough info to do completions, e.g.

‘{ type: “std::unique_ptr<$T>”, construction: { insert_snippet: “std::make_unique<$T>($0)”, required_include: “” }’ (the syntax can obviously be something else, e.g. C++ with attributes or YAML)
Pros: do not need to change the code, potentially allows per-project config
Cons: needs design (e.g. should C++ lang standards be taken into account?), agreement on where to put those configs, how to load them, etc.

We could also do both alternatives if we have infinite time: external annotations and ways to infer them from the code while indexing.