How can I figure out why a reference can't be found by clangd? Can I list the index to understand if what I'm looking for is missing?
Clangd docs
clangd has this information (see https://clangd.llvm.org/faq#why-does-clangd-not-return-all-references-for-a-symbol)
One of the potential reasons is that clangd has not indexed all the files in your project. Please make sure all files are visible to clangd through the project setup and compile_commands.json.
How do I make sure they are visible? Is just that the path of cc file is listed explicitly somewhere in the json file? (In that case, that is achieved)
More info about this particular case
I have a c++ project built with cmake and a compile_commands.json file is created as part of the build.
When I afterwards start my editor with clangd LSP, most LSP features like goto_definition and references work as expected, but some generated source files cant be found until I open them manually with my editor.
Source code files:
/my_repo/base/src/a.hh(declaresget_bananas())/my_repo/base/src/a.cc(definesget_bananas())
Some files cc files are generated by a build step (cmake+ninja+python) and put into build folder:
/my_repo/base/build/generated/gen_a_usage.cc(callsget_bananas())
When I perform lsp-call references() to try to find references from a.cc or a.hh the usages in gen_a_usage.cc file are not listed.
How can I figure out why I can't find gen_a_usage.cc? After I have opened this file from the build folder in my editor, references() start to list references in this file as well.
In reality the project is much bigger than just these three files. Both a.cc have entries and gen_a_usage.cc have entries in the compile_commands.json file.
Can it be that indexing is slow or fails?
extract from compile_commands.json
{
"directory": "/my_repo/base/build",
"command": "clang-wrapper-19.1.1/bin/clang++ -I/my_repo/base/build/generated -I/my_repo/base/src -I... -isystem ... -Og -g -std=gnu++20 -fPIC -Wall -Wextra -Wformat-signedness -ggdb -fcolor-diagnostics -o CMakeFiles/objects.dir/src/a.cc.o -c /my_repo/base/src/a.cc",
"file": "/my_repo/base/src/a.cc",
"output": "CMakeFiles/objects.dir/src/a.cc.o"
},
{
"directory": "/my_repo/base/build",
"command": "clang-wrapper-19.1.1/bin/clang++ -I/my_repo/base/build/generated -I/my_repo/base/src -I... -isystem ... -Og -g -std=gnu++20 -fPIC -Wall -Wextra -Wformat-signedness -ggdb -fcolor-diagnostics -o CMakeFiles/objects.dir/src/gen_a_usage.cc.o -c /my_repo/base/build/generated/gen_a_usage.cc",
"file": "/my_repo/base/build/generated/gen_a_usage.cc",
"output": "CMakeFiles/objects.dir/src/gen_a_usage.cc.o"
},
Environment
- Build is being done with cmake + ninja
- After build I start my editor (Neovim)
- LSP (clangd) is started with this config:
lsp.clangd.setup { cmd = {"clangd", "--clang-tidy", "--background-index", "--limit-references=0", "--cross-file-rename"}}
I have seen this behavior in clangd version 16, 19, and 20. And my colleague has similar issues in vscode.
LspLog has this information
ASTWorker building file /my_repo/base/src/a.cc version 0 with command \n[/my_repo/base/build/generated -I/my_repo/base/src -I... -isystem ... -Og -g -std=gnu++20 -fPIC -Wall -Wextra -Wformat-signedness -ggdb -fcolor-diagnostics -o CMakeFiles/objects.dir/src/a.cc.o -c clang-19.1.1/lib/clang/19 -- /my_repo/base/src/a.cc\n"
Loaded compilation database from /my_repo/base/build/compile_commands.json\n"
--> window/workDoneProgress/create(0)\n"
Enqueueing 930 commands for indexing\n"
<-- reply(0)\nI[11:45:43.742] --> $/progress\nI[11:45:43.742] --> $/progress\n"
Built preamble of size 21624316 for file /my_repo/base/src/a.cc version 0 in 1.46 seconds\n"
--> workspace/semanticTokens/refresh(1)\n"
Indexing c++20 standard library in the context of /my_repo/base/src/a.cc\n"
<-- reply(1)\n"
--> textDocument/publishDiagnostics\n"
Indexed c++20 standard library (incomplete due to errors): 15846 symbols, 2600 filtered\n"
<-- textDocument/references(2)\n"
--> reply:textDocument/references(2) 0 ms\n"
--> $/progress\n"
--> $/progress\nI[11:45:51.571] --> $/progress\nI[11:45:51.571] --> $/progress\n"
Indexed /my_repo/base/src/a.cc (136 symbols, 18679 refs, 475 files)\n"
--> $/progress\n"
Indexed /my_repo/base/src/b.cc (141 symbols, 18527 refs, 463 files)\n"
--> $/progress\n"
compile_commands.jsoninclude the offending files?