<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/120229>120229</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[C++20][Modules] Unrecognised import directives with -E option
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
iains,
urnathan,
dmpolukhin,
ChuanqiXu9
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
dmpolukhin
</td>
</tr>
</table>
<pre>
[D121591](https://reviews.llvm.org/D121591) added insertion of `-fdirectives-only` for header units compiled for preprocessor output. This option prevents macro expansion in the output, see [D121099](https://reviews.llvm.org/D121099). But it has very unfortunate side effect that `import` may not be recognized because Lexer recognize them only at top level and if there is nothing before. The reproducer is following:
```
// RUN: rm -fR %t
// RUN: split-file %s %t
// RUN: cd %t
// RUN: %clang_cc1 -verify -std=c++20 -Wno-experimental-header-units -emit-header-unit -xc++-user-header bz0.h -o bz0.pcm -fmodule-name=bz0.h
// Test direct build.
// RUN: %clang_cc1 -verify -std=c++20 -Wno-experimental-header-units -fmodule-map-file=modules.map -emit-header-unit -xc++-user-header -fmodule-file=bz0.h=bz0.pcm bz.h
// Test build for preprocessed output.
// RUN: %clang_cc1 -verify -std=c++20 -Wno-experimental-header-units -fmodule-map-file=modules.map -emit-header-unit -xc++-user-header -fmodule-file=bz0.h=bz0.pcm bz.h -E -fdirectives-only -o pp_output
// RUN: %clang_cc1 -verify -std=c++20 -Wno-experimental-header-units -fmodule-map-file=modules.map -emit-header-unit -xc++-user-header -fmodule-file=bz0.h=bz0.pcm pp_output
//--- modules.map
module "bz0.h" {
header "bz0.h"
export *
}
//--- h1.h
#pragma once
#define PUSH_WARNING _Pragma("GCC diagnostic push")
#define POP_WARNING _Pragma("GCC diagnostic pop")
PUSH_WARNING
POP_WARNING
//--- h2.h
#pragma once
#define FOO
struct A {};
//--- bz0.h
#include "h2.h"
// expected-no-diagnostics
//--- bz.h
// expected-no-diagnostics
#include "h1.h"
import "bz0.h";
#ifndef FOO
#error "FOO macro is not defined"
#endif
#include "h2.h"
```
After https://github.com/llvm/llvm-project/pull/111662 clang recognizes `import` after pragmas but because macro expansion is disabled it cannot be recognized in this case. One of the way to fix this issue is to allow macro expansion but preserve macro definitions in the output because they should be exported to preserve semantic.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUVk2P2zgP_jXKhXBgy3HSHHJIJm_6LrDbKbotureBLNGxdmVJq4_MpL9-IduJJ02xaA97KDBAxiRF8qEo8mHey6NG3JBqRyiVTGpPKCX0gVAanWahZfoqEJ01Kv7Vykn00Eam_5Z_xHUSVfsZi6E1bjOZzmojzsn_vqBFtS5ItSf0TRuC9aTcEnog9ODwJPHZz5U6dXPjjoQeLtZ0DUwIFCC1Rxek0WAaIMs8a4R0yIM8oc-MVmeyzKExDlpkAh1ELYMHbjorFYpeYx1aZzh6bxyYGGwMc_jYSg_G9p6twxPq4KFj3BnAF8u0TwqpIbQ4niH0ATwijJjy9foHMCVrup7DLgaQAVrm4YTuDFE3xoWoWUDwUiBg0yAPEFoWElzZWeNCwtixM2gToEZwyM1Ryy8ooEbOokf4FV_QTYqUdgepPMACBGNB4QkVMC1ANknrEKRPDlupj1BjYxymqiTv1hkRObpk0RilzLPUx4Qw35JlPv7lI2D48OkdKbfgOsiaD0BoFe503ioZskYqTHr_bSMuvi0ntOKK6eMT5wVkJ3SyOUPmgyDlnhO6I3RHc8g-a5Phi0UnO9SBqWxoiGxoiAw7GV6LIHsZD2fRoxtVUH_J5y1kpv_H8oSpMyIqzDTrkJT73mDK8SP6AENHQh2lEvP_KP9LGh2zfSFJuR8kft4x-934rn5GHwOc4TfBrb_coethffWQUFwe0s8PF7L_wd1USS1g7dP48n9qjDcwLkiyLINXwUi-Hb6AUDo4oBTIakfyLQBchusrZVLgSxpOQGjvd7X_OkBbjM1UWseOHQOjOV6MSoGN1AjvP_3-_6fP2w_vfnn3Fp7e94aEviGUvn14ACHZURsfJAcbfR-Yrm_PP77_vuPGTqfz7euw6XPycoeCfgeKw-PjIPLBRR5g2xdvtSfl7mt_0wQppeYqir7ofZS-rGOrpcbhAUWmTTbB8PfeXj_Yfzl0G624Rsu3w465udwp61I2WmBzAUhLdM70nXB4fBwX5rBIYCiFuKAoUQvZTH6-ifXVOtk2AR3cbtOjDG2s59x0hB7SSh1_MuvMn8gDoQcblSL0UBTFckmhf5bTHvS3O5T1IYZr9FDHcN2fd5vfg5Ce1YlDyACc6fvd27MD6YEzj3N41JgoSuILz-wMwUAjXwYD6X3s120wwNI6vQuXUrEOPbrTJZe-mjLxE3_LQ645hxbP4FsTVeIB42tEkaJcfXnsmA6Sz2diU4p1uWYz3BSrcrFYFMUqn7UbtmoazhZsxRYcFw1lvKkaSpd1VTdVXbGZ3NCcLgparIqyoFU-r-olX_E65zWyeo2CLHLsmFRXzjPrAW8KmlO6nilWo_Ij1dT4PJRj5I1u019nHY-eLHIlfZio0yzIoHqO-nCZqYlxVbvfhsFFqj180uOFpJU0NvI0yuFZhn6-D0RvFp3a_HCD9en61GIDntOG_hMAAP__ImuWlA">