docs/requirements/recognition-cpp20-modules.md
When a user builds a project that uses C++20 modules, the build invokes the
compiler on module-interface source files (typically .cppm, .ixx, .ccm)
and on module-related driver flags (e.g. clang++ --precompile,
-fmodule-file=). The user expects the generated compile_commands.json
to include these compilations the same way it includes ordinary .cpp
translation units. Clang tooling (clangd, clang-tidy) needs the module
inputs and module-path flags to follow imports and produce accurate
diagnostics.
.cppm, .ixx, .mxx,
.ccm, .cxxm, .c++m.--precompile (Clang module-interface compile)-fmodule-file=* (Clang/GCC, including the <name>=<file> form)-fmodule-map-file=*-fmodule-name=*-fmodules, -fno-modules, -fcxx-modules-fmodules-ts (Clang transitional)-fprebuilt-module-path=*-fbuiltin-module-map-fimplicit-modules, -fno-implicit-modules-fmodules-ts, -fmodule-header, -fmodule-only,
-fmodule-mapper=*, -fmodule-lazy.pcm, BMI files) are not classified as
sources. They appear on argv but never as the entry's file field.Module dependency-graph awareness, BMI cache discovery, and module-map authoring are accepted exclusions: this contract covers capturing the module compilation invocations and nothing more.
Given a build that compiles a module-interface unit:
When the user runs
bear -- clang++ -std=c++20 --precompile foo.cppm -o foo.pcm, then the resultingcompile_commands.jsoncontains one entry whosefileisfoo.cppmand whoseargumentspreserve--precompileand the input/output paths.
Given a build that consumes a precompiled module:
When the user runs
bear -- clang++ -std=c++20 -fmodule-file=foo=foo.pcm -c main.cpp, then the resultingcompile_commands.jsoncontains one entry whosefileismain.cppwith the-fmodule-file=foo=foo.pcmflag preserved, and no entry is produced forfoo.pcm.
Given a mixed build with one module interface and one consumer:
When the user runs both commands above in sequence, then
compile_commands.jsoncontains exactly two entries (one forfoo.cppm, one formain.cpp).
Given a GCC build using -fmodules-ts:
When the user runs
bear -- g++ -std=c++20 -fmodules-ts -c mod.cppm, then the resultingcompile_commands.jsoncontains one entry whosefileismod.cppm.
The .cppm scenarios above are representative of every extension in
the recognized set. The --precompile, -fmodule-file=, and
-fmodules-ts scenarios are representative of every flag in the
recognized set, value-carrying and plain alike.