Summary
Many headers under adobe/ show spurious "file not found" / cascading parse errors in the editor (clangd) when opened directly, even though the project builds cleanly. This also affects running clang-tidy's misc-include-cleaner check per-header to find truly unused includes (a separate but related investigation). Both issues trace back to the same root cause: headers with no dedicated test file have no reliable "donor" compile command, so clangd/clang-tidy fall back to a heuristic that can pick an unrelated file.
Root cause
compile_commands.json only contains entries for real translation units (.cpp files) — headers aren't compiled on their own, so they have no entry. When you open a header directly, clangd (and clang-tidy, and clangd --check) borrows compile flags from another file in the database, chosen by clang::tooling::InterpolatingCompilationDatabase (clang/lib/Tooling/InterpolatingCompilationDatabase.cpp). Per that file's own documentation, it's a point-scoring heuristic:
- +1 if a candidate's filename stem starts with the query header's stem; +1 more if it's an exact stem match (2 total)
- +1 for each of the last 2 parent-directory names of the query that also appears among the candidate's last 4 parent directories
- +1 if the candidate's whole path is a prefix match with the query's directory prefix
- Ties break on matching language, then longest path-string prefix, then a fixed deterministic order
- If literally nothing scores any points, it falls back to whichever file has the longest raw path-string prefix (score 0)
With ~330 of the ~420 entries in our compile_commands.json being third-party Boost sources (pulled in via CPM), headers whose names happen to share a stem prefix with some unrelated Boost internal file can get matched to it instead of a real project file:
adobe/algorithm/find.hpp → inferred command from boost/.../libs/atomic/src/find_address_sse2.cpp (1 point: stem "find_address_sse2" starts with "find"; 0 directory overlap) — that command's include paths know nothing about adobe/, so #include <adobe/config.hpp> fails, cascading into dozens of bogus errors ending in fatal_too_many_errors.
adobe/algorithm/unique.hpp → same story, matched to boost/.../libs/filesystem/src/unique_path.cpp.
adobe/algorithm/append.hpp → matched test/algorithm/clamp/clamp_test.cpp purely on shared algorithm directory name (1 point), since no append_test.cpp exists.
Checking test/algorithm/, only 4 of the ~48 adobe/algorithm/*.hpp headers have a dedicated test file (clamp, median, minmax, select). Every other header in that directory (and likely elsewhere in adobe/) is one coincidental Boost filename away from this failure mode.
Proposed fix
Add a minimal test .cpp for every header that lacks one, following the existing convention (test/<subdir>/<name>/<name>_test.cpp). This reliably wins the heuristic: e.g. for find.hpp, a test/algorithm/find/find_test.cpp scores 1 (stem prefix) + 1 (shared algorithm directory) = 2 points, beating any accidental 1-point Boost cross-match — and no Boost file would ever also match on the algorithm directory segment, so there's no ambiguity.
This is a good fix to pursue independent of any compile-command filtering, because:
- It doesn't touch
compile_commands.json, so Boost/Boost-symbol navigation in the editor is unaffected.
- It closes a real test-coverage gap (most of
adobe/algorithm/*.hpp currently has no dedicated test).
- It's local and incremental — can be done header-by-header.
Next steps
- Enumerate all
adobe/**/*.hpp headers lacking a same-stem test file.
- Add minimal test stubs (at least
#include the header, to guarantee a real compile-command match) for each, prioritizing the ones observed to actually misfire (find.hpp, unique.hpp, append.hpp, and others in adobe/algorithm/).
Summary
Many headers under
adobe/show spurious "file not found" / cascading parse errors in the editor (clangd) when opened directly, even though the project builds cleanly. This also affects runningclang-tidy'smisc-include-cleanercheck per-header to find truly unused includes (a separate but related investigation). Both issues trace back to the same root cause: headers with no dedicated test file have no reliable "donor" compile command, so clangd/clang-tidy fall back to a heuristic that can pick an unrelated file.Root cause
compile_commands.jsononly contains entries for real translation units (.cppfiles) — headers aren't compiled on their own, so they have no entry. When you open a header directly, clangd (andclang-tidy, andclangd --check) borrows compile flags from another file in the database, chosen byclang::tooling::InterpolatingCompilationDatabase(clang/lib/Tooling/InterpolatingCompilationDatabase.cpp). Per that file's own documentation, it's a point-scoring heuristic:With ~330 of the ~420 entries in our
compile_commands.jsonbeing third-party Boost sources (pulled in via CPM), headers whose names happen to share a stem prefix with some unrelated Boost internal file can get matched to it instead of a real project file:adobe/algorithm/find.hpp→ inferred command fromboost/.../libs/atomic/src/find_address_sse2.cpp(1 point: stem "find_address_sse2" starts with "find"; 0 directory overlap) — that command's include paths know nothing aboutadobe/, so#include <adobe/config.hpp>fails, cascading into dozens of bogus errors ending infatal_too_many_errors.adobe/algorithm/unique.hpp→ same story, matched toboost/.../libs/filesystem/src/unique_path.cpp.adobe/algorithm/append.hpp→ matchedtest/algorithm/clamp/clamp_test.cpppurely on sharedalgorithmdirectory name (1 point), since noappend_test.cppexists.Checking
test/algorithm/, only 4 of the ~48adobe/algorithm/*.hppheaders have a dedicated test file (clamp,median,minmax,select). Every other header in that directory (and likely elsewhere inadobe/) is one coincidental Boost filename away from this failure mode.Proposed fix
Add a minimal test
.cppfor every header that lacks one, following the existing convention (test/<subdir>/<name>/<name>_test.cpp). This reliably wins the heuristic: e.g. forfind.hpp, atest/algorithm/find/find_test.cppscores 1 (stem prefix) + 1 (sharedalgorithmdirectory) = 2 points, beating any accidental 1-point Boost cross-match — and no Boost file would ever also match on thealgorithmdirectory segment, so there's no ambiguity.This is a good fix to pursue independent of any compile-command filtering, because:
compile_commands.json, so Boost/Boost-symbol navigation in the editor is unaffected.adobe/algorithm/*.hppcurrently has no dedicated test).Next steps
adobe/**/*.hppheaders lacking a same-stem test file.#includethe header, to guarantee a real compile-command match) for each, prioritizing the ones observed to actually misfire (find.hpp,unique.hpp,append.hpp, and others inadobe/algorithm/).