Protocol extensions

clangd supports some features that are not in the official Language Server Protocol specification.

We try to do this sparingly. The most important considerations are:

These extensions may evolve or disappear over time. If you use them, try to recover gracefully if the structures aren’t what’s expected.


Switch between source/header

Lets editors switch between the main source file (*.cpp) and header (*.h).

New client->server request: textDocument/switchSourceHeader.

If the corresponding file can’t be determined, "" is returned. bug?

File status

Provides information about activity on clangd’s per-file worker thread. This can be relevant to users as building the AST blocks many other operations.

New server->client notification: textDocument/clangd.fileStatus

New initialization option: initializationOptions.clangdFileStatus : bool

Compilation commands

clangd relies on having accurate compilation commands to correctly interpret a file. Typically these are discovered via a compile_commands.json file in a parent directory. These extensions allow editors to supply the commands over LSP instead.

New initialization option: initializationOptions.compilationDatabasePath : string

New initialization option: initializationOptions.fallbackFlags : string[]

New configuration setting: settings.compilationDatabaseChanges : {string: CompileCommand}

Force diagnostics generation

Clangd does not regenerate diagnostics for every version of a file (e.g. after every keystroke), as that would be too slow. Its heuristics ensure:

This extension allows editors to force diagnostics to be generated/not generated at a particular revision.

New property of textDocument/didChange request: wantDiagnostics : bool

Diagnostic categories

Clang groups diagnostics into categories (e.g. “Inline Assembly Issue”). Clangd can emit these categories for interested editors.

New property of Diagnostic object: category : string:

New client capability: textDocument.publishDiagnostics.categorySupport:

Inline fixes for diagnostics

LSP specifies that code actions for diagnostics (fixes) are retrieved asynchronously using textDocument/codeAction. However clangd always computes these eagerly, and providing them alongside diagnostics can improve the UX in editors.

New property of Diagnostic object: codeActions : CodeAction[]:

New client capability: textDocument.publishDiagnostics.codeActionsInline : bool

Symbol info request

This attempts to resolve the symbol under the cursor, without retrieving further information (like definition location, which may require consulting an index). This was added to support integration with indexes outside clangd.

New client->server request: textDocument/symbolInfo:

UTF-8 offsets

LSP specifies that offsets within lines are in UTF-16 code units (for Positions and also delta-encoded document updates). This choice of encoding is a legacy of VSCode’s JavaScript implementation.

clangd allows clients to use UTF-8 offsets instead. This allows clients that always speak UTF-8 (in violation of the protocol) to work correctly, and those that are UTF-8 native to avoid unnecessary transcoding (which may be slow if implemented in e.g. vimscript).

New client capability: offsetEncoding : string[]:

Lists the encodings the client supports, in preference order. It SHOULD include "utf-16". If not present, it is assumed to be ["utf-16"]

Well-known encodings are:

New InitializeResponse property: offsetEncoding: string:

Advice for clients using this extension:

Advice for servers using this extension:

Type hierarchy

Clangd supports the type hierarchy extension proposed for LSP.

Type hierarchy allows the server to provide the client with information about the subclasses (derived classes) and superclasses (base classes) of the class referenced at a provided document location. Clients typically use this to show a tree view of the class and its subclasses or superclasses (or sometimes, in languages with single inheritance, a single tree showing both).

The version of the protocol currently implemented is the one in this proposal.

Code completion scores

LSP gives servers limited control over completion display order through the sortText attribute. Clangd uses several signals such as number of usages to ensure the most likely completions are near the top.

However as the user continues to type, editors filter and re-rank the results on the client side. This re-ranking should take into account the signals from the server, but LSP does not expose them.

New CompletionItem property: score: number:


C++ has a complicated grammar and semantic structure that’s not always obvious from the source. Inspecting the Clang AST can lend some insight. Despite the origin of the name (Abstract Syntax Tree), it captures semantics as well as syntax (e.g. implicit casts).

New client->server request: textDocument/ast:

New server capability: astProvider : bool:

Memory usage

clangd can use a lot of memory. It can be valuable to understand where it goes. We expose a hierarchy where memory is associated with a tree of components. e.g. an AST may be stored under clangd_server.tuscheduler."main.cpp".ast.

The actual component hierarchy is subject to change between versions, and the memory usage is only estimated (it mostly counts objects rather than tracking allocations directly).

New client->server request: $/memoryUsage:

New server capability: memoryUsageProvider : bool:

Reference Container

When finding references to a symbol, it’s often useful to know the name of the function or class in which the reference occurs.

New property of Location object: containerName : string?:

New client capability: textDocument.references.container:

Inlay hints

Inlay hints are labels that are displayed by the editor in-line with the code.

Without hints: memcpy(buf, data, n)
With hints: memcpy(dest: buf, src: data, count: n)

clangd can provide several categories of hints.

New client->server request: clangd/inlayHints:

New server capability: clangdInlayHintsProvider : bool`:

Compatibility: Several language servers support inlay hint extensions. This extension is mostly compatible with rust-analyzer/inlayHints. typescript-language-server also supports a similar typescript/inlayHints.

Our hope is that some version of inlay hints is standardized in LSP. Once standard inlay hints are implemented in clangd, we will deprecate this extension and eventually remove it.

See LSP bug 956, PR 609, PR 772.