<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/144981>144981</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang] Support layering checks for C++ modules
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          matts1
      </td>
    </tr>
</table>

<pre>
    One highly useful feature of build systems is the ability to ensure strict dependencies. For more details, see this [blog post](https://blog.bazel.build/2017/06/28/sjd-unused_deps.html).

## What are strict deps
TLDR: Strict deps enforce that code can only depend on its direct dependencies, and not transitive dependencies.

Consider the following code:
```
// foo.cppm
import bar;
import baz;
```

```
// bar.cppm
import baz
```

```
# BUILD

cc_module(
  name = "foo",
 interface = "foo.cppm",
  deps = [":bar"]
)

cc_module(
  name = "bar",
  interface = "bar.cppm",
  deps = [":baz"]
)
```
This code *should* not compile. `foo` imports `baz`, but does not declare a dependency on `baz`. However, build systems have no easy mechanism to enforce this, as they have to output compile steps along the lines of:
```
clang++ --precompile baz.cppm -o baz.pcm
clang++ --precompile bar.cppm -fmodule-file=baz=baz.pcm -o bar.pcm
clang++ --precompile foo.cppm -fmodule-file=baz=baz.pcm -fmodule-file=bar=bar.pcm -o foo.pcm
```

Note that we cannot simply remove the `-fmodule-file=baz=...`, otherwise we would get an error if the module `bar` ever tried to return a value of a type declared in `baz`.

## Proposal
I propose that clang adds a new option `-findirect-module-file`. This has the same semantics as `-fmodule-file`, with the only difference being that if you ever attempt to import the module from the main TU, you get an error.

It might also be a good idea to add `-Wstrict-module-deps` or similar, so that this option can be first applied as warnings to an existing codebase, instead of errors.

This would allow the build system to generate:
```
clang++ --precompile baz.cppm -o baz.pcm
clang++ --precompile bar.cppm -fmodule-file=baz=baz.pcm -o bar.pcm
clang++ --precompile foo.cppm -findirect-module-file=baz=baz.pcm -fmodule-file=bar=bar.pcm -o foo.pcm
```
Thus allowing foo to fail to compile in the first place.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMVkGP2zoO_jXKhYhhy5M0OeSQmSDYAsXuYjtFjwVt0bG6smSI8uRlfv2DJGea6Qzad3iHBwRJbJkfyY8fSSOzPlminVjdi9VhgVPond8NGAJXi8apy-4_lqDXp95cYGLqJgMdYZg8geugmbRRwBcONDBohtATYKONDhcIDshyfJKD120ARSNZRbbVxAUcnYfBeQJFAbVhIR-AiSD0mkGs7hvjTjA6DmJ1EHLThzCyqPdCHoU8xsOiwWcyRYpByKMsqw9CHst1_L8R8sjf1XKyE5P6pmjkog-DEXJbiHIfP7IWsoavPQbAVzGyKPePnw7_E_UePv-4C2Q759sYIAZonSJo0YKz5jJnBs6CDgxKe_op3ZgcWgXWBQgeLeugn-g1IzmuB2dZK_KJys4Z487anpK_mH25F-ty_pQzGdA5V7TjOIhyr4fR-QANelHf314_5-tX1u-CNejfgD3_zrKG-y8fPx3yUdt-G5yaDAm5EeUewOJAIOoDCCk754SUQj7EE20D-Q7b29Ps_OWRzH06Xt3H2_U-JidllEV0vf0LTmeLGfGN15eUf-31-WevNxQ8RtUmUQi5595NUZP7VO_WDaM2VIBYlzH7dQmZWI53Iuy6jPpopgDKEScjRa2JssQfGrlEfb1YFPAvd6Yn8tn0tg97fCKwDgj5AgO1PVrNQ-7Hq4R1lmTq2Eu2CA7cFMbpJWLgEFlA4-wpydFoSwyueyvE1qA9CXkv5D0sl6OnK0SDz4laWLr0f2yHXz_u58e7XM1lpw2J-pAEfJgRMpj_HdhVTL8De3Pq8_fVVcTJrn7qgX-7MI-DcxoGsXCsh9FcwNPgIqc9xZK9H0BRFHPpXejJnzVTBDpH8cCJAqAF8t550F1CyiBZAz7qKNYfgtekYvU8hclbQHhCM6X5jBAuI13FpEDfCujVHPyvd6NjNKLcf4QxXVwnXaQXUCkGBEtncGPQWYnLTts87Ja3-UVxpn7os76AYysyDWiDbjmq7g0nmYezDn2yyFNVdx15si1BQzppEEPk4uKmnDqGQMMYYvLzrLqhqfNuyNeoLTx-iQ6i5S2zMwkfAwz61AdAww6a2HYn5xRoRRjBUakU8te8Ja7ZpmWxLsH5WHZtMDUjuxxoWmQzWXFTNASd9hwAx9HEkiHDGb3V9sTJiQX6Q3O4jvsGmSKethwIVaxnivm6KRLFWSwY10TK9XYSRNATWfIY3tkd__SWfVdaf1PvPvYTZ9Ii2Z1zkaoOtYm_11i0zTs41Ww02FKxULtabestLmhXfViV9WZbVdWi36m67jbUbpp6s6o7WnVSlqqrZC3bLVZlt9A7WcpVuZZlWVfVqiqqLX0ou9Uay3ZV1VUj7koaUJvCmKehcP600MwT7aq7u-2mWhhsyPAub6OZvriMFn4XDZbNdGJxVxrNgX9ABB1MernLFqsDfJ7G1CcGL-ST0npq_8_QOQ8Pc0UypbyYvNm9fu066dBPTdG6Qchj9DL_LEfvvlMbhDymqFnI4xz4007-GQAA__9-gVnp">