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

    <tr>
        <th>Summary</th>
        <td>
            [Clang] 'import' followed by '<<', '<=', '<<=' or '<=>' wrongly lexed as a module header-name
        </td>
    </tr>

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

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

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

<pre>
    Clang's `Preprocessor::HandleModuleContextualKeyword` enables ParsingFilename before peeking the token after import, forcing the lexer to scan any leading < as an angled header-name. But per [cpp.pre]p2 a module directive is introduced only when import is followed by a header-name, <, identifier, or :. A compound punctuator that only starts with < (<<, <=, <<=, <=>) is a single preprocessing-token and none of those alternatives, yet clang misparses it:

`import << 1; `— import is misclassified as a header-unit-import (the angled scan hits no > and falls back to a synthetic bare <).
`import << (a > b); / import << <foo.h>` — a later > makes the scan fold the text between into a bogus header-name → spurious "file not found".
`import <=>; `— reports '=' file not found.

1. Minimal <=> reproducer  — [godbolt.org/z/5de1z9sr7](https://godbolt.org/z/5de1z9sr7)


```
// clang -std=c++20 -fsyntax-only
export module M;
import <=>;      // error: '=' file not found   ← should not lex '<=>' as a header-name
```


2. << shift cases — [godbolt.org/z/dKdfcsGMq](https://godbolt.org/z/dKdfcsGMq)

```

int import = 0;
int d(int x) { return
import << (x > 0);   // valid shift → clang: "'...' file not found"
}
int a() { return
import << 1;         // '
```import' silently misclassified as header-unit-import
}
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyMVe2O4jgQfJrmT4vIcYAkP_jBx3InrUbaV3DiDvGNsXO2M8A-_ckmA8zs3N6hSEmw3amuqu4W3qujIVrDcgvL_UyMobduLV6F78XRnfWssfK63mlhjsBLj7BiPxwNzrbkvXVQbKDY_CmM1PRi5ahpZ02gSxiF_k7Xs3USVgzJiEaTxx_CeWWOB6XJiBNhQ511hAPRqzJHDD1hsK9kUHSBHKrTYF0AvsPOuvZ9h6YLOQwWfSsMCnNFTULGVSh2KDymf4-aJPYkJLl5_FaG2zHgQA5huW2HIRscwXI_cBR4SshRKkdtUG-EyqMywVk5tiTRGn3Fc09mAhSXO6u1PZPE5ori-TsRLRS7eFOSTFCdIhffrEMoNhlusLWnwY5G4jCaNowiWIehF-H2IR-ECx7PKvQpIeBVjHcLmZ7296cPL3sovgGvIzqBkWZNONy1UuY4n7g1Eo01hLbD0FtPKHQgZ0RM3cdwVwrYRsnxpPwgnCePKkStWbpWbCLiBgJzKLbRGfCNQ8WgXjwRdVK-1dFmnSKZ1HlnazQqzN8D8SpKO8mWhO1V8GgsQvEtQe6E1h4b0b5G7QX6qwk9BdViIxzdOK-zr-ABr0QK0wCvE1R-wE9bil1nbdZHClcMH4kI1CJaMR4_iVfyyYIJYGe1vFmWLgEbCmeKFjEJXWOPo3_2xS3mCmqOfhidsqNH4LxTmtDYgF10BHD-RQZJ2M8MO4obYowymaDEj6Gym1Z5hi_KqJPQj1iYTBG97fApVVhuj1Y2VofMuiPww0_gh6Wk_GftXQnLPfCqD2Hw0Qj8APzwu-28nsyS0pkuNh2c3DX3QUKxb4FvgW85w3kXVRWXeawEYBu6JBam-nyBYgts8xU16TfFJudSY_pXahDvYjD0vR21TIuaLrcz92IqPxg2lfendNLFs3cf-V51AVsRK-Y_mJXfZdf6P17-_n_MPrbfmf2IQ5nwMPUe2USWCSiBV_F-id0Byi06CqMzn6hMdXJJRmdTndwpfRNaySm5h4-TiDeiOfAyy7JfuY5LbAPlfsIiYjv7PYz8LugDQJTlKeP3wVCij6Mk6OuvfebXLnMDMpPrQtZFLWa0zstqseJ1zapZv84ZsYrJZVHk1CwXUrBFked1uVqsqpaqYqbWnPEVK3mesyJfVFnJGC8WrBBlLWqqWlgwOgmlM63fTlG7mfJ-pDXPWV0sZ1o0pH0atZzfyOM8Tl23jgfmzXj0sGBa-eAfIYIKOs3n2xBe7iMZDwKeB9G7eXfxIY6Fu5k_vk9_pZH0ye9nZ81RX9OQndr1VH1PRTAbnV5_MqwK_dhkrT0BP0Ts020-OPsXtQH4IXHhgR8mOt7W_J8AAAD__1mDkWY">