mirror of
https://github.com/rizsotto/Bear.git
synced 2026-10-24 07:15:08 +02:00
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>
87 lines
3.3 KiB
Markdown
87 lines
3.3 KiB
Markdown
---
|
|
title: Recognize C++20 module compilations
|
|
status: 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's `file` field.
|
|
|
|
## 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 resulting `compile_commands.json` contains one entry whose
|
|
> `file` is `foo.cppm` and whose `arguments` preserve `--precompile`
|
|
> and 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 resulting `compile_commands.json` contains one entry whose
|
|
> `file` is `main.cpp` with the `-fmodule-file=foo=foo.pcm` flag preserved,
|
|
> and no entry is produced for `foo.pcm`.
|
|
|
|
Given a mixed build with one module interface and one consumer:
|
|
|
|
> When the user runs both commands above in sequence,
|
|
> then `compile_commands.json` contains exactly two entries
|
|
> (one for `foo.cppm`, one for `main.cpp`).
|
|
|
|
Given a GCC build using `-fmodules-ts`:
|
|
|
|
> When the user runs `bear -- g++ -std=c++20 -fmodules-ts -c mod.cppm`,
|
|
> then the resulting `compile_commands.json` contains one entry whose
|
|
> `file` is `mod.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.
|