Criterion-by-criterion pass over the 24 requirement files for a
minimal-but-complete contract set. Sixteen criteria that carried no
contract a user relies on are deleted (over-enumeration, restatements
of another file's contract, an unobservable same-source-twice rule that
duplicate detection collapses, untestable "may" disclaimers). Seventeen
instance-enumerations become one owned property each - source-extension
lists, kept-flag and link-flag lists, per-shape repeats, the MSVC /link
tail folded into "family-defined link-stage flag sets" - with the lists
retained as subject-matter references and a representative scenario
declared to cover them. Every generalization was checked to imply each
instance it replaces.
About thirty-five acceptance criteria that a real test already guarded
had no Given-When-Then scenario; these are written down now, modeled on
what the tests actually assert, and the implementing tests are tagged.
The genuine coverage gaps are closed with new tests: exact-exit-code
propagation, all-dropped and understood-but-empty exit codes, the
forced-preload rejection (the long-open mode-selection gap), a Fortran
entry, a masquerade launcher recorded under a compiler name, duplicate
output order, header/real-entry dedup, response-file source
participation, output-field path formatting, and reporting-failure
tolerance in wrapper mode. Coverage: 24/24 implemented requirements.
Found by the /requirements skill audit (dogfooding 1038d916).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.3 KiB
title, status
| title | status |
|---|---|
| Recognize C++20 module compilations | implemented |
Intent
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.
Acceptance criteria
- A compilation whose source file has a recognized C++20
module-interface extension produces a database entry like any other
translation unit. The recognized set:
.cppm,.ixx,.mxx,.ccm,.cxxm,.c++m. - Module-related driver flags, value-carrying or not, never swallow a
following source file and never suppress or corrupt the entry. The
recognized set:
--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- GCC:
-fmodules-ts,-fmodule-header,-fmodule-only,-fmodule-mapper=*,-fmodule-lazy
- Precompiled module artifacts (
.pcm, BMI files) are not classified as sources. They appear on argv but never as the entry'sfilefield.
Non-functional constraints
- The recognition layer must remain extension-driven for the source check. Probe-based detection of module-interface units is out of scope.
Known limitations
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.
Testing
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.
Notes
- Demand: issue #637.