Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion conformance/traceability.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"$comment": "Rule identifiers of specifications S1 to S5 mapped to evidence (usable plan W10.2), checked by docs/specs/tools/validate.py. Evidence: validate (a passing check of validate.py, by label prefix), test (tests/<file>.cpp: <name>), check (<fixture>/<check id>), review (a review fixture under tools/bench/review), script (a file and a line that enforces the rule), manual (why no automated evidence can exist).",
"$pending": {},
"$pending": {
"S1-7.2-10": "the server does not read `generated` yet",
"S1-7.2-11": "the server does not read `generated` yet",
"S1-7.2-12": "the server does not read `generated` yet",
"S1-7.2-13": "the server does not read `generated` yet"
},
"S1-3-1": [
{
"test": "tests/test_spec.cpp: private units are not visible and duplicates are ambiguous"
Expand Down Expand Up @@ -248,6 +253,51 @@
"test": "tests/test_spec.cpp: the level 3 GCC example loads"
}
],
"S1-7.2-1": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-2": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-3": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-4": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-5": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-6": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-7": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-8": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-7.2-9": [
{
"manual": "A producer rule. mcpp-community/mcpp writes the object, and its e2e 815 checks the fields; this repository contains no producer that could be tested."
}
],
"S1-8-1": [
{
"validate": "S1 schema rejects unit without source"
Expand Down
14 changes: 14 additions & 0 deletions docs/specs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

Changes to the specifications in this directory. Each specification is versioned independently.

## 2026-09-27 — S1 0.3.0: generated files

A set's `ide` object gains `generated` (optional, section 7.2): the files and directories that the
build generates and that the set's units compile or include, each with the path this document names
(`path`), the path the build of the same configuration writes (`build-path`), its `kind` (`source`,
`header` or `directory`) and, for a file, the step that writes it (`generator`: `id`, `inputs`,
`arguments`, `work-directory`). A consumer does not report a reference to a generated file that does
not exist as an error in the referring source; it may read the file at `build-path` read-only, and it
runs a step only with its user's consent (S1-7.2-10 to S1-7.2-13). A producer that plans without
building, such as `mcpp emit build-database`, plans in a directory of its own; before this, a header a
rule generates was missing there, and every source that included it lost its semantics
(mcpp-community/mcpp#724). Additive: a 0.2.0 consumer ignores the field (S1-11.2-1). mcpp writes it
from mcpp-community/mcpp's release that closes #724.

## 2026-09-27 — S3: a download the client may offer, and two more build systems

`CxxModulesIssue` gains `askOnline` (optional): on a `producer-needs-download` issue, the server will
Expand Down
2 changes: 1 addition & 1 deletion docs/specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This directory holds the normative specifications that let C++ named modules be

| Spec | Title | Version | Status | Schema |
|---|---|---|---|---|
| [S1](s1-build-database.md) | C++ Build Database: IDE Profile | profile-version 0.2.0 | Draft | [s1-build-database.schema.json](schema/s1-build-database.schema.json) |
| [S1](s1-build-database.md) | C++ Build Database: IDE Profile | profile-version 0.3.0 | Draft | [s1-build-database.schema.json](schema/s1-build-database.schema.json) |
| [S2](s2-discovery.md) | Build Database Discovery Protocol | 0.3.0 | Draft | [s2-discovery.schema.json](schema/s2-discovery.schema.json) |
| [S3](s3-lsp-extensions.md) | Language Server Protocol Extensions for C++ Modules | protocol version 1 | Draft | TypeScript interfaces in the text |
| [S4](s4-semantic-kit.md) | Semantic Kit | kit-version 1 | Draft | [s4-kit.schema.json](schema/s4-kit.schema.json) |
Expand Down
26 changes: 24 additions & 2 deletions docs/specs/s1-build-database.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
| | |
|---|---|
| Specification | S1 |
| Profile version | 0.2.0 |
| Profile version | 0.3.0 |
| Status | Draft |
| Schema | [`schema/s1-build-database.schema.json`](schema/s1-build-database.schema.json) |
| Examples | [`examples/s1-level3-gcc.json`](examples/s1-level3-gcc.json), [`examples/s1-level2-clang-two-sets.json`](examples/s1-level2-clang-two-sets.json) |
Expand Down Expand Up @@ -108,7 +108,7 @@ Database (P2977R2)

| Field | Type | Requirement | Description |
|---|---|---|---|
| `profile-version` | string | MUST | The version of this profile the document conforms to, as a semantic version, for example `"0.2.0"`. <a id="S1-5.1-1"></a><sup>S1-5.1-1</sup> |
| `profile-version` | string | MUST | The version of this profile the document conforms to, as a semantic version, for example `"0.3.0"`. <a id="S1-5.1-1"></a><sup>S1-5.1-1</sup> |
| `generator` | object | SHOULD | The producer: `name` (string, MUST) and `version` (string, SHOULD). <a id="S1-5.1-2"></a><a id="S1-5.1-3"></a><a id="S1-5.1-4"></a><sup>S1-5.1-2, S1-5.1-3, S1-5.1-4</sup> |
| `toolchains` | object | MUST | Map from toolchain id to Toolchain object (section 6). Ids are opaque strings. <a id="S1-5.1-5"></a><sup>S1-5.1-5</sup> |
| `extensions` | object | MAY | Vendor extensions (section 13). |
Expand Down Expand Up @@ -165,8 +165,30 @@ How units are grouped into sets follows how the build resolves imports. A build
| `kind` | enum | SHOULD | `library`, `executable`, `test` or `other`. Consumers use it to choose a default context. <a id="S1-7.1-3"></a><sup>S1-7.1-3</sup> |
| `options` | SemanticOptions | level 3 MUST | Structured form of `baseline-arguments` (section 9). <a id="S1-7.1-4"></a><sup>S1-7.1-4</sup> |
| `module-metadata` | string[] | MAY | Module metadata files of external modules visible to this set, excluding the toolchain's standard library. |
| `generated` | Generated[] | MAY | Files and directories that the build generates and that the units of this set compile or include (section 7.2). |
| `extensions` | object | MAY | Vendor extensions. |

### 7.2 Generated object

A build can generate files that the units of a set compile or include: sources and headers written by code generators, and the directories that hold them. A producer that performs no build describes them, so that a consumer can tell a file that a build has not written yet from a file that is missing.

| Field | Type | Requirement | Description |
|---|---|---|---|
| `path` | string | MUST | Absolute path of the file or directory in the configuration this document describes, as the units' `arguments` name it. <a id="S1-7.2-1"></a><sup>S1-7.2-1</sup> |
| `build-path` | string | SHOULD | Absolute path at which the build of the same configuration writes it. It differs from `path` when the producer plans in a directory of its own, and equals `path` otherwise. It is stated whether or not the file exists. <a id="S1-7.2-2"></a><sup>S1-7.2-2</sup> |
| `kind` | enum | MUST | `source` (a unit of the set is compiled from it), `header` (units of the set include it) or `directory` (an include directory whose contents are generated). <a id="S1-7.2-3"></a><sup>S1-7.2-3</sup> |
| `generator` | object | conditional MUST | REQUIRED for `source` and `header`, absent for `directory`. It has `id` (string, MUST), the producer's name for the step that writes the file; `inputs` (string[], SHOULD), the absolute paths of the files the step reads; `arguments` (string[], SHOULD), the step's command, program first; and `work-directory` (string, MAY). <a id="S1-7.2-4"></a><a id="S1-7.2-5"></a><a id="S1-7.2-6"></a><a id="S1-7.2-7"></a><a id="S1-7.2-8"></a><sup>S1-7.2-4, S1-7.2-5, S1-7.2-6, S1-7.2-7, S1-7.2-8</sup> |

A producer **SHOULD** list every generated file that a unit's `arguments` name, and every generated file in an include directory that the `arguments` name, whenever it knows the step that writes the file. <a id="S1-7.2-9"></a><sup>S1-7.2-9</sup> A translation unit whose `source` is the `path` of a `source` entry is a generated unit: before a build its source may be absent or empty.

A consumer:

- **MUST NOT** report a unit's reference to a generated file that does not exist as an error in that unit's source, and **SHOULD** tell the user that the file is generated, by which step, and that a build writes it; <a id="S1-7.2-10"></a><a id="S1-7.2-11"></a><sup>S1-7.2-10, S1-7.2-11</sup>
- **MAY** read the file at `build-path` when it exists, read-only (section 14), and **MUST** then treat it as possibly stale relative to the step's inputs; <a id="S1-7.2-12"></a><sup>S1-7.2-12</sup>
- **MUST NOT** run a step's `arguments` unless the user has allowed it for the workspace (section 14). <a id="S1-7.2-13"></a><sup>S1-7.2-13</sup>

Rationale: a producer that does not build (for example mcpp's `emit build-database`, which writes nothing into the project and runs no build step) plans in a directory of its own, so a generated header named by the units' `-I` arguments is absent there. Without this object a consumer reports a missing header in every source that includes it and loses the semantics of that source. The object states which files are generated and where the build writes them; running the generators remains a decision of the consumer and its user.

## 8. Translation unit object

| Field | Type | Requirement | Description |
Expand Down
87 changes: 85 additions & 2 deletions docs/specs/schema/s1-build-database.schema.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://github.com/mcpp-community/mcpp-language-server/specs/schema/s1-build-database/0.2.0",
"title": "C++ Build Database: IDE Profile 0.2.0 (S1)",
"$id": "https://github.com/mcpp-community/mcpp-language-server/specs/schema/s1-build-database/0.3.0",
"title": "C++ Build Database: IDE Profile 0.3.0 (S1)",
"description": "A P2977R2-compatible build database with the IDE profile fields of S1. Unknown fields are permitted everywhere; consumers ignore them.",
"type": "object",
"required": [
Expand Down Expand Up @@ -226,11 +226,94 @@
"$ref": "#/$defs/nonEmptyString"
}
},
"generated": {
"type": "array",
"items": {
"$ref": "#/$defs/generated"
}
},
"extensions": {
"$ref": "#/$defs/extensions"
}
}
},
"generated": {
"type": "object",
"required": [
"path",
"kind"
],
"properties": {
"path": {
"$ref": "#/$defs/nonEmptyString"
},
"build-path": {
"$ref": "#/$defs/nonEmptyString"
},
"kind": {
"enum": [
"source",
"header",
"directory"
]
},
"generator": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"$ref": "#/$defs/nonEmptyString"
},
"inputs": {
"$ref": "#/$defs/stringArray"
},
"arguments": {
"$ref": "#/$defs/stringArray"
},
"work-directory": {
"type": "string"
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"kind": {
"enum": [
"source",
"header"
]
}
}
},
"then": {
"required": [
"generator"
]
}
},
{
"if": {
"properties": {
"kind": {
"const": "directory"
}
}
},
"then": {
"not": {
"required": [
"generator"
]
}
}
}
]
},
"translationUnit": {
"type": "object",
"required": [
Expand Down