# clangd ## What is clangd? **clangd** is a language server for C and C++, built on the Clang compiler frontend. It implements the Language Server Protocol (LSP), a standard interface that lets a single language-analysis backend serve go-to-definition, autocomplete, inline diagnostics, and refactoring to any editor that speaks LSP, [[nvim]], VS Code, Emacs, without each editor needing its own C++ parser. The reason clangd can give accurate answers about C/C++ code, a language notoriously difficult to parse correctly without full preprocessor and template context, is that it reuses Clang's actual production compiler frontend rather than a separate lightweight parser. When clangd tells you a symbol is undefined, it's using the same semantic analysis that would eventually fail the real build. The practical consequence is that clangd needs to know your project's exact compile flags (include paths, defines, language standard) to analyze code correctly, the same way the compiler does. Without that information it falls back to guessing, which is where most clangd frustration originates. ## Install On Debian and Ubuntu: ```bash sudo apt install clangd ``` On Fedora and RHEL: ```bash sudo dnf install clang-tools-extra ``` Multiple versions may be installed side by side as `clangd-14`, `clangd-18`, etc.; `update-alternatives` can select the default: ```bash sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-18 100 ``` ## Practice clangd needs a `compile_commands.json` in the project root, a JSON file listing the exact compiler invocation for every translation unit. [[cmake]] generates this automatically when asked: ```bash cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build ln -s build/compile_commands.json . ``` With that file present, launching clangd against any source file in the project gives it the real flags the build actually uses: ```bash clangd --check=my_file.cpp # sanity-check clangd's own analysis, no editor needed ``` Most editors invoke `clangd` automatically once configured as the LSP server for C/C++ filetypes; the editor never needs its own understanding of the language, it just relays requests to clangd and renders the response. ## Concepts ### compile_commands.json This file is the single source of truth clangd uses to reconstruct each file's build environment: ```json [ { "directory": "/home/user/project/build", "command": "/usr/bin/g++ -std=c++20 -Iinclude -DDEBUG -c ../src/main.cpp", "file": "../src/main.cpp" } ] ``` For projects not built with CMake, `bear` (Build EAR) can generate the same file by intercepting the actual compiler invocations during a normal build: ```bash bear -- make ``` ### Diagnostics and code actions clangd surfaces compiler diagnostics inline as you type, the same errors and warnings you'd get from `gcc -Wall`, but attached to the exact line and column in the editor rather than requiring a full recompile to see them. Many diagnostics come with an attached **code action**, an automated fix clangd can apply directly, such as adding a missing `#include` for a symbol it recognises from the project's headers. ### Cross-references and the index clangd builds a background index of symbol definitions and references across the whole project, which is what powers "find all references" and accurate "go to definition" even across files that aren't currently open. This index is rebuilt incrementally as files change, and for large codebases it can be precomputed once with `clangd-indexer` and shared across a team rather than rebuilt from scratch on every machine. ### Relationship to clang-tidy clangd can optionally surface `clang-tidy` lint warnings (style and common-bug-pattern checks) inline alongside its own diagnostics, configured via a `.clangd` or `.clang-tidy` file in the project root: ```yaml # .clangd Diagnostics: ClangTidy: Add: [performance-*, bugprone-*] ```