[cfe-dev] Loading of named modules during preprocessing in c++2a

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Fri Oct 18 11:24:15 PDT 2019

On Thu, 17 Oct 2019 at 03:16, Boris Kolpackov via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> In build2 we scan a preprocessed TU in order to discover named modules
> that are needed to compile said TU. Clang, however, tries to load named
> modules during preprocessing, because, I believe, Clang's module map-
> based modules can also be named and such modules can export macros. This
> poses a problem for build systems that are only attempting to support
> C++20 modules.
> Prior to Clang 9 we hacked around this by simply not enabling (i.e., not
> passing -fmodules-ts) modules during preprocessing. However, starting
> with Clang 9, modules are enabled by default in the c++2a mode[1] and
> there doesn't seem to be a way to disable them. Plus, disabling them is
> really a hack rather than a solution: for example, it will fall apart
> once we try to support header units (e.g., via the module mapper).
> I would therefore like to propose a "strict" C++20 modules mode either
> as a default or as an opt-in. Another approach (suggested by Richard
> in private communication) is to try to load such a module but to not
> fail if it doesn't exist.

Well, approximately. What I intended to suggest was: perform normal module
name lookup, and then only try to load (or implicitly build) the module if
the lookup succeeds and we find the module name was declared in a module
map file (or slightly more broadly, that it names a header module rather
than a module interface unit).

I see two issues with this approach:
> 1. It would be hard to distinguish intentional and unintentional
>    "absence" of a BMI.
> 2. More importantly, the BMI might exist but be out of date.

For the alternative suggestion of checking whether there's a module map
file describing the module (rather than whether there's a BMI), I think
these aren't the right concerns. There is nonetheless a possibility that
(in a misconfigured preprocessing step) the module name lookup could fail
when preprocessing but succeed when compiling. But I don't think that's a
major problem, and we can't avoid the possibility that the preprocessing
step is misconfigured.

On the other hand, the strict mode sounds like a fairly simple solution
> (but I am happy to explore Richard's suggestion if this is preferred).

It's simple, but it provides less functionality and comes at the cost of an
extra configuration switch. I would prefer to not take that option if we
can avoid it.

> I've done a quick survey of the modules-related options and modes in
> Clang. Options:
>   -f[no-]modules      # Enable/Disable Clang modules.
>   -f[no-]cxx-modules  # Enable/Disable Clang modules in C++ TUs.
>   -fmodules-ts        # Enable Modules TS.
>   -std=c++2a          # Enables C++20 modules.
> LangOpts:
>   CPlusPlusModules
>   ModulesTS
>   Modules
> The current mapping of the options to LangOpts is best captured by this
> fragment from lib/Frontend/CompilerInvocation.cpp[2]:
>   Opts.CPlusPlusModules = Opts.CPlusPlus2a;
>   Opts.ModulesTS = Args.hasArg(OPT_fmodules_ts);
>   Opts.Modules =
>     Args.hasArg(OPT_fmodules) || Opts.ModulesTS || Opts.CPlusPlusModules;
> To support strict C++20 modules at the LangOpts level, it seems natural
> to introduce ClangModules (there is already a precedent in
> lib/Driver/ToolChains/Clang.cpp:RenderModuleOptions()[3]) with the
> following basic semantics:
>   Opts.ClangModules = Args.hasArg(OPT_fmodules);
>   Opts.Modules = Opts.ClangModules || Opts.ModulesTS ||
> Opts.CPlusPlusModules;
> At the options level, the approach depends on whether we want the default
> to be strict or if we want to make it opt-in. If it's strict by default,
> then using -fmodules in addition to -std=c++2a seems like a natural way to
> additionally request the Clang modules semantics. If we want it as opt-in,
> then -fno-modules again in combination with -std=c++2a seems natural (in
> fact, I was surprised that neither -fno-modules nor -fno-cxx-modules had
> any effect when -std=c++2a was specified).
> To me personally, strict by default seems cleaner (the Clang modules
> semantics would have been more appropriate for something like
> -std=clang++2a). But I am also ok with opt-in.
> What do you thinks? If this sounds sensible, I can come up with a patch.
> [1]
> https://github.com/llvm-mirror/clang/commit/cab7f1f7bc141ac88d15030088b311bd450b2c94
> [2]
> https://github.com/llvm-mirror/clang/blob/master/lib/Frontend/CompilerInvocation.cpp#L2754
> [3]
> https://github.com/llvm-mirror/clang/blob/master/lib/Driver/ToolChains/Clang.cpp#L2698
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20191018/c8440fe7/attachment.html>

More information about the cfe-dev mailing list