CLion’s clangd migration: fixing missing symbols and broken navigation
CLion 2023.1+ replaced its C++ engine with clangd When goto-definition or diagnostics break the usual culprit is a mismatched compile_commands.json Here's how to generate verify and troubleshoot it
15 Jun 2026, 00:00 UTC

You open CLion, press F12 on a std::vector call and nothing happens the status bar reads file not indexed After upgrading to CLion 2023.1 or later this is often not a bug it is a compile_commands.json mismatch
The clangd switch what changed in your editor
Since CLion 2023.1 the default C++ language engine is clangd LLVM's Language Server Protocol implementation It replaces JetBrains' custom resolver with the same clang frontend that production compilers use That means template substitution errors concept checks and C++20/23 features now appear with the same fidelity as a command-line build Background indexing is driven by clangd's on-disk AST cache and symbol search no longer requires keeping full ASTs in the IDE heap
Why goto-definition can break
clangd resolves symbols by reading a compile_commands.json file This file records the exact compiler invocations for every source file If the file is stale missing or built with different flags clangd's index becomes out of sync You'll see warnings in the status bar and navigation commands may fall back or silently fail
Fixing the compile_commands.json bottleneck
The most reliable fix is to ensure your project generates a matching compile_commands.json and that CLion picks it up
Generate it once
- Open the embedded terminal View Tool Windows Terminal in CLion
- Run the CMake flag that emits the database:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
This writes a compile_commands.json to your project root The placeholder .. refers to the CMakeLists.txt parent directory adjust if your build directory differs
Verify the fix
- Reload the project choose Reload when the prompt appears or select File Invalidate Caches Reload Project
- Press F12 on any
std::vectorusage Goto-definition should land in the vector header - Check the status bar it should no longer show file not indexed Open Help About and confirm clangd appears under Language engine
If diagnostics still look wrong open View Tool Windows Clangd Log to inspect LSP requests and see whether clangd is reading the expected database
Inlay hints completion and other clangd-driven perks
- Inlay hints Parameter names deduced types and namespace qualifiers appear inline Toggle them via Settings Editor Inlay Hints C++
- Code completion ranking Blends clangd's semantic scoring proximity type match with IDE-side heuristics recently used and scope priority
- Snippet expansion Supports placeholders via $0/$1 markers in your snippets
When the legacy engine still makes sense
CLion keeps the custom resolver available for projects that hit clangd regressions Enable it via the Registry Help Find Action Registry and set clion.cidr.engine=legacy Note that the legacy engine receives no new language-feature work so if you need C++20/23 fidelity or accurate template diagnostics clangd is the forward path
Trade-offs and limitations to keep in mind
- Very large codebases >500k LOC may see higher initial RAM usage during indexing You can tune clangd.background-index.priority and clangd.memory.limit in a clangd.conf file placed alongside compile_commands.json
- C++ modules import std; require clangd >= 17 and a module mapper clang-scan-deps CLion 2024.2+ bundles a compatible mapper but CMake >= 3.28 is needed for automatic setup
- Some JetBrains-specific inspections e.g "Include file not found in project" "Redundant include" are not yet ported to clangd and run as post-processors with slight latency
- If your build system generates multiple compile_commands.json fragments e.g multi-config CMake ensure the one matching your current active configuration is present
Actionable closing checklist
- Run cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON in your project root and commit the generated compile_commands.json
- Reload the project and confirm the status bar is free of file not indexed warnings
- Test goto-definition on a standard library type such as std::vector or std::string
- If something feels off open the Clangd Log window and look for database-read errors
- Only switch to the legacy engine via Registry if you have a verified clangd regression and need immediate stability over new features
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.