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

    <tr>
        <th>Summary</th>
        <td>
            clang module in deferred parse region gives very confusing diagnostics
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    This is derived from boost's define_if_constexpr header. That (and its sibling undef_if_constexp) are non-idempotent headers that surround conditional use of `if constexpr` by defining an IF_CONSTEXPR macro.  Sadly these #include <boost/config.hpp> to find information about whether if-constexpr is to be used.  It's desirable to have config.hpp as a header module (and weirdly I couldn't just make it textual and its includes modules).

```
// hdr.hh
#include "config.hh"

// cc1 -triple x86_64-linux-gnu -emit-header-module -fmodule-name=testing -std=c++20 -fmodules -fimplicit-module-maps -fno-builtin-module-map -emit-module -fmodules-embed-all-files -fno-implicit-modules -x c++-header -I . -o x module.modulemap

struct F
{
  // OK
#include "on.hh"
#include "off.hh"
  void Fn () {
    // Not OK
#include "on.hh"
    if (true) {}
#include "off.hh"
  }
};
```

```
// config.hh
#ifndef _CONFIG_HH
#define _CONFIG_HH
#endif
```

```
// on.hh
#include "config.hh" // comment this to fix boost

#ifndef _ON_OFF
#define CONSTEXPR if constexpr
#else
#undef MACRO
#endif
```

```
// off.hh
#define _ON_OFF
#include "on.hh"
#undef _ON_OFF

```

```
// module.modulemap
module "testing" {
  explicit module bits {
    header "config.hh"
    header "hdr.hh"
    textual header "on.hh"
    textual header "off.hh"
    export *
  }
}
```

The redundant include warnings are clueful, but I didn;t get them from our build -- I guess disabled?  But look at that weird parse error about `if (true)`!  that's really confusing.  AFAICT it's because that's in a deferred parse region.  The prior on/off includes inside the definition of F are fine.

A somewhat blunter diagnostic about trying to load an importable header not at namespace scope might be more helpful.  Yes, I realize the in-struct case works, but seems still like code-smell to me, and of course won't work in C++20 modules land.


```
(130)devvm5975:47>../llvm/trunk/build/bin/clang-15 -cc1 -triple x86_64-linux-gnu -emit-header-module -fmodule-name=testing -std=c++20 -fmodules -fimplicit-module-maps -fno-builtin-module-map -emit-module -fmodules-embed-all-files -fno-implicit-modules -x c++-header -I . -o x module.modulemap
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:8:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:9:
In file included from ./off.hh:2:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:12:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
./hdr.hh:13:5: error: expected member name or ';' after declaration specifiers
    if (true) {}
    ^
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:14:
In file included from ./off.hh:2:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
./hdr.hh:10:15: error: expected '}'
  void Fn () {
              ^
./hdr.hh:10:14: note: to match this '{'
  void Fn () {
             ^
./hdr.hh:15:4: error: expected ';' after struct
  }
   ^
   ;
./hdr.hh:16:1: error: extraneous closing brace ('}')
};
^
8 errors generated.
(1)devvm5975:47>
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztV0lv20YU_jXS5YGCRFrbQQfZjhqhaFwkBtKejCE5FCcmOcLMULb76_s9bpJsOnHQHnKwQYvLzNuX702o46fVbaos4YqlUQcZU2J0TqHW1g38OX9OVCHvVHIX6cI6-bg3lEqB3SO6TYWjgb8QRUzKWbIqzFSxo7IA1SnJwF-SMJIKXXgqlvleO1m4ho8lx3xsaYwGJYEoVk7pQmRUWkk6ocFsrBLqFMArhU-1aixPFLTd3F3dfPpy--GvPz9TLiKjR0RfRJw9gbsEl4EfqCLKyhiPwVVj3wYsE7Ubpfv9IPhAThM4wpYi0SYXrAOJUJeOHlIJNoZU4h3dAKeBIpSsZQxx29ZjVhkRZpJXU3GQdJRCwpJo7KZcx2UmWwc-SGVY3S22l1lcgJejb6V1MOdewr8Eqa6EU1p3N_bYhpGFl0eD8fVgvG5-Z-Pmql_9DS5KYzNK0_bT0Sm-36qZ4vmMT00YRRPynFF76Py4mN3NLjxEu3z0dkVJnsyV82rDvMYwL6kfvELkchBcO2kdh8uzLsZrNPAvcfnjbqPFk8r3mYrAq6HNxZ4_F9oLS5WB_mShkfpMnMXXUMaeyDKwq7mC_BljfH2kRoVGb_K2NCJP02Pj0VF9g6RTd1hnysjRpvk2v6wfiBo_3fze51xdnDn2fC1JTheJDlrFtCk4Nbh0TmR0Uj5p9yZJTILaASeoLVtu8-s36XHch4fgsj-tvpNrx4zqpCXcG4iLdbP97e7jx26lbjR9KxL9IPlp2bUbfpDm1Cma59yRXFoXdaIemx54Vged-jef7m42m-e6HzvQWbfq7Mis7F6qHkl_rK8-3_xXQ-uoPffjMxW_l4plj1E_q0V_xXQtzm-Kv_L5MZ3hn6oo214Ycl87S_emNHvb0_l609hOF9uOedz0sjh69jwvg0pPbRjr1r2l8bqzblNJRsbwsEB6tUF4EIaBy1agiE8yKbOBf0UhoGZLsUL3Dy4d7SRnpMxrTNalIe6BMXkedu1KaQE2yjLUoJ9uiC5Bnml9T8LVmFphCu2FAQBKwKtp4KzG02NPYKX9CVVEFYYZie75VNVvaaEp0G29WW-vbgE81YZQRoLBuaNQgEpGZIiRrUgjd4BQ0LIX9kZBvgaubeDgI3ipwmIkYDsbQK9gF6C_qbzDyXyGamuyOpcPbF6YlYVDzGIldgWKVUWNfc48MdCgkDMtYp4P0P0RwAqVm0AXaKDgwdhk9yKSZCO9l5SrXeoY1HNteG-2R2xgwt-Mr1fwO7tG_VMrDDRq0CASsPdBm3vbxtFKmWMkcirLKFP3PAXE0rO5xDsUAyJiI0O55l5Rmoq-Rn3mww696hCyxawMBOcY31-Si0mAiC5jeTjk0-V8OgjWF3OMOKMR3J9lhxw3KF7c417lFN8VxyaCiJ03mZL3jvdfU8U9if3DdnTNbN41M_i0CcG2IBbe5nUzR2PUbNRv8x1BAI3_AzoOU9PPgvWi28yf6w4WrCfNf13Y_HDsMyf9Htn1Qu8Rt1m8ktjvJSqVHhSAj8eN-YY_D6aX3tfWuXXleAVI4eROxmDaO0L0zJDTD0flO5umrfYoQ8n3VnaInlFYFJ6RveNWy-0Xic3yDZsbPDnl_B7IXy2Qk_fg9ATn3EVBw_LoDMxFMoLGgDP0YFOhKWmeouZ8XmDjkwqhJXDF1CdqCxKVKBz833JCqY48v1quXLxX_f-aWGP-eSWzOKZIBvy-4XB8_PuepItTzXkWEy5K67NfJe3yZ6W9Iqwau1636rRAaje9OFyc8ubn9gx-Lmf2IpdwpjGikLq0OF5onuApNDzkVma0DsXg__J034pb1NwsTiGFROnKbvDEdNk3W_aOosN4FcTLYCmGTrlMrqrxsk1p5GzviYF26oCB7SDNyRHkZMq3w9Jkq9S5veXaqg6gO9RAGY5wkD9OuHzz9kZ_g8_xqqwteYrfTGfBxB-mKzEO4mk4GcfziVz4vh8H85kvwmQ6nsxCsZgMMxHi0L5CQaEeCvlAFQuujen1UK38se-PZ8F4spgs_enIXwaRP46XIvHDaDFJBhdjzJIqG7EeI212Q7OqVArLncVipqyzx0VhrdoVUlbiwF-ULtVmVZpC4JRVDCvZq0r3fwEBMJZp">