[clang] [clang][modules] Headers meant to be included multiple times can be completely invisible in clang module builds (PR #83660)

Ian Anderson via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 4 10:02:08 PST 2024


ian-twilightcoder wrote:

> > Once a file has been `#import`'ed, it gets stamped as if it was `#pragma once` and will not be re-entered, even on #include.
> 
> Can you explain how this is happening? The only place where `HeaderFileInfo::isPragmaOnce` is set to `true` is in `HeaderSearch::MarkFileIncludeOnce()`, only called from `Preprocessor::HandlePragmaOnce()`, which seems correct.

It gets `HeaderFileInfo::isImport` which causes it to be treated the same as `#pragma once` from then on.

> > The problem arises when a submodule includes a multiple-include header. The "already included" state is global across all modules (which is necessary so that non-modular headers don't get compiled into multiple translation units and cause redeclaration errors). If another module or the main file #import's the same header, it becomes invisible from then on. If the original submodule is not imported, the include of the header will effectively do nothing and the header will be invisible. The only way to actually get the header's declarations is to somehow figure out which submodule consumed the header, and import that instead. That's basically impossible since it depends on exactly which modules were built in which order.
> 
> Could this be also solved by tracking the "already included" state [per submodule](https://github.com/llvm/llvm-project/pull/71117)?

That would fix headers that can be included multiple times (which is what I'm trying to fix here). But I think that would break headers that can only be included once and are not part of a module, since their declarations would go into multiple pcms.

https://github.com/llvm/llvm-project/pull/83660


More information about the cfe-commits mailing list